--- a/ChangeLog Sat Feb 15 21:14:07 2020 -0600
+++ b/ChangeLog Tue Feb 25 22:30:11 2020 -0600
@@ -1,4 +1,5 @@
* Changed the website to the repository on keep.imfreedom.org.
* Removed an unnecessary meson version check. (Gary Kramlich)
@@ -8,11 +9,20 @@
* Removed GPluginVersionCompareFunc and the GPluginPluginInfo::version-func
property as they aren't necessary with semantic versioning. (Gary Kramlich)
* Fixed licenses throughout the codecase. (Richard Laager)
+ * Removed the moonscript support from the Lua loader. (Gary Kramlich) + * Add support for Lua 5.3. (Richard Laager) + * After years of on again, off again work, the Perl loader finally works! + (Gary Kramlich, Richard Laager) * Bumped the Python 3 dependency to 3.5. (Gary Kramlich)
* Replaced mbstowcs with Py_DecodeLocale. (Gary Kramlich)
* Renamed the python loader from gplugin-python to gplugin-python3.
- * Removed the moonscript support from the Lua loader. (Gary Kramlich)
* Synchronize GPluginGtkStore with the plugin manager, make the enabled
@@ -167,7 +177,7 @@
* Moved the native loader to the loader-testing static library
* Overhauled the native loader tests
* Fixed a bug where in certain conditions a load-on-query plugin that failed
- to load, would get it's info tracked twice.
+ to load, would get its info tracked twice. * Added gplugin_get_option_group which implements options for adding paths
--- a/gplugin-gtk-viewer/gplugin-gtk-viewer-window.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin-gtk-viewer/gplugin-gtk-viewer-window.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,6 +1,5 @@
- * Copyright (C) 2017-2018 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
--- a/gplugin-gtk-viewer/gplugin-gtk-viewer-window.h Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin-gtk-viewer/gplugin-gtk-viewer-window.h Tue Feb 25 22:30:11 2020 -0600
@@ -1,6 +1,5 @@
- * Copyright (C) 2017-2018 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
--- a/gplugin-gtk-viewer/gplugin-gtk-viewer.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin-gtk-viewer/gplugin-gtk-viewer.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -214,4 +214,3 @@
--- a/gplugin-gtk/gplugin-gtk-plugin-info.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin-gtk/gplugin-gtk-plugin-info.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -21,10 +21,10 @@
* SECTION:gplugin-gtk-plugin-info
- * @Title: Plugin Info Gtk+ Widgets
- * @Short_description: Gtk+ Widgets for plugins
+ * @title: Plugin Info Gtk Widgets + * @short_description: Gtk Widgets for plugins - * #GPluginGtkPluginInfo is a Gtk+ widget that shows information about plugins.
+ * #GPluginGtkPluginInfo is a Gtk widget that shows information about plugins. @@ -306,12 +306,12 @@
* gplugin_gtk_plugin_info_set_plugin:
- * @info: The #GPluginGtkPluginInfo instance
- * @plugin: The #GPluginPlugin instance
+ * @info: The #GPluginGtkPluginInfo instance. + * @plugin: The #GPluginPlugin instance. * Sets the #GPluginPlugin that should be displayed.
- * A @plugin value of NULL will clear the widget.
+ * A @plugin value of %NULL will clear the widget. gplugin_gtk_plugin_info_set_plugin(GPluginGtkPluginInfo *info,
@@ -326,12 +326,12 @@
* gplugin_gtk_plugin_info_get_plugin:
- * @info: The #GPluginGtkPluginInfo instance
+ * @info: The #GPluginGtkPluginInfo instance. * Returns the #GPluginPlugin that's being displayed.
* Return Value: (transfer full): The #GPluginPlugin that's being
gplugin_gtk_plugin_info_get_plugin(GPluginGtkPluginInfo *info) {
--- a/gplugin-gtk/gplugin-gtk-plugin-info.h Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin-gtk/gplugin-gtk-plugin-info.h Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -42,4 +42,3 @@
#endif /* GPLUGIN_GTK_PLUGIN_INFO_H */
--- a/gplugin-gtk/gplugin-gtk-store.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin-gtk/gplugin-gtk-store.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -21,10 +21,10 @@
* SECTION:gplugin-gtk-store
- * @Title: GtkTreeModelStore for gplugins
- * @Short_description: A store for plugins
+ * @title: GtkTreeModelStore for plugins + * @short_description: A store for plugins - * #GPluginGtkStore is a GtkTreeModel populated with gplugins.
+ * #GPluginGtkStore is a GtkTreeModel populated with plugins. @@ -110,7 +110,7 @@
plugins = gplugin_manager_find_plugins(id);
for(l = plugins; l; l = l->next)
gplugin_gtk_store_add_plugin(store, GPLUGIN_PLUGIN(l->data));
- gplugin_manager_free_plugin_list(plugins);
+ g_slist_free_full(plugins, g_object_unref); @@ -203,7 +203,7 @@
gplugin_gtk_store_init(GPluginGtkStore *store) {
- GType *types = (GType *)gplugin_gtk_get_store_column_types();
+ GType *types = (GType *)gplugin_gtk_store_get_column_types(); gtk_list_store_set_column_types(GTK_LIST_STORE(store),
GPLUGIN_GTK_STORE_N_COLUMNS,
@@ -225,10 +225,10 @@
- * Create a new GPluginGtkStore which is a prepopulated #GtkTreeStore.
+ * Create a new #GPluginGtkStore which is a prepopulated #GtkTreeStore. - * Returns: (transfer full): A new GtkTreeModel prepopulated with all of the
+ * Returns: (transfer full): A new #GtkTreeModel prepopulated with all of the gplugin_gtk_store_new(void) {
@@ -236,15 +236,14 @@
- * gplugin_gtk_get_store_column_types:
+ * gplugin_gtk_store_get_column_types: * Returns the columns that #GPluginGtkStore's will use.
- * Returns: (transfer none): A list of #GTypes for the columes that the store
+ * Returns: (transfer none): A list of #GType's for the columns that the store -gplugin_gtk_get_store_column_types(void) {
+gplugin_gtk_store_get_column_types(void) {
--- a/gplugin-gtk/gplugin-gtk-store.h Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin-gtk/gplugin-gtk-store.h Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -43,9 +43,8 @@
GPluginGtkStore *gplugin_gtk_store_new(void);
-const GType *gplugin_gtk_get_store_column_types(void);
+const GType *gplugin_gtk_store_get_column_types(void); #endif /* GPLUGIN_GTK_STORE_H */
--- a/gplugin-gtk/gplugin-gtk-view.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin-gtk/gplugin-gtk-view.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,10 +22,10 @@
* SECTION:gplugin-gtk-view
- * @Title: Gtk+ View for gplugins
- * @Short_description: A view for plugins
+ * @title: GtkTreeView for plugins + * @short_description: A view for plugins - * #GPluginGtkView is a display widget for a list of GPlugins.
+ * #GPluginGtkView is a display widget for a list of plugins. @@ -232,7 +232,7 @@
- * Creates a new GPluginGtkView.
+ * Creates a new #GPluginGtkView. * Returns: (transfer full): The new view.
@@ -253,7 +253,7 @@
* gplugin_gtk_view_set_show_internal:
- * @view: The #GPluginGtkView instance
+ * @view: The #GPluginGtkView instance. * @show_internal: Whether or not to show internal plugins.
* This function will toggle whether or not the widget will show internal
@@ -272,7 +272,7 @@
* gplugin_gtk_view_get_show_internal:
- * @view: The #GPluginGtkView instance
+ * @view: The #GPluginGtkView instance. * Returns whether or not @view is showing internal plugins.
@@ -282,4 +282,3 @@
return view->show_internal;
--- a/gplugin-gtk/gplugin-gtk-view.h Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin-gtk/gplugin-gtk-view.h Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -40,4 +40,3 @@
#endif /* GPLUGIN_GTK_VIEW_H */
--- a/gplugin-gtk/gplugin-gtk.h.in Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin-gtk/gplugin-gtk.h.in Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -26,4 +26,3 @@
#undef GPLUGIN_GTK_GLOBAL_HEADER_INSIDE
#endif /* GPLUGIN_GTK_H */
--- a/gplugin-gtk/gplugin-gtk.xml.in Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin-gtk/gplugin-gtk.xml.in Tue Feb 25 22:30:11 2020 -0600
@@ -28,7 +28,7 @@
- <glade-widget-group name="gplugin-gtk" title="GPlugin Gtk+ Widgets">
+ <glade-widget-group name="gplugin-gtk" title="GPlugin Gtk Widgets"> <glade-widget-class-ref name="GPluginGtkPluginInfo"/>
<glade-widget-class-ref name="GPluginGtkView"/>
<glade-widget-class-ref name="GPluginGtkStore"/>
--- a/gplugin-gtk/meson.build Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin-gtk/meson.build Tue Feb 25 22:30:11 2020 -0600
@@ -97,7 +97,7 @@
- description : 'Gtk+ widgets for GPlugin',
+ description : 'Gtk widgets for GPlugin', version : meson.project_version(),
filebase : 'gplugin-gtk',
--- a/gplugin-gtk/reference/gplugin-gtk-docs.xml Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin-gtk/reference/gplugin-gtk-docs.xml Tue Feb 25 22:30:11 2020 -0600
@@ -1,20 +1,21 @@
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" + "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [ <!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
<!ENTITY version SYSTEM "version.xml">
<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
- <title>GPlugin Gtk+ Reference Manual</title>
+ <title>GPlugin Gtk Reference Manual</title> - <title>GPlugin Gtk+ &version;</title>
+ <title>GPluginGtk &version;</title> - GPlugin Gtk+ is a GObject based library that implements a reusable plugin system that
- supports loading plugins in other languages
- via loaders. GPlugin also implements
- dependencies among the plugins.
+ GPluginGtk is a collection of Gtk widgets to make it easier to + integrate GPlugin into applications. + The latest version of this documentation can be found on-line at + <ulink role="online-location" url="https://docs.pidgin.im/gplugin-gtk/latest">https://docs.pidgin.im/gplugin-gtk/latest/</ulink>. @@ -41,10 +42,6 @@
<title>Index of deprecated symbols</title>
<xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
-<!-- <index id="api-index-2.11.0" role="2.11.0">
- <title>Index of new symbols in 2.11.0</title>
- <xi:include href="xml/api-index-2.11.0.xml"><xi:fallback /></xi:include>
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
--- a/gplugin-gtk/reference/meson.build Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin-gtk/reference/meson.build Tue Feb 25 22:30:11 2020 -0600
@@ -15,7 +15,7 @@
- '--extra-dir', join_paths(meson.current_build_dir(), '../../gplugin/reference')
+ '--extra-dir=' + join_paths(meson.current_build_dir(), '../../gplugin/reference/html') gplugin_gtk_version_xml = configure_file(
@@ -28,6 +28,7 @@
main_xml : DOC_MODULE + '-docs.xml',
+ namespace : 'gplugin_gtk', src_dir : gplugin_gtk_inc,
dependencies : gplugin_gtk_dep,
ignore_headers : ignore_hfiles,
--- a/gplugin/gplugin-core.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-core.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -16,7 +16,7 @@
+#include <glib/gi18n-lib.h> #include <gplugin/gplugin-core.h>
@@ -25,11 +25,10 @@
- * @Short_description: the core api
+ * @short_description: the core API - * This section contains the core api of gplugin, which includes #gplugin_init
+ * This section contains the core API of GPlugin. /******************************************************************************
@@ -76,4 +75,3 @@
gplugin_manager_private_uninit();
--- a/gplugin/gplugin-core.h Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-core.h Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -25,7 +25,7 @@
-#define GPLUGIN_DOMAIN (g_quark_from_static_string("gplugin"))
+#define GPLUGIN_DOMAIN (g_quark_from_static_string("gplugin")) @@ -35,4 +35,3 @@
#endif /* GPLUGIN_CORE_H */
--- a/gplugin/gplugin-file-tree.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-file-tree.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -17,7 +17,7 @@
#include "gplugin-file-tree.h"
+#include <glib/gi18n-lib.h> /******************************************************************************
@@ -145,4 +145,3 @@
--- a/gplugin/gplugin-file-tree.h Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-file-tree.h Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -33,4 +33,3 @@
#endif /* GPLUGIN_FILE_TREE_H */
--- a/gplugin/gplugin-loader-tests.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-loader-tests.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -19,7 +19,6 @@
@@ -224,4 +223,3 @@
gplugin_loader_tests_add_tests(short_name);
--- a/gplugin/gplugin-loader-tests.h Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-loader-tests.h Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -29,4 +29,3 @@
#endif /* GPLUGIN_OPTIONS_H */
--- a/gplugin/gplugin-loader.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-loader.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -20,24 +20,23 @@
#include <gplugin/gplugin-core.h>
+ * SECTION:gplugin-loader + * @title: Plugin Loader + * @short_description: Abstract class for loading plugins + * GPluginLoader defines the base behavior for loaders of all languages. * The standard _get_type macro for #GPluginLoader.
- * SECTION:gplugin-loader
- * @Title: Plugin Loader Interface
- * @Short_description: interface for loading plugins
- * A PluginLoader has to implement the interface described here for GPlugin to
- * be able to use it to load plugins.
- * An abstract data type that should not be accessed directly.
+ * An abstract class that should not be accessed directly. @@ -52,11 +51,11 @@
* @unload: The unload vfunc is called when the plugin manager wants to unload
* a previously loaded plugin from this loader.
- * #GPluginLoader class defines the behavior for loading plugins.
+ * #GPluginLoaderClass defines the behavior for loading plugins. /******************************************************************************
+ * GObject Implementation *****************************************************************************/
G_DEFINE_ABSTRACT_TYPE(GPluginLoader, gplugin_loader, G_TYPE_OBJECT);
@@ -74,14 +73,15 @@
* gplugin_loader_query_plugin:
- * @loader: #GPluginLoader instance performing the query
- * @filename: filename to query
- * @error: return location for a GError, or NULL
+ * @loader: The #GPluginLoader instance performing the query. + * @filename: The filename to query. + * @error: (nullable): The return location for a #GError, or %NULL. - * This function is called by the plugin manager to ask a loader to query the
- * given file and determine if it's a usable plugin.
+ * This function is called by the plugin manager to ask @loader to query + * @filename and determine if it's a usable plugin. - * Return value: (transfer full): A #GPluginPlugin instance or NULL on failure
+ * Return value: (transfer full): A #GPluginPlugin instance or %NULL on gplugin_loader_query_plugin(GPluginLoader *loader,
@@ -104,14 +104,14 @@
* gplugin_loader_load_plugin:
- * @loader: #GPluginLoader instance performing the load
- * @plugin: #GPluginPlugin instance to load
- * @error: return location for a GError, or NULL
+ * @loader: The #GPluginLoader instance performing the load. + * @plugin: The #GPluginPlugin instance to load. + * @error: (nullable): The return location for a #GError, or %NULL. - * This function is called by the plugin manager to ask a loader to load the
+ * This function is called by the plugin manager to ask @loader to load - * Return value: TRUE if @plugin was loaded successfully, FALSE otherwise
+ * Return value: %TRUE if @plugin was loaded successfully, %FALSE otherwise. gplugin_loader_load_plugin(GPluginLoader *loader,
@@ -139,14 +139,14 @@
* gplugin_loader_unload_plugin:
- * @loader: #GPluginLoader instance performing the unload
- * @plugin: #GPluginPlugin instance to unload
- * @error: return location for a GError, or NULL
+ * @loader: The #GPluginLoader instance performing the unload. + * @plugin: The #GPluginPlugin instance to unload. + * @error: (nullable): The return location for a #GError, or %NULL. - * This function is called by the plugin manager to ask a loader to unload the
+ * This function is called by the plugin manager to ask @loader to unload - * Return value: TRUE if @plugin was unloaded successfully, FALSE otherwise
+ * Return value: %TRUE if @plugin was unloaded successfully, %FALSE otherwise. gplugin_loader_unload_plugin(GPluginLoader *loader,
@@ -173,21 +173,26 @@
- * gplugin_loader_class_get_supported_extensions:
- * @klass: #GPluginLoader instance
+ * gplugin_loader_get_supported_extensions: + * @loader: The #GPluginLoader instance. - * Returns a #GSList of string for which extensions the loader supports.
+ * Returns a #GSList of strings containing the extensions that the loader + * supports. Each extension should not include the dot. For example: so, * Return value: (element-type utf8) (transfer container): A #GSList of
* extensions that the loader supports.
-gplugin_loader_class_get_supported_extensions(GPluginLoaderClass *klass) {
- g_return_val_if_fail(GPLUGIN_IS_LOADER_CLASS(klass), NULL);
+gplugin_loader_get_supported_extensions(GPluginLoader *loader) { + GPluginLoaderClass *klass = NULL; + g_return_val_if_fail(GPLUGIN_IS_LOADER(loader), NULL); - if(klass->supported_extensions)
- return klass->supported_extensions(klass);
+ klass = GPLUGIN_LOADER_GET_CLASS(loader); + if(klass != NULL && klass->supported_extensions) { + return klass->supported_extensions(loader);
--- a/gplugin/gplugin-loader.h Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-loader.h Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -38,7 +38,7 @@
- GSList *(*supported_extensions)(GPluginLoaderClass *klass);
+ GSList *(*supported_extensions)(GPluginLoader *loader); GPluginPlugin *(*query)(GPluginLoader *loader, const gchar *filename, GError **error);
@@ -49,7 +49,7 @@
-GSList *gplugin_loader_class_get_supported_extensions(GPluginLoaderClass *klass);
+GSList *gplugin_loader_get_supported_extensions(GPluginLoader *loader); GPluginPlugin *gplugin_loader_query_plugin(GPluginLoader *loader, const gchar *filename, GError **error);
--- a/gplugin/gplugin-manager.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-manager.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -19,7 +19,7 @@
+#include <glib/gi18n-lib.h> #include <gplugin/gplugin-manager.h>
#include <gplugin/gplugin-core.h>
@@ -61,7 +61,8 @@
GHashTable *plugins_filename_view;
+ GHashTable *loaders_by_extension; @@ -76,8 +77,8 @@
GList *(*get_paths)(GPluginManager *manager);
- void (*register_loader)(GPluginManager *manager, GType type);
- void (*unregister_loader)(GPluginManager *manager, GType type);
+ gboolean (*register_loader)(GPluginManager *manager, GType type, GError **error); + gboolean (*unregister_loader)(GPluginManager *manager, GType type, GError **error); void (*refresh)(GPluginManager *manager);
@@ -156,6 +157,31 @@
+ * gplugin_manager_find_loader_by_type: + * @manager: The #GPluginManager instance. + * @type: The #GType of the loader to find. + * Looks up a #GPluginLoader instance by its type. + * Returns: (transfer none): The #GPluginLoader instance or %NULL. +gplugin_manager_find_loader_by_type(GPluginManager *manager, GType type) { + g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), NULL); + g_return_val_if_fail(g_type_is_a(type, GPLUGIN_TYPE_LOADER), NULL); + for(l = manager->loaders; l; l = l->next) { + if(G_OBJECT_TYPE(l->data) == type) { + return GPLUGIN_LOADER(l->data); /******************************************************************************
*****************************************************************************/
@@ -219,37 +245,37 @@
return manager->paths->head;
-gplugin_manager_real_register_loader(GPluginManager *manager,
+gplugin_manager_real_register_loader(GPluginManager *manager, GType type, GPluginLoader *loader = NULL;
- GPluginLoaderClass *lo_class = NULL;
+ GSList *l = NULL, *exts = NULL; + g_return_val_if_fail(g_type_is_a(type, GPLUGIN_TYPE_LOADER), FALSE); - g_return_if_fail(g_type_is_a(type, GPLUGIN_TYPE_LOADER));
+ loader = gplugin_manager_find_loader_by_type(manager, type); + if(GPLUGIN_IS_LOADER(loader)) { + g_set_error(error, GPLUGIN_DOMAIN, 0, + _("loader %s was already registered"), g_type_name(type)); /* Create the loader instance first. If we can't create it, we bail */
loader = g_object_new(type, NULL);
if(!GPLUGIN_IS_LOADER(loader)) {
- g_warning(_("failed to create loader instance for %s"),
+ g_set_error(error, GPLUGIN_DOMAIN, 0, + _("failed to create loader instance for %s"),
- /* grab the class of the loader */
- lo_class = GPLUGIN_LOADER_GET_CLASS(loader);
- g_warning(_("failed to get the loader class for %s"), g_type_name(type));
- g_object_unref(G_OBJECT(loader));
+ manager->loaders = g_slist_prepend(manager->loaders, + g_object_ref(G_OBJECT(loader)));
- for(l = gplugin_loader_class_get_supported_extensions(lo_class);
+ exts = gplugin_loader_get_supported_extensions(loader); + for(l = exts; l; l = l->next) { GSList *existing = NULL, *ll = NULL;
const gchar *ext = (const gchar *)l->data;
@@ -257,7 +283,7 @@
* we can prepend our loader. But before we add ours, we remove any
* old copies we might have of ours.
- existing = g_hash_table_lookup(manager->loaders, ext);
+ existing = g_hash_table_lookup(manager->loaders_by_extension, ext); for(ll = existing; ll; ll = ll->next) {
if(G_OBJECT_TYPE(ll->data) == type) {
GPluginLoader *old = GPLUGIN_LOADER(ll->data);
@@ -273,40 +299,48 @@
existing = g_slist_prepend(existing, g_object_ref(G_OBJECT(loader)));
/* Now insert the updated slist back into the hash table */
- g_hash_table_insert(manager->loaders, g_strdup(ext), existing);
+ g_hash_table_insert(manager->loaders_by_extension, g_strdup(ext), /* make a note that we need to refresh */
manager->refresh_needed = TRUE;
/* we remove our initial reference from the loader now to avoid a leak */
g_object_unref(G_OBJECT(loader));
-gplugin_manager_real_unregister_loader(GPluginManager *manager,
+gplugin_manager_real_unregister_loader(GPluginManager *manager, GType type, - GPluginLoaderClass *klass = NULL;
+ GPluginLoader *loader = NULL; + GSList *l = NULL, *exts = NULL; - g_return_if_fail(g_type_is_a(type, GPLUGIN_TYPE_LOADER));
+ g_return_val_if_fail(g_type_is_a(type, GPLUGIN_TYPE_LOADER), FALSE); - klass = g_type_class_ref(type);
+ loader = gplugin_manager_find_loader_by_type(manager, type); + if(!GPLUGIN_IS_LOADER(loader)) { + g_set_error(error, GPLUGIN_DOMAIN, 0, + _("loader %s is not registered"), g_type_name(type)); - for(exts = gplugin_loader_class_get_supported_extensions(klass);
- exts; exts = exts->next) {
+ exts = gplugin_loader_get_supported_extensions(loader); + for(l = exts; l; l = l->next) {
ext = (const gchar *)exts->data;
- los = g_hash_table_lookup(manager->loaders, ext);
+ los = g_hash_table_lookup(manager->loaders_by_extension, ext); - for(l = los; l; l = l->next) {
- GPluginLoader *lo = GPLUGIN_LOADER(l->data);
+ for(ll = los; ll; ll = ll->next) { + GPluginLoader *lo = GPLUGIN_LOADER(ll->data); /* check if this is not the loader we're looking for */
if(G_OBJECT_TYPE(lo) != type)
@@ -318,10 +352,12 @@
los = g_slist_remove(los, lo);
- g_hash_table_insert(manager->loaders, g_strdup(ext), los);
- g_hash_table_remove(manager->loaders, ext);
+ g_hash_table_insert(manager->loaders_by_extension, + g_hash_table_remove(manager->loaders_by_extension, ext); /* kill our ref to the loader */
g_object_unref(G_OBJECT(lo));
@@ -330,8 +366,12 @@
- g_type_class_unref(klass);
+ manager->loaders = g_slist_remove(manager->loaders, loader); + g_object_unref(G_OBJECT(loader)); @@ -380,7 +420,7 @@
GPluginPluginState state =
gplugin_plugin_get_state(plugin);
- /* The plugin is in our "view", check it's state. If it's
+ /* The plugin is in our "view", check its state. If it's * queried or loaded, move on to the next one.
if(state == GPLUGIN_PLUGIN_STATE_QUERIED ||
@@ -392,9 +432,8 @@
/* grab the list of loaders for this extension */
- for(l = g_hash_table_lookup(manager->loaders, e->extension); l;
+ l = g_hash_table_lookup(manager->loaders_by_extension, e->extension); + for(; l; l = l->next) { @@ -409,7 +448,7 @@
- /* Check the GError, if it's set, output it's message and
+ /* Check the GError, if it's set, output its message and if(plugin == NULL || error) {
@@ -605,124 +644,32 @@
- const gchar * const *dependencies = NULL;
- /* now walk through any dependencies the plugin has and load them. If they
- * fail to load we need to fail as well.
- dependencies = gplugin_plugin_info_get_dependencies(info);
- if(dependencies != NULL) {
- gboolean all_found = TRUE;
- for(i = 0; dependencies[i]; i++) {
- gboolean found = FALSE;
- ors = g_strsplit(dependencies[i], "|", 0);
- for(o = 0; ors[o]; o++) {
- GMatchInfo *match = NULL;
- GSList *matches = NULL, *m = NULL;
- gchar *oid = NULL, *oop = NULL, *over = NULL;
+ GSList *dependencies = NULL, *l = NULL; + GError *ourerror = NULL; + gboolean all_loaded = TRUE; - if(!g_regex_match(dependency_regex, ors[o], 0, &match)) {
- /* grab the or'd id, op, and version */
- oid = g_match_info_fetch_named(match, "id");
- oop = g_match_info_fetch_named(match, "op");
- over = g_match_info_fetch_named(match, "version");
- /* free the match info */
- g_match_info_free(match);
- /* now look for a plugin matching the id */
- matches = gplugin_manager_find_plugins(oid);
- /* now iterate the matches and check if we need to check their
- for(m = matches; m; m = m->next) {
- GPluginPlugin *dplugin = GPLUGIN_PLUGIN(g_object_ref(G_OBJECT(m->data)));
+ dependencies = gplugin_manager_get_plugin_dependencies(plugin, &ourerror); + g_propagate_error(error, ourerror);
- /* we need to check the version, so grab the info to
- * get the version and check it.
- GPluginPluginInfo *dinfo = NULL;
- const gchar *dver = NULL;
- gboolean satisfied = FALSE;
- dinfo = gplugin_plugin_get_info(dplugin);
- dver = gplugin_plugin_info_get_version(dinfo);
- res = gplugin_version_compare(dver, over, error);
- g_object_unref(G_OBJECT(dinfo));
- /* dver is greather than over */
- if(g_strcmp0(oop, ">") == 0)
- /* dver is equal to over */
- if(g_strcmp0(oop, ">=") == 0 ||
- g_strcmp0(oop, "<=") == 0 ||
- g_strcmp0(oop, "=") == 0 ||
- g_strcmp0(oop, "==") == 0)
- if(g_strcmp0(oop, "<") == 0)
- ret = gplugin_manager_load_plugin(dplugin, error);
-# warning need to figure out dependencies
-// gplugin_plugin_add_dependent_plugin(dplugin, plugin);
- g_object_unref(G_OBJECT(dplugin));
+ for(l = dependencies; l != NULL; l = l->next) { + GPluginPlugin *dependency = GPLUGIN_PLUGIN(l->data); + gboolean loaded = FALSE;
+ loaded = gplugin_manager_load_plugin(dependency, error);
+ g_slist_free_full(dependencies, g_object_unref); @@ -733,7 +680,7 @@
GPluginPluginInfo *info = NULL;
const gchar * const *dependencies = NULL;
info = gplugin_plugin_get_info(plugin);
dependencies = gplugin_plugin_info_get_dependencies(info);
@@ -742,26 +689,64 @@
- for(idx = 0; dependencies[idx] != NULL; idx++) {
- GPluginPlugin *dep = gplugin_manager_find_plugin(dependencies[idx]);
+ for(i = 0; dependencies[i] != NULL; i++) { + gboolean found = FALSE; + ors = g_strsplit(dependencies[i], "|", 0); + for(o = 0; ors[o]; o++) { + GMatchInfo *match = NULL; + GSList *matches = NULL; + gchar *oid = NULL, *oop = NULL, *over = NULL; + if(!g_regex_match(dependency_regex, ors[o], 0, &match)) { + /* grab the or'd id, op, and version */ + oid = g_match_info_fetch_named(match, "id"); + oop = g_match_info_fetch_named(match, "op"); + over = g_match_info_fetch_named(match, "version"); + /* free the match info */ + g_match_info_free(match); - if(!GPLUGIN_IS_PLUGIN(dep)) {
- "failed to find plugin dependency '%s'",
+ /* now look for a plugin matching the id */ + matches = gplugin_manager_find_plugins_with_version(oid, oop, + /* prepend the first found match to our return value */ + ret = g_slist_prepend(ret, g_object_ref(matches->data)); + g_slist_free_full(matches, g_object_unref); - g_slist_free_full(ret, g_object_unref);
+ g_set_error(error, GPLUGIN_DOMAIN, 0, + _("failed to find dependency %s for %s"), + dependencies[i], gplugin_plugin_info_get_id(info));
+ g_slist_free_full(ret, g_object_unref); + g_object_unref(G_OBJECT(info)); - ret = g_slist_prepend(ret, dep);
+ g_object_unref(G_OBJECT(info)); @@ -904,11 +889,15 @@
/* destroy the filename view */
g_clear_pointer(&manager->plugins_filename_view, g_hash_table_destroy);
+ /* clean up our list of loaders */ + g_slist_free_full(manager->loaders, g_object_unref); + manager->loaders = NULL; /* free all the data in the loaders hash table and destroy it */
- g_hash_table_foreach_remove(manager->loaders,
+ g_hash_table_foreach_remove(manager->loaders_by_extension, gplugin_manager_remove_list_value,
- g_clear_pointer(&manager->loaders, g_hash_table_destroy);
+ g_clear_pointer(&manager->loaders_by_extension, g_hash_table_destroy); /* call the base class's destructor */
G_OBJECT_CLASS(gplugin_manager_parent_class)->finalize(obj);
@@ -1065,18 +1054,18 @@
manager->plugins_filename_view =
g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref);
- /* The loaders hash table is keyed on the supported extensions of the
- * loader. Which means that a loader that supports multiple extensions
- * will be in the table multiple times.
+ /* The loaders_by_extension hash table is keyed on the supported extensions + * of the loader. Which means that a loader that supports multiple + * extensions will be in the table multiple times. * We deal with collisions by using a GSList for the value which will hold
* references to instances of the actual loaders.
- * Storing this in this method allows up to quickly figure out which loader
+ * Storing this in this method allows us to quickly figure out which loader * to use by the filename and helps us to avoid iterating the loaders table
+ manager->loaders_by_extension = g_hash_table_new_full(gplugin_manager_str_hash, g_str_equal,
@@ -1086,13 +1075,22 @@
*****************************************************************************/
gplugin_manager_private_init(void) {
instance = g_object_new(GPLUGIN_TYPE_MANAGER, NULL);
- gplugin_manager_register_loader(GPLUGIN_TYPE_NATIVE_LOADER);
+ if(!gplugin_manager_register_loader(GPLUGIN_TYPE_NATIVE_LOADER, &error)) { + g_error("failed to register loader: %s", error->message); + g_error("failed to register loader: unknown failure"); dependency_regex = g_regex_new(dependency_pattern, 0, 0, NULL);
@@ -1110,7 +1108,7 @@
* gplugin_manager_append_path:
- * @path: A path to add to the end of the plugin search paths
+ * @path: A path to add to the end of the plugin search paths. * Adds @path to the end of the list of paths to search for plugins.
@@ -1129,7 +1127,7 @@
* gplugin_manager_prepend_path:
- * @path: A path to add to the beginning of the plugin search paths
+ * @path: A path to add to the beginning of the plugin search paths. * Adds @path to the beginning of the list of paths to search for plugins.
@@ -1148,7 +1146,7 @@
* gplugin_manager_remove_path:
- * @path: A path to remove from the plugin search paths
+ * @path: A path to remove from the plugin search paths. * Removes @path from the list of paths to search for plugins.
@@ -1187,7 +1185,8 @@
* gplugin_manager_add_default_paths:
* Adds the path that GPlugin was installed to to the plugin search path, as
- * well as ${XDG_CONFIG_HOME}/gplugin.
+ * well as `${XDG_CONFIG_HOME}/gplugin` so users can install additional loaders gplugin_manager_add_default_paths(void) {
@@ -1209,8 +1208,8 @@
* @appname: The name of the application whose paths to add.
* Adds the application installation path for @appname. This will add
- * $prefix/@appname/plugins to the list as well as
- * ${XDG_CONFIG_HOME}/@appname/plugins.
+ * `@prefix/@appname/plugins` to the list as well as + * `${XDG_CONFIG_HOME}/@appname/plugins`. gplugin_manager_add_app_paths(const gchar *prefix,
@@ -1232,10 +1231,10 @@
* gplugin_manager_get_paths:
- * Gets the list of paths which will be search for plugins.
+ * Gets the list of paths which will be searched for plugins. - * Return value: (element-type utf8) (transfer none): list of paths which will
- * be searched for plugins.
+ * Returns: (element-type utf8) (transfer none): The list of paths which will + * be searched for plugins. gplugin_manager_get_paths(void) {
@@ -1253,38 +1252,56 @@
* gplugin_manager_register_loader:
- * @type: #GType of a #GPluginLoader
+ * @type: #GType of a #GPluginLoader. + * @error: (out) (nullable): The return address for a #GError. * Registers @type as an available loader.
+ * Returns: %TRUE if the loader was successfully register, %FALSE otherwise
-gplugin_manager_register_loader(GType type) {
+gplugin_manager_register_loader(GType type, GError **error) { GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE;
GPluginManagerClass *klass = NULL;
- g_return_if_fail(GPLUGIN_IS_MANAGER(manager));
+ g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), FALSE); klass = GPLUGIN_MANAGER_GET_CLASS(manager);
if(klass && klass->register_loader)
- klass->register_loader(manager, type);
+ return klass->register_loader(manager, type, error); + g_set_error(error, GPLUGIN_DOMAIN, 0, + "register_loader method not implemented"); * gplugin_manager_unregister_loader:
- * @type: #GType of a #GPluginLoader
+ * @type: #GType of a #GPluginLoader. + * @error: (out) (nullable): The return address for a #GError. * Unregisters @type as an available loader.
+ * Returns: %TRUE if the loader was successfully unregistered, %FALSE + * otherwise with @error set.
-gplugin_manager_unregister_loader(GType type) {
+gplugin_manager_unregister_loader(GType type, GError **error) { GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE;
GPluginManagerClass *klass = NULL;
- g_return_if_fail(GPLUGIN_IS_MANAGER(manager));
+ g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), FALSE); klass = GPLUGIN_MANAGER_GET_CLASS(manager);
if(klass && klass->unregister_loader)
- klass->unregister_loader(manager, type);
+ return klass->unregister_loader(manager, type, error); + g_set_error(error, GPLUGIN_DOMAIN, 0, + "unregister_loader method not implemented"); @@ -1306,14 +1323,14 @@
* gplugin_manager_find_plugins:
- * @id: id string of the plugin to find
+ * @id: id string of the plugin to find. * Finds all plugins matching @id.
- * Return value: (element-type GPlugin.Plugin) (transfer full): A #GSList of
- * referenced #GPluginPlugin's matching @id. Call
- * #gplugin_manager_free_plugin_list on the returned value
- * when you're done with it.
+ * Returns: (element-type GPlugin.Plugin) (transfer full): A #GSList of + * referenced #GPluginPlugin's matching @id. Call + * g_slist_free_full() with a `DestroyNotify` of g_object_unref() on + * the returned value when you're done with it. gplugin_manager_find_plugins(const gchar *id) {
@@ -1330,30 +1347,84 @@
- * gplugin_manager_free_plugin_list:
- * @plugins_list: (element-type GPlugin.Plugin): Returned value from
- * #gplugin_manager_find_plugins
+ * gplugin_manager_find_plugins_with_version: + * @id: The ID of the plugin to find. + * @op: one of <, <=, =, ==, >=, >. + * @version: The version to compare against. + * Similar to gplugin_manager_find_plugins() but only returns plugins whose + * versions match @op and @version. This is primarily used for dependency + * loading where a plugin may depend on a specific range of versions of another - * Frees the return value of #gplugin_manager_find_plugins.
+ * Returns: (element-type GPlugin.Plugin) (transfer full): A #GSList of + * referenced #GPluginPlugin's matching @id. Call + * g_slist_free_full() with a `DestroyNotify` of g_object_unref() on + * the returned value when you're done with it.
-gplugin_manager_free_plugin_list(GSList *plugins_list) {
+gplugin_manager_find_plugins_with_version(const gchar *id, const gchar *op, + GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE; + GSList *plugins = NULL, *filtered = NULL, *l = NULL; - g_return_if_fail(plugins_list != NULL);
+ g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), NULL); - for(l = plugins_list; l; l = l->next) {
- GPluginPlugin *plugin = NULL;
+ plugins = gplugin_manager_find_plugins(id);
- plugin = GPLUGIN_PLUGIN(l->data);
- g_object_unref(G_OBJECT(plugin));
+ if(op == NULL && version == NULL) { + /* we weren't actually passed an operator and a version so just return + * the list we have based on the id. - g_slist_free(plugins_list);
+ for(l = plugins; l; l = l->next) { + GPluginPlugin *plugin = GPLUGIN_PLUGIN(l->data); + GPluginPluginInfo *info = NULL; + const gchar *found_version = NULL; + /* get the plugin's version from it's info */ + info = gplugin_plugin_get_info(plugin); + found_version = gplugin_plugin_info_get_version(info); + g_object_unref(G_OBJECT(info)); + /* now compare the version of the plugin to passed in version. This + * should be done in this order so it's easier to track the operators. + * IE: we want to keep the inequality the same. + result = gplugin_version_compare(found_version, version, &error); + g_warning("failed to compare versions for %s: %s", + error->message ? error->message : _("unknown error")); + keep = (g_strcmp0(op, "<") == 0 || g_strcmp0(op, "<=") == 0); + } else if(result == 0) { + keep = (g_strcmp0(op, "=") == 0 || g_strcmp0(op, "==") == 0 || + g_strcmp0(op, "<=") == 0 || g_strcmp0(op, ">=") == 0); + } else if(result > 0) { + keep = (g_strcmp0(op, ">") == 0 || g_strcmp0(op, ">=") == 0); + filtered = g_slist_prepend(filtered, g_object_ref(G_OBJECT(plugin))); + g_slist_free_full(plugins, g_object_unref); + return g_slist_reverse(filtered); @@ -1380,7 +1451,7 @@
plugin = GPLUGIN_PLUGIN(g_object_ref(G_OBJECT(plugins_list->data)));
- gplugin_manager_free_plugin_list(plugins_list);
+ g_slist_free_full(plugins_list, g_object_unref); @@ -1388,13 +1459,15 @@
* gplugin_manager_get_plugin_dependencies:
* @plugin: The #GPluginPlugin whose dependencies to get.
- * @error: Return address for a #GError.
+ * @error: (out) (nullable): Return address for a #GError. * Returns a list of all the #GPluginPlugin's that @plugin depends on.
* Return value: (element-type GPlugin.Plugin) (transfer full): A #GSList of
- * #GPluginPlugin's that @plugin depends on, or NULL on error
+ * #GPluginPlugin's that @plugin depends on, or %NULL on error + * with @error set. Call g_slist_free_full() with a + * `DestroyNotify` of g_object_unref() on the returned value when gplugin_manager_get_plugin_dependencies(GPluginPlugin *plugin, GError **error) {
@@ -1416,15 +1489,15 @@
* gplugin_manager_load_plugin:
- * @plugin: #GPluginPlugin instance
- * @error: (out): return location for a #GError or null
+ * @plugin: #GPluginPlugin instance. + * @error: (out) (nullable): return location for a #GError or %NULL. - * Loads @plugin and all of it's dependencies. If a dependency can not be
+ * Loads @plugin and all of its dependencies. If a dependency can not be * loaded, @plugin will not be loaded either. However, any other plugins that
* @plugin depends on that were loaded from this call, will not be unloaded.
- * Return value: TRUE if @plugin was loaded successfully or already loaded,
+ * Return value: %TRUE if @plugin was loaded successfully or already loaded, gplugin_manager_load_plugin(GPluginPlugin *plugin, GError **error) {
@@ -1445,13 +1518,13 @@
* gplugin_manager_unload_plugin:
- * @plugin: #GPluginPlugin instance
- * @error: (out): return location for a #GError or null
+ * @plugin: #GPluginPlugin instance. + * @error: (out) (nullable): Return location for a #GError or %NULL. * Unloads @plugin. If @plugin has dependencies, they are not unloaded.
- * Return value: TRUE if @plugin was unloaded successfully or not loaded,
+ * Returns: %TRUE if @plugin was unloaded successfully or not loaded, %FALSE gplugin_manager_unload_plugin(GPluginPlugin *plugin, GError **error) {
@@ -1503,8 +1576,8 @@
* This is provided so that signals can be connected and should not be tinkered
- * Return Value: (transfer none): The #GObject that is the instance of the
+ * Returns: (transfer none): The #GObject that is the instance of the plugin gplugin_manager_get_instance(void) {
@@ -1513,4 +1586,3 @@
--- a/gplugin/gplugin-manager.h Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-manager.h Tue Feb 25 22:30:11 2020 -0600
@@ -39,13 +39,13 @@
GList *gplugin_manager_get_paths(void);
-void gplugin_manager_register_loader(GType type);
-void gplugin_manager_unregister_loader(GType type);
+gboolean gplugin_manager_register_loader(GType type, GError **error); +gboolean gplugin_manager_unregister_loader(GType type, GError **error); void gplugin_manager_refresh(void);
GSList *gplugin_manager_find_plugins(const gchar *id);
-void gplugin_manager_free_plugin_list(GSList *plugins_list);
+GSList *gplugin_manager_find_plugins_with_version(const gchar *id, const gchar *op, const gchar *version); GPluginPlugin *gplugin_manager_find_plugin(const gchar *id);
--- a/gplugin/gplugin-native-loader.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-native-loader.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,7 +22,7 @@
#include <gplugin/gplugin-native-plugin.h>
#include <gplugin/gplugin-native-private.h>
+#include <glib/gi18n-lib.h> @@ -31,14 +31,6 @@
#define GPLUGIN_UNLOAD_SYMBOL "gplugin_unload"
- * SECTION:gplugin-native-loader
- * @Title: Native Loader API
- * @Short_description: API for the native plugin loader
- * Basic API for the native plugin loader.
* GPLUGIN_TYPE_NATIVE_LOADER:
* The standard _get_type macro for #GPluginNativeLoader.
@@ -109,12 +101,12 @@
* GPluginLoaderInterface API
*****************************************************************************/
-gplugin_native_loader_class_supported_extensions(G_GNUC_UNUSED GPluginLoaderClass *klass) {
+gplugin_native_loader_supported_extensions(G_GNUC_UNUSED GPluginLoader *l) { GSList *exts = g_slist_append(NULL, G_MODULE_SUFFIX);
#if defined(__APPLE__) || defined(__MACH__)
- /* G_MODULE_SUFFIX only requests so on not windows, and both .so and
- * .dylib are use on macos, so add dylib if we're on macos.
+ /* G_MODULE_SUFFIX only requests `.so` on not windows, and both .so and + * .dylib are used on macos, so add dylib if we're on macos. * See: https://gitlab.gnome.org/GNOME/glib/issues/1413
exts = g_slist_append(exts, "dylib");
@@ -315,7 +307,7 @@
GPLUGIN_LOADER_CLASS(klass);
loader_class->supported_extensions =
- gplugin_native_loader_class_supported_extensions;
+ gplugin_native_loader_supported_extensions; loader_class->query = gplugin_native_loader_query;
loader_class->load = gplugin_native_loader_load;
loader_class->unload = gplugin_native_loader_unload;
--- a/gplugin/gplugin-native-loader.h Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-native-loader.h Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -37,4 +37,3 @@
#endif /* GPLUGIN_NATIVE_LOADER_H */
--- a/gplugin/gplugin-native-plugin.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-native-plugin.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -24,16 +24,7 @@
#include <gplugin/gplugin-core.h>
- * SECTION:gplugin-native-plugin
- * @Title: Native Plugin API
- * @Short_description: API for native plugins
- * API for use by native plugins. That is plugins written in a compiled
+#include <glib/gi18n-lib.h> * GPLUGIN_TYPE_NATIVE_PLUGIN:
@@ -274,4 +265,3 @@
--- a/gplugin/gplugin-native-plugin.h Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-native-plugin.h Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -36,4 +36,3 @@
#endif /* GPLUGIN_NATIVE_PLUGIN_H */
--- a/gplugin/gplugin-native-private.h Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-native-private.h Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -35,4 +35,3 @@
#endif /* GPLUGIN_PRIVATE_H */
--- a/gplugin/gplugin-native.h.in Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-native.h.in Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
--- a/gplugin/gplugin-options.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-options.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -16,7 +16,7 @@
+#include <glib/gi18n-lib.h> #include <gplugin/gplugin-options.h>
@@ -99,7 +99,8 @@
* g_option_context_add_group(), if you are using g_option_context_parse() to
* parse your commandline arguments.
- * GPlugin must be initialized before you call this function.
+ * If gplugin_init() has yet to be called before g_option_context_parse() is + * called, gplugin_init() will be called automatically. * Return Value: (transfer full): a #GOptionGroup for the commandline arguments
@@ -118,4 +119,3 @@
--- a/gplugin/gplugin-options.h Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-options.h Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -23,7 +23,6 @@
#define GPLUGIN_OPTIONS_H
-#include <glib-object.h>
@@ -32,4 +31,3 @@
#endif /* GPLUGIN_OPTIONS_H */
--- a/gplugin/gplugin-plugin-info.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-plugin-info.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -24,7 +24,7 @@
* SECTION:gplugin-plugin-info
* @Title: Plugin Info Objects
- * @Short_description: information about plugins
+ * @Short_description: information about plugins. * #GPluginPluginInfo holds metadata for plugins.
@@ -57,19 +57,17 @@
- GPluginVersionCompareFunc version_func;
@@ -96,12 +94,11 @@
@@ -204,11 +201,13 @@
-gplugin_plugin_info_set_icon(GPluginPluginInfo *info, const gchar *icon) {
+gplugin_plugin_info_set_icon_name(GPluginPluginInfo *info, + const gchar *icon_name) GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
- priv->icon = g_strdup(icon);
+ g_free(priv->icon_name); + priv->icon_name = g_strdup(icon_name); @@ -252,15 +251,6 @@
-gplugin_plugin_info_set_help(GPluginPluginInfo *info, const gchar *help)
- GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
- priv->help = g_strdup(help);
gplugin_plugin_info_set_website(GPluginPluginInfo *info,
@@ -326,8 +316,8 @@
g_value_set_string(value,
gplugin_plugin_info_get_license_url(info));
- g_value_set_string(value, gplugin_plugin_info_get_icon(info));
+ g_value_set_string(value, gplugin_plugin_info_get_icon_name(info)); g_value_set_string(value, gplugin_plugin_info_get_summary(info));
@@ -342,9 +332,6 @@
g_value_set_boxed(value, gplugin_plugin_info_get_authors(info));
- g_value_set_string(value, gplugin_plugin_info_get_help(info));
g_value_set_string(value, gplugin_plugin_info_get_website(info));
@@ -400,8 +387,8 @@
gplugin_plugin_info_set_license_url(info,
g_value_get_string(value));
- gplugin_plugin_info_set_icon(info, g_value_get_string(value));
+ gplugin_plugin_info_set_icon_name(info, g_value_get_string(value)); gplugin_plugin_info_set_summary(info, g_value_get_string(value));
@@ -416,9 +403,6 @@
gplugin_plugin_info_set_authors(info, g_value_get_boxed(value));
- gplugin_plugin_info_set_help(info, g_value_get_string(value));
gplugin_plugin_info_set_website(info, g_value_get_string(value));
@@ -442,11 +426,10 @@
g_clear_pointer(&priv->license_id, g_free);
g_clear_pointer(&priv->license_text, g_free);
g_clear_pointer(&priv->license_url, g_free);
- g_clear_pointer(&priv->icon, g_free);
+ g_clear_pointer(&priv->icon_name, g_free); g_clear_pointer(&priv->summary, g_free);
g_clear_pointer(&priv->description, g_free);
g_clear_pointer(&priv->authors, g_strfreev);
- g_clear_pointer(&priv->help, g_free);
g_clear_pointer(&priv->website, g_free);
g_clear_pointer(&priv->dependencies, g_strfreev);
@@ -474,8 +457,8 @@
* While not required, the recommended convention is to use the following
* format: <application or library>/<name of the plugin>.
- * For example, the python loader in GPlugin has an id of
- * "gplugin/python-plugin-loader".
+ * For example, the Python3 loader in GPlugin has an id of + * "gplugin/python3-loader". properties[PROP_ID] = g_param_spec_string(
@@ -490,14 +473,16 @@
* The GPlugin ABI version that the plugin was compiled against.
- * GPlugin only uses the first byte (0xff000000) of this value. The
+ * GPlugin only uses the first byte (`0xff000000`) of this value. The * remaining 3 bytes are available for the application to use.
* Take the following example from an application:
+ * |[<!-- language="C" --> * #define ABI_VERSION (GPLUGIN_NATIVE_ABI_VERSION |
* (APPLICATION_MAJOR_VERSION << 8) |
* (APPLICATION_MINOR_VERSION))
* The application here uses the thrid and fourth bytes, but could use
@@ -514,7 +499,7 @@
* Whether or not the plugin is considered an "internal" plugin.
properties[PROP_INTERNAL] = g_param_spec_boolean(
@@ -531,7 +516,7 @@
* This is used by the loaders and may be useful to your application as
properties[PROP_LOQ] = g_param_spec_boolean(
"load-on-query", "load-on-query",
@@ -543,7 +528,7 @@
* GPluginPluginInfo:bind-local:
- * Determines whether the plugin should be have it's symbols bound locally.
+ * Determines whether the plugin should be have its symbols bound locally. * Note: This should only be used by the native plugin loader.
@@ -569,7 +554,7 @@
* GPluginPluginInfo:version:
- * The version of the plugin.
+ * The version of the plugin. Preferably a semantic version. properties[PROP_VERSION] = g_param_spec_string(
@@ -584,8 +569,8 @@
* The short name of the license.
* It is recommended to use the identifier of the license from
- * http://dep.debian.net/deps/dep5/#license-specification and should be
- * "Other" for licenses that are not mentioned in DEP5.
+ * https://spdx.org/licenses/ and should be "Other" for licenses that are * If a plugin has multiple license, they should be separated by a pipe
* (|). In the odd case that you have multiple licenses that are used at
@@ -602,7 +587,7 @@
* GPluginPluginInfo:license-text:
* The text of the license for this plugin. This should only be used when
- * the plugin is licensed under a license that is not listed in DEP5.
+ * the plugin is licensed under a license that is not listed at spdx.org. properties[PROP_LICENSE_TEXT] = g_param_spec_string(
"license-text", "license text",
@@ -615,7 +600,7 @@
* GPluginPluginInfo:license-url:
* The url to the text of the license. This should primarily only be used
- * for licenses not listed in DEP5.
+ * for licenses not listed at spdx.org. properties[PROP_LICENSE_URL] = g_param_spec_string(
"license-url", "license url",
@@ -625,14 +610,14 @@
- * GPluginPluginInfo:icon:
+ * GPluginPluginInfo:icon-name: - * A string representing an icon for the plugin. The actual use of this
- * is determined by the application/library using GPlugin.
+ * A XDG icon name for the plugin. The actual use of this is determined by + * the application/library using GPlugin. - properties[PROP_ICON] = g_param_spec_string(
- "The file path of the icon for the plugin",
+ properties[PROP_ICON_NAME] = g_param_spec_string( + "icon-name", "icon-name", + "The XDG icon name for the plugin", G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
@@ -683,11 +668,10 @@
* GPluginPluginInfo:authors:
- * A gchar ** of the names and email addresses of the authors.
+ * A list of the names and email addresses of the authors. * It is recommended to use the RFC 822, 2822 format of:
- * "First Last <user@domain.com>" with additional authors separated by a
+ * `"First Last <user@domain.com>"`. properties[PROP_AUTHORS] = g_param_spec_boxed(
@@ -697,18 +681,6 @@
- * GPluginPluginInfo:help:
- * The url of the plugin that can be represented in a user interface.
- properties[PROP_HELP] = g_param_spec_string(
- "The help string for the plugin",
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
* GPluginPluginInfo:website:
* The url of the plugin that can be represented in a user interface.
@@ -741,18 +713,18 @@
* gplugin_plugin_info_new: (skip)
- * @id: The id of the plugin
- * @abi_version: The GPlugin ABI version that the plugin uses
+ * @id: The id of the plugin. + * @abi_version: The GPlugin ABI version that the plugin uses. * @...: name/value pairs of properties to set, followed by %NULL.
- * Creates a new GPluginPluginInfo instance.
+ * Creates a new #GPluginPluginInfo instance. - * Returns: The new GPluginPluginInfo instance.
+ * Returns: (transfer full): The new #GPluginPluginInfo instance. * gplugin_plugin_info_get_id:
- * @info: #GPluginPluginInfo instance
+ * @info: The #GPluginPluginInfo instance. * Returns the id that the plugin identifies itself as.
@@ -771,7 +743,7 @@
* gplugin_plugin_info_get_abi_version:
- * @info: #GPluginPluginInfo instance
+ * @info: The #GPluginPluginInfo instance. * Returns the ABI or Application Binary Interface version that the plugin
* is supposed to work against.
@@ -791,13 +763,13 @@
* gplugin_plugin_info_get_internal:
- * @info: #GPluginPluginInfo instance
+ * @info: The #GPluginPluginInfo instance. * Returns where or not this plugin is is considered an internal plugin. An
* internal plugin would be something like a plugin loader or another plugin
* that should not be shown to users.
- * Returns: TRUE if the plugin is internal, FALSE otherwise.
+ * Returns: %TRUE if the plugin is internal, %FALSE otherwise. gplugin_plugin_info_get_internal(GPluginPluginInfo *info) {
@@ -812,14 +784,14 @@
* gplugin_plugin_info_get_load_on_query:
- * @info: #GPluginPluginInfo instance
+ * @info: The #GPluginPluginInfo instance. * Returns whether or not this plugin should be loaded when queried. This is
* useful for internal plugins that are adding functionality and should always
* be turned on. The plugin loaders use this to make sure all plugins can
- * Returns: TRUE if the plugin should be loaded on query, FALSE otherwise.
+ * Returns: %TRUE if the plugin should be loaded on query, %FALSE otherwise. gplugin_plugin_info_get_load_on_query(GPluginPluginInfo *info) {
@@ -834,7 +806,7 @@
* gplugin_plugin_info_get_name:
- * @info: #GPluginPluginInfo instance
+ * @info: The #GPluginPluginInfo instance. * Returns the name of the plugin as specified in @info.
@@ -853,7 +825,7 @@
* gplugin_plugin_info_get_version:
- * @info: #GPluginPluginInfo instance
+ * @info: The #GPluginPluginInfo instance. * Returns the version of the plugin as specified in @info.
@@ -871,29 +843,8 @@
- * gplugin_plugin_info_get_version_func: (skip)
- * @info: #GPluginPluginInfo instance
- * Returns the #GPluginVersionCompareFunc used to compare versions of the
- * Returns: The #GPluginVersionCompareFunc that can compare versions of this
-GPluginVersionCompareFunc
-gplugin_plugin_info_get_version_func(GPluginPluginInfo *info) {
- GPluginPluginInfoPrivate *priv = NULL;
- g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
- priv = gplugin_plugin_info_get_instance_private(info);
- return priv->version_func;
* gplugin_plugin_info_get_license_id:
- * @info: #GPluginPluginInfo instance
+ * @info: The #GPluginPluginInfo instance. * Returns the liences id for the plugin as specified in @info.
@@ -912,7 +863,7 @@
* gplugin_plugin_info_get_license_text:
- * @info: #GPluginPluginInfo instance
+ * @info: The #GPluginPluginInfo instance. * Returns the license text for the plugin as specified in @info.
@@ -931,7 +882,7 @@
* gplugin_plugin_info_get_license_url:
- * @info: #GPluginPluginInfo instance
+ * @info: The #GPluginPluginInfo instance. * Returns the url of the license for the plugin as specified in @info
@@ -949,27 +900,27 @@
- * gplugin_plugin_info_get_icon:
- * @info: #GPluginPluginInfo instance
+ * gplugin_plugin_info_get_icon_name: + * @info: The #GPluginPluginInfo instance. * Returns the name of the icon for the plugin as specified in @info.
- * Returns: The icon from @info.
+ * Returns: The icon name from @info. -gplugin_plugin_info_get_icon(GPluginPluginInfo *info) {
+gplugin_plugin_info_get_icon_name(GPluginPluginInfo *info) { GPluginPluginInfoPrivate *priv = NULL;
g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
priv = gplugin_plugin_info_get_instance_private(info);
+ return priv->icon_name; * gplugin_plugin_info_get_summary:
- * @info: #GPluginPluginInfo instance
+ * @info: The #GPluginPluginInfo instance. * Returns the summery for the plugin as specified in @info.
@@ -988,7 +939,7 @@
* gplugin_plugin_info_get_description:
- * @info: #GPluginPluginInfo instance
+ * @info: The #GPluginPluginInfo instance. * Returns the description for the plugin as specified in @info.
@@ -1007,7 +958,7 @@
* gplugin_plugin_info_get_category:
- * @info: #GPluginPluginInfo instance
+ * @info: The #GPluginPluginInfo instance. * Returns the category of the plugin as specified in @info.
@@ -1026,7 +977,7 @@
* gplugin_plugin_info_get_authors:
- * @info: #GPluginPluginInfo instance
+ * @info: The #GPluginPluginInfo instance. * Returns the authors of the plugin as specified in @info.
@@ -1044,27 +995,8 @@
- * gplugin_plugin_info_get_help:
- * @info: #GPluginPluginInfo instance
- * Returns the help text for the plugin as specified in @info.
- * Returns: The help from @info.
-gplugin_plugin_info_get_help(GPluginPluginInfo *info) {
- GPluginPluginInfoPrivate *priv = NULL;
- g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
- priv = gplugin_plugin_info_get_instance_private(info);
* gplugin_plugin_info_get_website:
- * @info: #GPluginPluginInfo instance
+ * @info: The #GPluginPluginInfo instance. * Returns the website for the plugin as specified in @info.
@@ -1083,7 +1015,7 @@
* gplugin_plugin_info_get_dependencies:
- * @info: #GPluginPluginInfo instance
+ * @info: The #GPluginPluginInfo instance. * Returns the dependencies of the plugins as specified in @info.
@@ -1103,12 +1035,12 @@
* gplugin_plugin_info_get_bind_local:
- * @info: #GPluginPluginInfo instance
+ * @info: The #GPluginPluginInfo instance. * This function is only used by the native plugin loader.
- * Returns: TRUE if the plugin has requested to be loaded with it's symbols
- * bound locally, FALSE if they should bind be bound globally.
+ * Returns: %TRUE if the plugin has requested to be loaded with its symbols + * bound locally, %FALSE if they should be bound globally. gplugin_plugin_info_get_bind_local(GPluginPluginInfo *info) {
@@ -1120,4 +1052,3 @@
--- a/gplugin/gplugin-plugin-info.h Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-plugin-info.h Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -58,16 +58,14 @@
const gchar *gplugin_plugin_info_get_license_id(GPluginPluginInfo *info);
const gchar *gplugin_plugin_info_get_license_text(GPluginPluginInfo *info);
const gchar *gplugin_plugin_info_get_license_url(GPluginPluginInfo *info);
-const gchar *gplugin_plugin_info_get_icon(GPluginPluginInfo *info);
+const gchar *gplugin_plugin_info_get_icon_name(GPluginPluginInfo *info); const gchar *gplugin_plugin_info_get_summary(GPluginPluginInfo *info);
const gchar *gplugin_plugin_info_get_description(GPluginPluginInfo *info);
const gchar *gplugin_plugin_info_get_category(GPluginPluginInfo *info);
const gchar * const *gplugin_plugin_info_get_authors(GPluginPluginInfo *info);
const gchar *gplugin_plugin_info_get_website(GPluginPluginInfo *info);
const gchar * const *gplugin_plugin_info_get_dependencies(GPluginPluginInfo *info);
-const gchar *gplugin_plugin_info_get_help(GPluginPluginInfo *info);
#endif /* GPLUGIN_PLUGIN_INFO_H */
--- a/gplugin/gplugin-plugin.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-plugin.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,25 +22,25 @@
- * @Title: Plugin Objects
- * @Short_description: abstract plugin implementation
+ * @Title: Plugin Interface + * @Short_description: The plugin interface that all plugins must implement. - * #GPluginPlugin is an abstract class that tracks the state of a plugin. It
- * is subclassed by each loader for them to add additional data for their
+ * #GPluginPlugin is an interface that defines the behavior of plugins. It + * is implemented by each loader which add additional data for their - * @GPLUGIN_PLUGIN_STATE_UNKNOWN: The state of the plugin is unknown
+ * @GPLUGIN_PLUGIN_STATE_UNKNOWN: The state of the plugin is unknown. * @GPLUGIN_PLUGIN_STATE_ERROR: There was an error loading or unloading the
- * @GPLUGIN_PLUGIN_STATE_QUERIED: The plugin has been queried but not loaded
- * @GPLUGIN_PLUGIN_STATE_REQUERY: The plugin should be requeried
- * @GPLUGIN_PLUGIN_STATE_LOADED: The plugin is loaded
- * @GPLUGIN_PLUGIN_STATE_LOAD_FAILED: The plugin failed to load
+ * @GPLUGIN_PLUGIN_STATE_QUERIED: The plugin has been queried but not loaded. + * @GPLUGIN_PLUGIN_STATE_REQUERY: The plugin should be requeried. + * @GPLUGIN_PLUGIN_STATE_LOADED: The plugin is loaded. + * @GPLUGIN_PLUGIN_STATE_LOAD_FAILED: The plugin failed to load. - * The expected states of a plugin.
+ * The known states of a plugin. @@ -57,7 +57,8 @@
* GPluginPluginInterface:
- * @state_changed: The class closure for the #GPluginPlugin::state-changed signal.
+ * @state_changed: The class closure for the #GPluginPlugin::state-changed * The interface that defines the behavior of plugins, including properties and
@@ -162,11 +163,11 @@
* gplugin_plugin_get_filename:
- * @plugin: #GPluginPlugin instance
+ * @plugin: The #GPluginPlugin instance. * Returns the filename that @plugin was loaded from.
- * Returns: (transfer full): The filename of @plugin
+ * Returns: (transfer full): The filename of @plugin. gplugin_plugin_get_filename(GPluginPlugin *plugin) {
@@ -181,11 +182,11 @@
* gplugin_plugin_get_loader:
- * @plugin: #GPluginPlugin instance
+ * @plugin: The #GPluginPlugin instance. * Returns the #GPluginLoader that loaded @plugin.
- * Returns: (transfer full): The #GPluginLoader that loaded @plugin
+ * Returns: (transfer full): The #GPluginLoader that loaded @plugin. gplugin_plugin_get_loader(GPluginPlugin *plugin) {
@@ -200,11 +201,11 @@
* gplugin_plugin_get_info:
- * @plugin: #GPluginPlugin instance
+ * @plugin: The #GPluginPlugin instance. * Returns the #GPluginPluginInfo for @plugin.
- * Returns: (transfer full): The #GPluginPluginInfo instance for @plugin
+ * Returns: (transfer full): The #GPluginPluginInfo instance for @plugin. gplugin_plugin_get_info(GPluginPlugin *plugin) {
@@ -219,11 +220,11 @@
* gplugin_plugin_get_state:
- * @plugin: #GPluginPlugin instance
+ * @plugin: The #GPluginPlugin instance. - * Gets the current state of @plugin
+ * Gets the current state of @plugin. - * Returns: (transfer full): The current state of @plugin
+ * Returns: (transfer full): The current state of @plugin. gplugin_plugin_get_state(GPluginPlugin *plugin) {
@@ -238,8 +239,8 @@
* gplugin_plugin_set_state:
- * @plugin: #GPluginPlugin instance
- * @state: new #GPluginPluginState for @plugin
+ * @plugin: The #GPluginPlugin instance. + * @state: A new #GPluginPluginState for @plugin. * Changes the state of @plugin to @state. This function should only be called
--- a/gplugin/gplugin-plugin.h Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-plugin.h Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -67,4 +67,3 @@
#endif /* GPLUGIN_PLUGIN_H */
--- a/gplugin/gplugin-private.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-private.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -33,4 +33,3 @@
return continue_emission;
--- a/gplugin/gplugin-private.h Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-private.h Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -40,4 +40,3 @@
#endif /* GPLUGIN_PRIVATE_H */
--- a/gplugin/gplugin-query.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-query.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -222,7 +222,7 @@
- gplugin_manager_free_plugin_list(plugins);
+ g_slist_free_full(plugins, g_object_unref); @@ -352,4 +352,3 @@
--- a/gplugin/gplugin-version.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-version.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -18,11 +18,11 @@
* SECTION:gplugin-version
* @Title: Version Information
- * @Short_description: variables and functions to check the GPlugin version
+ * @Short_description: variables and functions to check the version of GPlugin. - * GPlugin provides version information, primarily useful in configure
- * checks for builds that have a configure script. Applications will
- * not typically use the features described here.
+ * GPlugin provided version information, primarily useful when building against + * GPlugin. Applications will not typically use the features described here + * unless checking for new versions during builds. #include <gplugin/gplugin-core.h>
@@ -30,7 +30,7 @@
+#include <glib/gi18n-lib.h> /******************************************************************************
@@ -148,42 +148,71 @@
- * @major: the major version to compare for
- * @minor: the minor version to compare for
- * @micro: the micro version to compare for
+ * @major: The major version to compare for. + * @minor: The minor version to compare for. + * @micro: The micro version to compare for. * Checks the version of the GPlugin library that is being compiled
- * against. See gplugin_version_compare() for a runtime check.
* Returns: %TRUE if the version of the GPlugin header files
* is the same as or newer than the passed-in version.
- * GPluginVersionCompareFunc:
- * @v1: The first version to compare
- * @v2: The second version to compare
- * @error: A #GError return address if there are any errors.
+ * gplugin_version_check: + * @major: The required major version. + * @minor: The required minor version. + * @micro: The required micro version. + * Checks that the GPlugin library in use is compatible with the given version. + * Generally you would pass in the constants #GPLUGIN_MAJOR_VERSION, + * #GPLUGIN_MINOR_VERSION, #GPLUGIN_MICRO_VERSION as the three arguments to + * this function; that produces a check that the library in use is compatible + * with the version of GPlugin the application or module was compiled against. + * Compatibility is defined by two things: first the version of the running + * library is newer than the version @major.@minor.@micro. Second the running + * library must be binary compatible with the version @major.@minor.@micro + * (same major version). - * #GPluginVersionCompareFunc is used to compare two versions of a plugin. It
- * should return -1 if @v1 is greater than @v2, 0 if @v1 is equal to @v2, and
- * 1 if @v1 is less than @v2.
- * Returns: -1 if @v1 is greater than @v2, 0 if @v1 is equal to @v1, and 1 if
- * @v1 is less than @v2.
+ * Returns: %NULL if the GPlugin library is compatible with the given version, + * or a string describing the version mismatch. The returned string + * is owned by GPlugin and must not be modified or freed. +gplugin_version_check(guint major, guint minor, guint micro) { + if(major > GPLUGIN_MAJOR_VERSION) { + return "gplugin version too old (major mismatch)"; + /* disable the pvs-studio suppression after 1.0.0 is released */ + if(major < GPLUGIN_MAJOR_VERSION) { //-V547 + return "gplugin version too new (major mismatch)"; + if(minor > GPLUGIN_MINOR_VERSION) { + return "gplugin version too old (minor mismatch)"; + if(minor == GPLUGIN_MINOR_VERSION && micro > GPLUGIN_MICRO_VERSION) { + return "gplugin version too old (micro mismatch)"; * gplugin_version_compare:
- * @v1: The first version to compare
- * @v2: The second version to compare
- * @error: A #GError return address if there are any errors.
+ * @v1: The first version to compare. + * @v2: The second version to compare. + * @error: (out) (nullable): A #GError return address if there are any errors. - * The default #GPluginVersionCompareFunc. It handles the typical
- * MAJOR.MINOR.MICRO format and ignore any characters after the micro version.
+ * A semantic version checker which ignores any characters after the micro - * Returns: -1 if @v1 is greater than @v2, 0 if @v1 is equal to @v1, and 1 if
- * @v1 is less than @v2.
+ * Returns: less than 0 if @v1 is less than @v2, 0 if @v1 is equal to @v1, and + * greater than 0 if @v1 is greater than @v2. gplugin_version_compare(const gchar *v1, const gchar *v2, GError **error) {
@@ -199,21 +228,20 @@
/* make sure v1 matches the regex */
if(!gplugin_version_parser(v1, &v1_maj, &v1_min, &v1_mic, NULL, error))
/* make sure v2 matches the regex */
if(!gplugin_version_parser(v2, &v2_maj, &v2_min, &v2_mic, NULL, error))
/* now figure out if they match */
- return v2_mic - v1_mic;
+ return v1_mic - v2_mic;
--- a/gplugin/gplugin-version.h.in Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin-version.h.in Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -38,11 +38,10 @@
-typedef gint (*GPluginVersionCompareFunc)(const gchar *v1, const gchar *v2, GError **error);
+const gchar *gplugin_version_check(guint major, guint minor, guint micro); gint gplugin_version_compare(const gchar *v1, const gchar *v2, GError **error);
#endif /* GPLUGIN_VERSION_H */
--- a/gplugin/gplugin.h.in Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/gplugin.h.in Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -26,5 +26,3 @@
#undef GPLUGIN_GLOBAL_HEADER_INSIDE
--- a/gplugin/reference/embedding.xml Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/reference/embedding.xml Tue Feb 25 22:30:11 2020 -0600
@@ -13,8 +13,8 @@
- Using GPlugin is pretty simple and I'd like to think straight forward
- since that's the way I designed it.
+ GPlugin was designed to be simple to implement and use. Initialization + and teardown examples can be found below. @@ -30,14 +30,13 @@
gplugin_manager_add_default_paths();
/* Optionally tell GPlugin to look for plugins in application specific
+ * paths. This will add `$PREFIX/lib/application`. gplugin_manager_add_app_paths(PREFIX, "application");
/* Once you're ready to find/load plugins call g_plugin_manager_refresh.
gplugin_manager_refresh();
</programlisting></informalexample>
@@ -51,4 +50,4 @@
</programlisting></informalexample>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin/reference/genie.xml Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,70 @@
+<?xml version='1.0' encoding="UTF-8"?> +<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" + "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [ +<chapter id="chapter-genie"> + <title>Genie Plugins</title> + You <emphasis role="strong">MUST</emphasis> have the Vala bindings + installed on your system for this to work. They are built by the + <title>Example Genie Plugin</title> + Like all plugins in GPlugin, Genie plugins must also implement + the <code>gplugin_query</code>, <code>gplugin_load</code>, and + <code>gplugin_unload</code> functions. + Due to the way <code>GPlugin.PluginInfo</code> info works, you must + subclass it and set your values in the new constructor. + The following is a basic Genie plugin. + <informalexample><programlisting> + class BasicPluginInfo : GPlugin.PluginInfo + authors : array of string = {"author1"} + id: "gplugin/genie-basic-plugin", + abi_version: 0x01020304, + description: "description" + def gplugin_query(out error : Error) : GPlugin.PluginInfo + return new BasicPluginInfo() + def gplugin_load(plugin : GPlugin.Plugin, out error : Error) : bool + def gplugin_unload(plugin : GPlugin.Plugin, out error : Error) : bool + </programlisting></informalexample> --- a/gplugin/reference/gplugin-docs.xml Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/reference/gplugin-docs.xml Tue Feb 25 22:30:11 2020 -0600
@@ -11,10 +11,13 @@
<title>GPlugin &version;</title>
- GPlugin is a GObject based library that implements a reusable plugin system that
- supports loading plugins in other languages
- via loaders. GPlugin also implements
- dependencies among the plugins.
+ GPlugin is a GObject based library that implements a reusable plugin + system that supports loading plugins in other languages via loaders. + GPlugin also implements dependencies among the plugins. + The latest version of this documentation can be found on-line at + <ulink role="online-location" url="https://docs.pidgin.im/gplugin/latest">https://docs.pidgin.im/gplugin/latest/</ulink>. @@ -23,8 +26,10 @@
<xi:include href="embedding.xml"/>
+ <xi:include href="genie.xml"/> + <xi:include href="lua.xml"/> <xi:include href="native-plugins.xml"/>
- <xi:include href="lua.xml"/>
+ <xi:include href="perl.xml"/> <xi:include href="python.xml"/>
<xi:include href="vala.xml"/>
@@ -38,23 +43,13 @@
<title>API Reference</title>
- <title>Core API</title>
- <xi:include href="xml/gplugin-core.xml"/>
- <xi:include href="xml/gplugin-loader.xml"/>
- <xi:include href="xml/gplugin-manager.xml"/>
- <xi:include href="xml/gplugin-options.xml"/>
- <xi:include href="xml/gplugin-plugin-info.xml"/>
- <xi:include href="xml/gplugin-plugin.xml"/>
- <xi:include href="xml/gplugin-version.xml"/>
- <chapter id="nativeapi">
- <title>Native API</title>
- <xi:include href="xml/gplugin-native-plugin.xml"/>
- <xi:include href="xml/gplugin-native-loader.xml"/>
+ <xi:include href="xml/gplugin-core.xml"/> + <xi:include href="xml/gplugin-loader.xml"/> + <xi:include href="xml/gplugin-manager.xml"/> + <xi:include href="xml/gplugin-options.xml"/> + <xi:include href="xml/gplugin-plugin-info.xml"/> + <xi:include href="xml/gplugin-plugin.xml"/> + <xi:include href="xml/gplugin-version.xml"/> <index id="api-index-full">
--- a/gplugin/reference/lua.xml Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/reference/lua.xml Tue Feb 25 22:30:11 2020 -0600
@@ -24,33 +24,34 @@
The following is a basic Lua plugin.
- <informalexample><programlisting>
- local lgi = require 'lgi'
- local GPlugin = lgi.GPlugin
+ <informalexample><programlisting> + local lgi = require "lgi" + local GPlugin = lgi.GPlugin - function gplugin_query()
- return GPlugin.PluginInfo {
- id = "gplugin-lua/basic-plugin",
- abi_version = 0x01020304,
- license_id = "license-id",
- summary = "basic lua plugin",
- description = "description of the basic lua plugin",
- authors = { "Gary Kramlich <grim@reaperworld.com>" },
- website = "https://bitbucket.org/gplugin/gplugin/"
+ function gplugin_query() + return GPlugin.PluginInfo { + id = "gplugin-lua/basic-plugin", + abi_version = 0x01020304, + license_id = "license-id", + summary = "basic lua plugin", + description = "description of the basic lua plugin", + authors = { "Gary Kramlich <grim@reaperworld.com>" }, + website = "https://bitbucket.org/gplugin/gplugin/" - function gplugin_load(plugin)
+ function gplugin_load(plugin) - function gplugin_unload(plugin)
- </programlisting></informalexample>
+ function gplugin_unload(plugin) + </programlisting></informalexample> --- a/gplugin/reference/meson.build Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/reference/meson.build Tue Feb 25 22:30:11 2020 -0600
@@ -7,6 +7,8 @@
'gplugin-loader-tests.h',
'gplugin-native-private.h',
+ 'gplugin-native-loader.h', + 'gplugin-native-plugin.h', @@ -26,13 +28,17 @@
main_xml : DOC_MODULE + '-docs.xml',
dependencies : gplugin_dep,
ignore_headers : ignore_hfiles,
--- a/gplugin/reference/native-plugins.xml Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/reference/native-plugins.xml Tue Feb 25 22:30:11 2020 -0600
@@ -7,7 +7,7 @@
- Writing Native plugins is very simple, but since it's C/C++ it's a bit
+ Writing Native plugins is pretty simple, but since it's C/C++ it's a bit @@ -25,17 +25,17 @@
/* gplugin_plugin_query is called by the native loader to determine if
* the plugin is loadable. It must have this signature and should
- * return a valid GPluginPluginInfo if everything is fine. If something
- * went wrong, error should be set to a valid GError and NULL should be
+ * return a valid GPluginPluginInfo instance if everything is fine. If + * something went wrong, error should be set to a valid GError and NULL G_MODULE_EXPORT GPluginPluginInfo *
gplugin_plugin_query(GError **error) {
- /* Authors is a list of authors of the plugin. Generally these are
- * in the "Name Surname <user@domain.com>" format.
+ /* Authors is a list of authors who worked on the plugin. Generally + * these are in the "Name Surname <user@domain.com>" format. const gchar * const authors[] = {
+ "Author O <author@example.com>", --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin/reference/perl.xml Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,60 @@
+<?xml version='1.0' encoding="UTF-8"?> +<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" + "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [ +<chapter id="chapter-perl"> + <title>Perl Plugins</title> + You <emphasis role="strong">MUST</emphasis> have the Perl loader + plugin installed and working as well as the gobject-introspection + package for GPlugin installed to use Perl plugins. + <title>Example Perl Plugin</title> + Like all plugins in GPlugin, Perl plugins must also implement + the <code>gplugin_query</code>, <code>gplugin_load</code>, and + <code>gplugin_unload</code> functions. + The following is a basic Perl plugin. + <informalexample><programlisting> + use Glib::Object::Introspection; + Glib::Object::Introspection->setup(basename => "GPlugin", version => "0.0", package=> "GPlugin"); + return GPlugin::PluginInfo->new( + id => "gplugin/perl-basic-plugin", + abi_version => 0x01020304, + name => "basic plugin", + authors => ("author1"), + license_id => "license", + description => "description", + </programlisting></informalexample> --- a/gplugin/reference/python.xml Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/reference/python.xml Tue Feb 25 22:30:11 2020 -0600
@@ -24,33 +24,33 @@
The following is a basic Python plugin.
- <informalexample><programlisting>
- gi.require_version('GPlugin', '0.0')
- from gi.repository import GPlugin
+ <informalexample><programlisting> + gi.require_version("GPlugin", "0.0") + from gi.repository import GPlugin - def gplugin_plugin_query():
- return GPlugin.PluginInfo(
- id='gplugin-python/basic-plugin',
- abi_version=0x01020304,
- description='description',
+ def gplugin_plugin_query(): + return GPlugin.PluginInfo( + id="gplugin-python/basic-plugin", + abi_version=0x01020304, + description="description", - def gplugin_plugin_load(plugin):
+ def gplugin_plugin_load(plugin): - def gplugin_plugin_unload(plugin):
- </programlisting></informalexample>
+ def gplugin_plugin_unload(plugin): + </programlisting></informalexample> --- a/gplugin/reference/vala.xml Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/reference/vala.xml Tue Feb 25 22:30:11 2020 -0600
@@ -8,8 +8,8 @@
You <emphasis role="strong">MUST</emphasis> have the Vala bindings
- installed on your system for this to work. They are built by the
+ installed on your system for this to work. They are built by @@ -29,46 +29,47 @@
The following is a basic Vala plugin.
- <informalexample><programlisting>
- public class BasicPluginInfo : GPlugin.PluginInfo {
- public BasicPluginInfo() {
- string[] authors = {"author1"};
+ <informalexample><programlisting> + public class BasicPluginInfo : GPlugin.PluginInfo { + public BasicPluginInfo() { + string[] authors = {"author1"};
- id: "gplugin/vala-basic-plugin",
- abi_version: 0x01020304,
- description: "description"
+ id: "gplugin/vala-basic-plugin", + abi_version: 0x01020304, + description: "description"
- public GPlugin.PluginInfo gplugin_query(out Error error) {
- return new BasicPluginInfo();
+ public GPlugin.PluginInfo gplugin_query(out Error error) { - public bool gplugin_load(GPlugin.Plugin plugin, out Error error) {
+ return new BasicPluginInfo();
+ public bool gplugin_load(GPlugin.Plugin plugin, out Error error) { - public bool gplugin_unload(GPlugin.Plugin plugin, out Error error) {
+ public bool gplugin_unload(GPlugin.Plugin plugin, out Error error) {
- </programlisting></informalexample>
+ </programlisting></informalexample> --- a/gplugin/tests/bad-plugins/query-error.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/bad-plugins/query-error.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -38,4 +38,3 @@
--- a/gplugin/tests/bind-local/bind-local.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/bind-local/bind-local.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -42,4 +42,3 @@
--- a/gplugin/tests/dynamic-type/dynamic-test.h Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/dynamic-type/dynamic-test.h Tue Feb 25 22:30:11 2020 -0600
@@ -1,4 +1,5 @@
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * Copyright (C) 2013 Ankit Vani <a@nevitus.org>
* This library is free software; you can redistribute it and/or
--- a/gplugin/tests/dynamic-type/dynamic-type-provider.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/dynamic-type/dynamic-type-provider.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,4 +1,5 @@
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * Copyright (C) 2013 Ankit Vani <a@nevitus.org>
* This library is free software; you can redistribute it and/or
@@ -58,4 +59,3 @@
--- a/gplugin/tests/dynamic-type/dynamic-type-user.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/dynamic-type/dynamic-type-user.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,4 +1,5 @@
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * Copyright (C) 2013 Ankit Vani <a@nevitus.org>
* This library is free software; you can redistribute it and/or
@@ -67,4 +68,3 @@
--- a/gplugin/tests/id-collision/id-collision1.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/id-collision/id-collision1.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -42,4 +42,3 @@
--- a/gplugin/tests/id-collision/id-collision2.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/id-collision/id-collision2.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -42,4 +42,3 @@
--- a/gplugin/tests/load-on-query-fail/load-on-query-fail.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/load-on-query-fail/load-on-query-fail.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -44,4 +44,3 @@
--- a/gplugin/tests/load-on-query-pass/load-on-query-pass.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/load-on-query-pass/load-on-query-pass.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -42,4 +42,3 @@
--- a/gplugin/tests/meson.build Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/meson.build Tue Feb 25 22:30:11 2020 -0600
@@ -28,6 +28,10 @@
dependencies : [gplugin_dep, GLIB, GOBJECT])
+e = executable('test-loader-registration', 'test-loader-registration.c', + dependencies : [gplugin_dep, GLIB, GOBJECT]) +test('Loader Registration', e) e = executable('test-option-group', 'test-option-group.c',
dependencies : [gplugin_dep, GLIB, GOBJECT])
--- a/gplugin/tests/plugins/basic-plugin.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/plugins/basic-plugin.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -54,4 +54,3 @@
--- a/gplugin/tests/plugins/broken-dependent-plugin.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/plugins/broken-dependent-plugin.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -47,4 +47,3 @@
--- a/gplugin/tests/plugins/dependent-plugin.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/plugins/dependent-plugin.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -48,4 +48,3 @@
--- a/gplugin/tests/plugins/load-exception.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/plugins/load-exception.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -39,4 +39,3 @@
--- a/gplugin/tests/plugins/load-failed.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/plugins/load-failed.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -40,4 +40,3 @@
--- a/gplugin/tests/plugins/unload-failed.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/plugins/unload-failed.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -40,4 +40,3 @@
--- a/gplugin/tests/test-bind-local.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/test-bind-local.c Tue Feb 25 22:30:11 2020 -0600
@@ -27,7 +27,7 @@
*****************************************************************************/
/* This test kind of sucks because theres no way for us to lookup whether or
- * not a module handle has had it's symbols bound locally. Therefore, right
+ * not a module handle has had its symbols bound locally. Therefore, right * now we have to settle to see if it was loaded correctly.
--- a/gplugin/tests/test-id-collision.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/test-id-collision.c Tue Feb 25 22:30:11 2020 -0600
@@ -39,7 +39,7 @@
g_assert_cmpuint(g_slist_length(plugins), ==, 2);
- gplugin_manager_free_plugin_list(plugins);
+ g_slist_free_full(plugins, g_object_unref); /******************************************************************************
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin/tests/test-loader-registration.c Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,179 @@
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. +/* it's getting dirty in here... */ +#define GPLUGIN_COMPILATION +#include "../gplugin-private.h" +#undef GPLUGIN_COMPILATION +/****************************************************************************** + * GObject Implementation + *****************************************************************************/ +#define TEST_GPLUGIN_TYPE_LOADER (test_gplugin_loader_get_type()) +G_DECLARE_FINAL_TYPE(TestGPluginLoader, test_gplugin_loader, TEST_GPLUGIN, LOADER, GPluginLoader) +struct _TestGPluginLoader { +test_gplugin_loader_supported_extensions(G_GNUC_UNUSED GPluginLoader *loader) { +test_gplugin_loader_query(G_GNUC_UNUSED GPluginLoader *loader, + G_GNUC_UNUSED const gchar *filename, + G_GNUC_UNUSED GError **error) +test_gplugin_loader_load(G_GNUC_UNUSED GPluginLoader *loader, + G_GNUC_UNUSED GPluginPlugin *plugin, + G_GNUC_UNUSED GError **error) +test_gplugin_loader_unload(G_GNUC_UNUSED GPluginLoader *loader, + G_GNUC_UNUSED GPluginPlugin *plugin, + G_GNUC_UNUSED GError **error) +G_DEFINE_TYPE(TestGPluginLoader, test_gplugin_loader, GPLUGIN_TYPE_LOADER) +test_gplugin_loader_init(TestGPluginLoader *loader) { +test_gplugin_loader_class_init(TestGPluginLoaderClass *klass) { + GPluginLoaderClass *loader_class = GPLUGIN_LOADER_CLASS(klass); + loader_class->supported_extensions = + test_gplugin_loader_supported_extensions; + loader_class->query = test_gplugin_loader_query; + loader_class->load = test_gplugin_loader_load; + loader_class->unload = test_gplugin_loader_unload; +/****************************************************************************** + *****************************************************************************/ +test_gplugin_manager_loader_register(void) { + gplugin_manager_private_uninit(); + gplugin_manager_private_init(); + ret = gplugin_manager_register_loader(TEST_GPLUGIN_TYPE_LOADER, &error); + g_assert_no_error(error); +test_gplugin_manager_loader_register_twice(void) { + gplugin_manager_private_uninit(); + gplugin_manager_private_init(); + ret = gplugin_manager_register_loader(TEST_GPLUGIN_TYPE_LOADER, &error); + g_assert_no_error(error); + ret = gplugin_manager_register_loader(TEST_GPLUGIN_TYPE_LOADER, &error); + g_assert_error(error, GPLUGIN_DOMAIN, 0); +test_gplugin_manager_loader_unregister(void) { + gplugin_manager_private_uninit(); + gplugin_manager_private_init(); + ret = gplugin_manager_register_loader(TEST_GPLUGIN_TYPE_LOADER, &error); + g_assert_no_error(error); + ret = gplugin_manager_unregister_loader(TEST_GPLUGIN_TYPE_LOADER, &error); + g_assert_no_error(error); +test_gplugin_manager_loader_unregister_twice(void) { + gplugin_manager_private_uninit(); + gplugin_manager_private_init(); + ret = gplugin_manager_register_loader(TEST_GPLUGIN_TYPE_LOADER, &error); + g_assert_no_error(error); + ret = gplugin_manager_unregister_loader(TEST_GPLUGIN_TYPE_LOADER, &error); + g_assert_no_error(error); + ret = gplugin_manager_unregister_loader(TEST_GPLUGIN_TYPE_LOADER, &error); + g_assert_error(error, GPLUGIN_DOMAIN, 0); +/****************************************************************************** + *****************************************************************************/ +main(gint argc, gchar **argv) { + g_test_init(&argc, &argv, NULL); + g_test_add_func("/manager/loader/register", + test_gplugin_manager_loader_register); + g_test_add_func("/manager/loader/register-twice", + test_gplugin_manager_loader_register_twice); + g_test_add_func("/manager/loader/unregister", + test_gplugin_manager_loader_unregister); + g_test_add_func("/manager/loader/unregister-twice", + test_gplugin_manager_loader_unregister_twice); --- a/gplugin/tests/test-plugin-info.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/test-plugin-info.c Tue Feb 25 22:30:11 2020 -0600
@@ -76,10 +76,10 @@
test_gplugin_plugin_info_construction(void) {
GPluginPluginInfo *info = NULL;
- gchar *id = NULL, *name = NULL, *version = NULL;
+ gchar *id = NULL, *name = NULL, *version = NULL, *icon_name = NULL; gchar *license_id = NULL, *license_text = NULL, *license_url = NULL;
- gchar *icon = NULL, *summary = NULL, *description = NULL, *category = NULL;
- gchar *help = NULL, *website = NULL;
+ gchar *summary = NULL, *description = NULL, *category = NULL; gchar **authors = NULL, **dependencies = NULL;
gboolean internal = FALSE, load_on_query = FALSE;
@@ -98,12 +98,11 @@
"license-id", "license-id",
"license-text", "license-text",
"license-url", "license-url",
+ "icon-name", "icon-name", "description", "description",
"dependencies", r_dependencies,
@@ -123,12 +122,11 @@
"license-id", &license_id,
"license-text", &license_text,
"license-url", &license_url,
+ "icon-name", &icon_name, "description", &description,
"dependencies", &dependencies,
@@ -143,13 +141,12 @@
test_string(license_id, "license-id");
test_string(license_text, "license-text");
test_string(license_url, "license-url");
- test_string(icon, "icon");
+ test_string(icon_name, "icon-name"); test_string(summary, "summary");
test_string(description, "description");
test_string(category, "category");
test_stringv(authors, r_authors,
(TestStringVFunc)gplugin_plugin_info_get_authors, info);
- test_string(help, "help");
test_string(website, "website");
test_stringv(dependencies, r_dependencies,
(TestStringVFunc)gplugin_plugin_info_get_dependencies, info);
@@ -182,10 +179,10 @@
test_gplugin_plugin_info_new_full(void) {
GPluginPluginInfo *info = NULL;
- gchar *id = NULL, *name = NULL, *version = NULL;
+ gchar *id = NULL, *name = NULL, *version = NULL, *icon_name = NULL; gchar *license_id = NULL, *license_text = NULL, *license_url = NULL;
- gchar *icon = NULL, *summary = NULL, *description = NULL, *category = NULL;
- gchar *website = NULL, *help = NULL;
+ gchar *summary = NULL, *description = NULL, *category = NULL; gchar **authors = NULL, **dependencies = NULL;
gboolean internal = FALSE, load_on_query = FALSE;
@@ -203,12 +200,11 @@
"license-id", "license-id",
"license-text", "license-text",
"license-url", "license-url",
+ "icon-name", "icon-name", "description", "description",
"dependencies", r_dependencies,
@@ -228,12 +224,11 @@
"license-id", &license_id,
"license-text", &license_text,
"license-url", &license_url,
+ "icon-name", &icon_name, "description", &description,
"dependencies", &dependencies,
@@ -248,13 +243,12 @@
test_string(license_id, "license-id");
test_string(license_text, "license-text");
test_string(license_url, "license-url");
- test_string(icon, "icon");
+ test_string(icon_name, "icon-name"); test_string(summary, "summary");
test_string(description, "description");
test_string(category, "category");
test_stringv(authors, r_authors,
(TestStringVFunc)gplugin_plugin_info_get_authors, info);
- test_string(help, "help");
test_string(website, "website");
test_stringv(dependencies, r_dependencies,
(TestStringVFunc)gplugin_plugin_info_get_dependencies, info);
--- a/gplugin/tests/test-version-compare.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/test-version-compare.c Tue Feb 25 22:30:11 2020 -0600
@@ -28,7 +28,7 @@
test_gplugin_version_null__null(void) {
- g_test_trap_subprocess("/version-check/null__null/subprocess", 0, 0);
+ g_test_trap_subprocess("/version-compare/null__null/subprocess", 0, 0); g_test_trap_assert_failed();
g_test_trap_assert_stderr("*gplugin_version_compare*assertion*");
@@ -41,7 +41,7 @@
test_gplugin_version_null__1_2_3(void) {
- g_test_trap_subprocess("/version-check/null__1_2_3/subprocess", 0, 0);
+ g_test_trap_subprocess("/version-compare/null__1_2_3/subprocess", 0, 0); g_test_trap_assert_failed();
g_test_trap_assert_stderr("*gplugin_version_compare*assertion*");
@@ -54,7 +54,7 @@
test_gplugin_version_1_2_3__null(void) {
- g_test_trap_subprocess("/version-check/1_2_3__null/subprocess", 0, 0);
+ g_test_trap_subprocess("/version-compare/1_2_3__null/subprocess", 0, 0); g_test_trap_assert_failed();
g_test_trap_assert_stderr("*gplugin_version_compare*assertion*");
@@ -73,7 +73,7 @@
test_gplugin_version_abc__1_2_3(void) {
- g_test_trap_subprocess("/version-check/abc__1_2_3/subprocess", 0, 0);
+ g_test_trap_subprocess("/version-compare/abc__1_2_3/subprocess", 0, 0); g_test_trap_assert_failed();
g_test_trap_assert_stderr("*assertion*");
@@ -92,7 +92,7 @@
test_gplugin_version_1_2_3__abc(void) {
- g_test_trap_subprocess("/version-check/1_2_3__abc/subprocess", 0, 0);
+ g_test_trap_subprocess("/version-compare/1_2_3__abc/subprocess", 0, 0); g_test_trap_assert_failed();
g_test_trap_assert_stderr("*assertion*");
@@ -101,7 +101,7 @@
/* major version tests */
test_gplugin_version_1_0_0__0_0_0(void) {
- g_assert_cmpint(gplugin_version_compare("1.0.0", "0.0.0", NULL), ==, -1);
+ g_assert_cmpint(gplugin_version_compare("1.0.0", "0.0.0", NULL), >, 0); @@ -111,13 +111,13 @@
test_gplugin_version_0_0_0__1_0_0(void) {
- g_assert_cmpint(gplugin_version_compare("0.0.0", "1.0.0", NULL), ==, 1);
+ g_assert_cmpint(gplugin_version_compare("0.0.0", "1.0.0", NULL), <, 0); /* minor version tests */
test_gplugin_version_0_1_0__0_0_0(void) {
- g_assert_cmpint(gplugin_version_compare("0.1.0", "0.0.0", NULL), ==, -1);
+ g_assert_cmpint(gplugin_version_compare("0.1.0", "0.0.0", NULL), >, 0); @@ -127,28 +127,28 @@
test_gplugin_version_0_0_0__0_1_0(void) {
- g_assert_cmpint(gplugin_version_compare("0.0.0", "0.1.0", NULL), ==, 1);
+ g_assert_cmpint(gplugin_version_compare("0.0.0", "0.1.0", NULL), <, 0); /* micro version tests */
test_gplugin_version_0_0_1__0_0_0(void) {
- g_assert_cmpint(gplugin_version_compare("0.1.0", "0.0.0", NULL), ==, -1);
+ g_assert_cmpint(gplugin_version_compare("0.0.1", "0.0.0", NULL), >, 0); test_gplugin_version_0_0_1__0_0_1(void) {
- g_assert_cmpint(gplugin_version_compare("0.1.0", "0.1.0", NULL), ==, 0);
+ g_assert_cmpint(gplugin_version_compare("0.0.1", "0.0.1", NULL), ==, 0); test_gplugin_version_0_0_0__0_0_1(void) {
- g_assert_cmpint(gplugin_version_compare("0.0.0", "0.1.0", NULL), ==, 1);
+ g_assert_cmpint(gplugin_version_compare("0.0.0", "0.0.1", NULL), <, 0); static void test_gplugin_version_1_0__0_1(void) {
- g_assert_cmpint(gplugin_version_compare("1.0", "0.1", NULL), ==, -1);
+ g_assert_cmpint(gplugin_version_compare("1.0", "0.1", NULL), >, 0); static void test_gplugin_version_1_0__1_0(void) {
@@ -156,12 +156,12 @@
static void test_gplugin_version_0_1__1_0(void) {
- g_assert_cmpint(gplugin_version_compare("0.1", "1.0", NULL), ==, 1);
+ g_assert_cmpint(gplugin_version_compare("0.1", "1.0", NULL), <, 0); static void test_gplugin_version_1__0(void) {
- g_assert_cmpint(gplugin_version_compare("1", "0", NULL), ==, -1);
+ g_assert_cmpint(gplugin_version_compare("1", "0", NULL), >, 0); static void test_gplugin_version_1__1(void) {
@@ -169,7 +169,7 @@
static void test_gplugin_version_0__1(void) {
- g_assert_cmpint(gplugin_version_compare("0", "1", NULL), ==, 1);
+ g_assert_cmpint(gplugin_version_compare("0", "1", NULL), <, 0); /******************************************************************************
@@ -182,65 +182,65 @@
- g_test_add_func("/version-check/null__null",
+ g_test_add_func("/version-compare/null__null", test_gplugin_version_null__null);
- g_test_add_func("/version-check/null__1_2_3",
+ g_test_add_func("/version-compare/null__1_2_3", test_gplugin_version_null__1_2_3);
- g_test_add_func("/version-check/1_2_3__null",
+ g_test_add_func("/version-compare/1_2_3__null", test_gplugin_version_1_2_3__null);
- g_test_add_func("/version-check/abc__1_2_3",
+ g_test_add_func("/version-compare/abc__1_2_3", test_gplugin_version_abc__1_2_3);
- g_test_add_func("/version-check/1_2_3__abc",
+ g_test_add_func("/version-compare/1_2_3__abc", test_gplugin_version_1_2_3__abc);
- g_test_add_func("/version-check/null__null/subprocess",
+ g_test_add_func("/version-compare/null__null/subprocess", test_gplugin_version_null__null_subprocess);
- g_test_add_func("/version-check/null__1_2_3/subprocess",
+ g_test_add_func("/version-compare/null__1_2_3/subprocess", test_gplugin_version_null__1_2_3_subprocess);
- g_test_add_func("/version-check/1_2_3__null/subprocess",
+ g_test_add_func("/version-compare/1_2_3__null/subprocess", test_gplugin_version_1_2_3__null_subprocess);
- g_test_add_func("/version-check/abc__1_2_3/subprocess",
+ g_test_add_func("/version-compare/abc__1_2_3/subprocess", test_gplugin_version_abc__1_2_3_subprocess);
- g_test_add_func("/version-check/1_2_3__abc/subprocess",
+ g_test_add_func("/version-compare/1_2_3__abc/subprocess", test_gplugin_version_1_2_3__abc_subprocess);
- g_test_add_func("/version-check/1_0_0__0_0_0",
+ g_test_add_func("/version-compare/1_0_0__0_0_0", test_gplugin_version_1_0_0__0_0_0);
- g_test_add_func("/version-check/1_0_0__1_0_0",
+ g_test_add_func("/version-compare/1_0_0__1_0_0", test_gplugin_version_1_0_0__1_0_0);
- g_test_add_func("/version-check/0_0_0__1_0_0",
+ g_test_add_func("/version-compare/0_0_0__1_0_0", test_gplugin_version_0_0_0__1_0_0);
- g_test_add_func("/version-check/0_1_0__0_0_0",
+ g_test_add_func("/version-compare/0_1_0__0_0_0", test_gplugin_version_0_1_0__0_0_0);
- g_test_add_func("/version-check/0_1_0__0_1_0",
+ g_test_add_func("/version-compare/0_1_0__0_1_0", test_gplugin_version_0_1_0__0_1_0);
- g_test_add_func("/version-check/0_0_0__0_1_0",
+ g_test_add_func("/version-compare/0_0_0__0_1_0", test_gplugin_version_0_0_0__0_1_0);
- g_test_add_func("/version-check/0_0_1__0_0_0",
+ g_test_add_func("/version-compare/0_0_1__0_0_0", test_gplugin_version_0_0_1__0_0_0);
- g_test_add_func("/version-check/0_0_1__0_0_1",
+ g_test_add_func("/version-compare/0_0_1__0_0_1", test_gplugin_version_0_0_1__0_0_1);
- g_test_add_func("/version-check/0_0_0__0_0_1",
+ g_test_add_func("/version-compare/0_0_0__0_0_1", test_gplugin_version_0_0_0__0_0_1);
- g_test_add_func("/version-check/1_0__0_1",
+ g_test_add_func("/version-compare/1_0__0_1", test_gplugin_version_1_0__0_1);
- g_test_add_func("/version-check/1_0__1_0",
+ g_test_add_func("/version-compare/1_0__1_0", test_gplugin_version_1_0__1_0);
- g_test_add_func("/version-check/0_1__1_0",
+ g_test_add_func("/version-compare/0_1__1_0", test_gplugin_version_0_1__1_0);
- g_test_add_func("/version-check/1__0",
+ g_test_add_func("/version-compare/1__0", test_gplugin_version_1__0);
- g_test_add_func("/version-check/1__1",
+ g_test_add_func("/version-compare/1__1", test_gplugin_version_1__1);
- g_test_add_func("/version-check/0__1",
+ g_test_add_func("/version-compare/0__1", test_gplugin_version_0__1);
--- a/gplugin/tests/unresolved-symbol/unresolved-symbol.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/unresolved-symbol/unresolved-symbol.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2016 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -40,4 +40,3 @@
--- a/gplugin/tests/versioned-dependencies/bar.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/versioned-dependencies/bar.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -42,4 +42,3 @@
--- a/gplugin/tests/versioned-dependencies/baz.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/versioned-dependencies/baz.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -42,4 +42,3 @@
--- a/gplugin/tests/versioned-dependencies/exact1.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/versioned-dependencies/exact1.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -42,4 +42,3 @@
--- a/gplugin/tests/versioned-dependencies/exact2.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/versioned-dependencies/exact2.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -42,4 +42,3 @@
--- a/gplugin/tests/versioned-dependencies/fez.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/versioned-dependencies/fez.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -42,4 +42,3 @@
--- a/gplugin/tests/versioned-dependencies/greater-equal.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/versioned-dependencies/greater-equal.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -42,4 +42,3 @@
--- a/gplugin/tests/versioned-dependencies/greater.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/versioned-dependencies/greater.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -42,4 +42,3 @@
--- a/gplugin/tests/versioned-dependencies/less-equal.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/versioned-dependencies/less-equal.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -42,4 +42,3 @@
--- a/gplugin/tests/versioned-dependencies/less.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/versioned-dependencies/less.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -42,4 +42,3 @@
--- a/gplugin/tests/versioned-dependencies/no-version.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/versioned-dependencies/no-version.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -40,4 +40,3 @@
--- a/gplugin/tests/versioned-dependencies/super-dependent.c Sat Feb 15 21:14:07 2020 -0600
+++ b/gplugin/tests/versioned-dependencies/super-dependent.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -57,4 +57,3 @@
--- a/lua/gplugin-lua-core.c Sat Feb 15 21:14:07 2020 -0600
+++ b/lua/gplugin-lua-core.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -51,15 +51,11 @@
-gplugin_load(GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+gplugin_load(GPluginNativePlugin *plugin, GError **error) { gplugin_lua_loader_register(plugin);
gplugin_lua_plugin_register(plugin);
- gplugin_manager_register_loader(GPLUGIN_LUA_TYPE_LOADER);
+ return gplugin_manager_register_loader(GPLUGIN_LUA_TYPE_LOADER, error); @@ -75,4 +71,3 @@
--- a/lua/gplugin-lua-loader.c Sat Feb 15 21:14:07 2020 -0600
+++ b/lua/gplugin-lua-loader.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -19,7 +19,7 @@
#include "gplugin-lua-plugin.h"
+#include <glib/gi18n-lib.h> @@ -81,7 +81,7 @@
* GPluginLoaderInterface API
*****************************************************************************/
-gplugin_lua_loader_class_supported_extensions(G_GNUC_UNUSED GPluginLoaderClass *klass) {
+gplugin_lua_loader_supported_extensions(G_GNUC_UNUSED GPluginLoader *l) { return g_slist_append(NULL, "lua");
@@ -177,7 +177,7 @@
GPluginLoaderClass *loader_class = GPLUGIN_LOADER_CLASS(klass);
loader_class->supported_extensions =
- gplugin_lua_loader_class_supported_extensions;
+ gplugin_lua_loader_supported_extensions; loader_class->query = gplugin_lua_loader_query;
loader_class->load = gplugin_lua_loader_load;
loader_class->unload = gplugin_lua_loader_unload;
--- a/lua/gplugin-lua-loader.h Sat Feb 15 21:14:07 2020 -0600
+++ b/lua/gplugin-lua-loader.h Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -31,4 +31,3 @@
#endif /* GPLUGIN_LUA_LOADER_H */
--- a/lua/gplugin-lua-plugin.c Sat Feb 15 21:14:07 2020 -0600
+++ b/lua/gplugin-lua-plugin.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
--- a/lua/gplugin-lua-plugin.h Sat Feb 15 21:14:07 2020 -0600
+++ b/lua/gplugin-lua-plugin.h Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -35,4 +35,3 @@
#endif /* GPLUGIN_LUA_PLUGIN_H */
--- a/lua/gplugin-lua-test-lgi.c Sat Feb 15 21:14:07 2020 -0600
+++ b/lua/gplugin-lua-test-lgi.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -63,4 +63,3 @@
--- a/lua/meson.build Sat Feb 15 21:14:07 2020 -0600
+++ b/lua/meson.build Tue Feb 25 22:30:11 2020 -0600
@@ -14,17 +14,30 @@
- _LUAS = [['lua', '>=5.1.0'],
- ['lua-5.2', '>=5.2.0']]
+ # These are ordered from most to least preferred, which would normally + # be from the highest to lowest version. + ['lua-5.3', '>=5.3.0'], + ['lua-5.2', '>=5.2.0'], + ['lua-5.1', '>=5.1.0'],
- LUA = dependency(_LUA[0], version : _LUA[1], required : false)
- LUA_FOUND = LUA.found()
+ LUA = dependency(_LUA[0], version : _LUA[1], required : false) + # Compile and run our lua-lgi test program + lua_lgi_test = compiler.run(files('gplugin-lua-test-lgi.c'), + name : 'lua "lgi" module') + if lua_lgi_test.compiled() and lua_lgi_test.returncode() == 0 @@ -32,14 +45,6 @@
error('No usable Lua library was found')
- # Compile and run our lua-lgi test program
- lua_lgi_test = compiler.run(files('gplugin-lua-test-lgi.c'),
- name : 'lua "lgi" module')
- if not lua_lgi_test.compiled() or lua_lgi_test.returncode() != 0
- error('Failed to find the "lgi" lua module')
shared_library('gplugin-lua',
--- a/lua/tests/plugins/basic.lua Sat Feb 15 21:14:07 2020 -0600
+++ b/lua/tests/plugins/basic.lua Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -40,5 +40,3 @@
function gplugin_unload(plugin)
--- a/lua/tests/plugins/dependent.lua Sat Feb 15 21:14:07 2020 -0600
+++ b/lua/tests/plugins/dependent.lua Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -32,4 +32,3 @@
function gplugin_unload(plugin)
--- a/lua/tests/plugins/load-exception.lua Sat Feb 15 21:14:07 2020 -0600
+++ b/lua/tests/plugins/load-exception.lua Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -31,4 +31,3 @@
function gplugin_unload(plugin)
--- a/lua/tests/plugins/load-failed.lua Sat Feb 15 21:14:07 2020 -0600
+++ b/lua/tests/plugins/load-failed.lua Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -31,4 +31,3 @@
function gplugin_unload(plugin)
--- a/lua/tests/plugins/unload-failed.lua Sat Feb 15 21:14:07 2020 -0600
+++ b/lua/tests/plugins/unload-failed.lua Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -31,4 +31,3 @@
function gplugin_unload(plugin)
--- a/lua/tests/test-lua-loader.c Sat Feb 15 21:14:07 2020 -0600
+++ b/lua/tests/test-lua-loader.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -28,4 +28,3 @@
--- a/meson.build Sat Feb 15 21:14:07 2020 -0600
+++ b/meson.build Tue Feb 25 22:30:11 2020 -0600
@@ -74,7 +74,6 @@
toplevel_inc = include_directories('.')
###############################################################################
###############################################################################
@@ -101,4 +100,3 @@
install_data('ChangeLog', 'INSTALL.md', 'README.md', 'HACKING.md',
install_dir : join_paths(get_option('datadir'), 'doc', 'gplugin'))
--- a/meson_options.txt Sat Feb 15 21:14:07 2020 -0600
+++ b/meson_options.txt Tue Feb 25 22:30:11 2020 -0600
@@ -39,12 +39,12 @@
- type : 'boolean', value : false,
+ type : 'boolean', value : true, description : 'Whether or not to build the Perl plugin loader'
type : 'boolean', value : true,
description : 'Whether or not to build the Python 3.x plugin loader'
--- a/packaging/debian/control Sat Feb 15 21:14:07 2020 -0600
+++ b/packaging/debian/control Tue Feb 25 22:30:11 2020 -0600
@@ -51,6 +51,7 @@
Depends: ${misc:Depends}, ${shlibs:Depends},
Description: metapackage for all gplugin loaders
GPlugin is a GObject based library that implements a reusable plugin system
@@ -115,7 +116,7 @@
This package allows GPlugin to load plugins written in the Lua programming
-Package: libgplugin-python
+Package: libgplugin-python3 Depends: ${misc:Depends}, ${shlibs:Depends}, python3, python3-gi,
libgplugin0, gir1.2-gplugin-0.0
@@ -124,6 +125,18 @@
which supports loading plugins in other languages via loaders. It relies
heavily on GObjectIntrospection to expose its API to the other languages.
- This package allows GPlugin to load plugin written in the Python programming
+ This package allows GPlugin to load plugins written in the Python programming +Package: libgplugin-perl +Depends: ${misc:Depends}, ${shlibs:Depends}, perl, libglib-perl, + libglib-object-introspection-perl, libgplugin0, gir1.2-gplugin-0.0 +Description: GPlugin Perl Loader + GPlugin is a GObject based library that implements a reusable plugin system + which supports loading plugins in other languages via loaders. It relies + heavily on GObjectIntrospection to expose its API to the other languages. + This package allows GPlugin to load plugins written in the Perl programming --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/packaging/debian/libgplugin-perl.install Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,1 @@
+debian/tmp/usr/lib/*/gplugin/gplugin-perl.so --- a/packaging/debian/libgplugin-python.install Sat Feb 15 21:14:07 2020 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-debian/tmp/usr/lib/*/gplugin/gplugin-python.so
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/packaging/debian/libgplugin-python3.install Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,1 @@
+debian/tmp/usr/lib/*/gplugin/gplugin-python3.so --- a/packaging/gplugin.spec.in Sat Feb 15 21:14:07 2020 -0600
+++ b/packaging/gplugin.spec.in Tue Feb 25 22:30:11 2020 -0600
@@ -23,7 +23,14 @@
BuildRequires: python3-devel
BuildRequires: python3-gobject
-BuildRequires: /usr/lib64/pkgconfig/pygobject-3.0.pc
+BuildRequires: perl-Glib +BuildRequires: perl-Glib-Object-Introspection +BuildRequires: perl-devel +BuildRequires: perl-ExtUtils-Config Summary: A GObject based library that implements a reusable plugin system
@@ -54,6 +61,10 @@
Summary: A GObject based library that implements a reusable plugin system
Group: Development/Libraries
+Summary: A GObject based library that implements a reusable plugin system +Group: Development/Libraries Summary: A GObject based library that implements a reusable plugin system
Group: Development/Libraries
@@ -68,31 +79,16 @@
that supports loading plugins in other languages via loaders. GPlugin also
implements dependencies among the plugins.
-It was started due to the infamous "Plugin Problem" for Guifications 3, which
-was that I needed plugins that could depend on each other, be able to be
-written in other languages, have plugins that are loaded before the main load
-phase, and allow plugins to register types into the GObject type system.
%description -n libgplugin0
GPlugin is a GObject based library that implements a reusable plugin system
that supports loading plugins in other languages via loaders. GPlugin also
implements dependencies among the plugins.
-It was started due to the infamous "Plugin Problem" for Guifications 3, which
-was that I needed plugins that could depend on each other, be able to be
-written in other languages, have plugins that are loaded before the main load
-phase, and allow plugins to register types into the GObject type system.
GPlugin is a GObject based library that implements a reusable plugin system
that supports loading plugins in other languages via loaders. GPlugin also
implements dependencies among the plugins.
-It was started due to the infamous "Plugin Problem" for Guifications 3, which
-was that I needed plugins that could depend on each other, be able to be
-written in other languages, have plugins that are loaded before the main load
-phase, and allow plugins to register types into the GObject type system.
This package contains all necessary include files and libraries needed
to develop applications that require these.
@@ -101,11 +97,6 @@
that supports loading plugins in other languages via loaders. GPlugin also
implements dependencies among the plugins.
-It was started due to the infamous "Plugin Problem" for Guifications 3, which
-was that I needed plugins that could depend on each other, be able to be
-written in other languages, have plugins that are loaded before the main load
-phase, and allow plugins to register types into the GObject type system.
This package contains additional GTK3 dependencies for %{name} library.
@@ -113,11 +104,6 @@
that supports loading plugins in other languages via loaders. GPlugin also
implements dependencies among the plugins.
-It was started due to the infamous "Plugin Problem" for Guifications 3, which
-was that I needed plugins that could depend on each other, be able to be
-written in other languages, have plugins that are loaded before the main load
-phase, and allow plugins to register types into the GObject type system.
This package contains all necessary include files and libraries needed
to develop GTK3 applications that require these.
@@ -126,11 +112,6 @@
that supports loading plugins in other languages via loaders. GPlugin also
implements dependencies among the plugins.
-It was started due to the infamous "Plugin Problem" for Guifications 3, which
-was that I needed plugins that could depend on each other, be able to be
-written in other languages, have plugins that are loaded before the main load
-phase, and allow plugins to register types into the GObject type system.
This package contains the vapi bindings allowing GPluginGtk to be used from
@@ -139,23 +120,20 @@
that supports loading plugins in other languages via loaders. GPlugin also
implements dependencies among the plugins.
-It was started due to the infamous "Plugin Problem" for Guifications 3, which
-was that I needed plugins that could depend on each other, be able to be
-written in other languages, have plugins that are loaded before the main load
-phase, and allow plugins to register types into the GObject type system.
+This package contains the Lua Loader for %{name} library. -This package contains the Lua Loader for %{name} library.
+GPlugin is a GObject based library that implements a reusable plugin system +that supports loading plugins in other languages via loaders. GPlugin also +implements dependencies among the plugins. +This package contains Perl loader for %{name} library. GPlugin is a GObject based library that implements a reusable plugin system
that supports loading plugins in other languages via loaders. GPlugin also
implements dependencies among the plugins.
-It was started due to the infamous "Plugin Problem" for Guifications 3, which
-was that I needed plugins that could depend on each other, be able to be
-written in other languages, have plugins that are loaded before the main load
-phase, and allow plugins to register types into the GObject type system.
This package contains Python 3 loader for %{name} library.
@@ -163,18 +141,11 @@
that supports loading plugins in other languages via loaders. GPlugin also
implements dependencies among the plugins.
-It was started due to the infamous "Plugin Problem" for Guifications 3, which
-was that I needed plugins that could depend on each other, be able to be
-written in other languages, have plugins that are loaded before the main load
-phase, and allow plugins to register types into the GObject type system.
This package contains the vapi bindings allowing GPlugin to be used from vala.
CFLAGS="%{optflags}" meson \
ninja -C build %{?_smp_mflags}
@@ -196,17 +167,21 @@
%{_mandir}/man1/gplugin-query.1*
%{_libdir}/libgplugin.so.0.1.0
%doc HACKING.md README.md
%{_datadir}/gir-1.0/GPlugin-0.0.gir
%{_datadir}/gtk-doc/html/gplugin/
%{_includedir}/gplugin-1.0/
@@ -219,6 +194,7 @@
%{_bindir}/gplugin-gtk-viewer
%{_libdir}/libgplugin-gtk.so.0.1.0
%{_mandir}/man1/gplugin-gtk-viewer.1*
@@ -227,6 +203,7 @@
%dir %{_datadir}/glade/catalogs/
%{_datadir}/gir-1.0/GPluginGtk-0.0.gir
%{_datadir}/glade/catalogs/gplugin-gtk.xml
%{_datadir}/gtk-doc/html/gplugin-gtk/
@@ -234,16 +211,30 @@
%{_libdir}/libgplugin-gtk.so
%{_libdir}/libgplugin-gtk.so.0
+%{_datadir}/vala/vapi/gplugin-gtk.vapi +%{_datadir}/vala/vapi/gplugin-gtk.deps %{_libdir}/gplugin/gplugin-lua.so
+%{_libdir}/gplugin/gplugin-perl.so -%{_libdir}/gplugin/gplugin-python.so
+%{_libdir}/gplugin/gplugin-python3.so @@ -252,14 +243,11 @@
%{_datadir}/vala/vapi/gplugin.vapi
%{_datadir}/vala/vapi/gplugin.deps
-%{_datadir}/vala/vapi/gplugin-gtk.vapi
-%{_datadir}/vala/vapi/gplugin-gtk.deps
+* Tue Feb 18 2020 Gary Kramlich <grim@reaperworld.com> +- Updated the python files to reference the new name for gplugin-python3
* Thu Oct 31 2019 Gary Kramlich <grim@reaperworld.com>
- Fixed an include bug in gplugin-gtk
- Fixed building again python3.8
--- a/perl/gplugin-perl-core.c Sat Feb 15 21:14:07 2020 -0600
+++ b/perl/gplugin-perl-core.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -21,6 +21,9 @@
#include "gplugin-perl-loader.h"
#include "gplugin-perl-plugin.h"
+#include <glib/gi18n-lib.h> G_MODULE_EXPORT GPluginPluginInfo *
gplugin_query(GError **error) {
const gchar * const authors[] = {
@@ -52,13 +55,17 @@
gplugin_perl_plugin_register(plugin);
gplugin_perl_loader_register(plugin);
- gplugin_manager_register_loader(GPLUGIN_PERL_TYPE_LOADER);
+ return gplugin_manager_register_loader(GPLUGIN_PERL_TYPE_LOADER, error); gplugin_unload(GPluginNativePlugin *plugin, GError **error) {
+ _("The Perl loader can not be unloaded")
--- a/perl/gplugin-perl-loader.c Sat Feb 15 21:14:07 2020 -0600
+++ b/perl/gplugin-perl-loader.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -16,15 +16,9 @@
#include "gplugin-perl-loader.h"
+#include "gplugin-perl-plugin.h" -/* perl define's _() to something completely different that we don't use. So
- * we undef it so that we can use it for gettext.
+#include <glib/gi18n-lib.h> struct _GPluginPerlLoader {
@@ -32,52 +26,20 @@
G_DEFINE_DYNAMIC_TYPE(GPluginPerlLoader, gplugin_perl_loader, GPLUGIN_TYPE_LOADER);
-/* I can't believe I have to use this variable name... */
static PerlInterpreter *my_perl = NULL;
/******************************************************************************
- * GPluginLoaderInterface API
- *****************************************************************************/
-gplugin_perl_loader_class_supported_extensions(const GPluginLoaderClass *klass) {
- return g_slist_append(NULL, "pl");
-gplugin_perl_loader_query(GPluginLoader *loader,
- const gchar *args[] = { "", filename };
- gchar **argv = (gchar **)args;
- perl_parse(my_perl, NULL, argc, argv, NULL);
- call_argv("gplugin_plugin_query", G_DISCARD | G_NOARGS, argv);
-gplugin_perl_loader_load(GPluginLoader *loader,
-gplugin_perl_loader_unload(GPluginLoader *loader,
-/******************************************************************************
*****************************************************************************/
+extern void boot_DynaLoader(pTHX_ CV* cv); +gplugin_perl_loader_xs_init(pTHX) { + newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, __FILE__); gplugin_perl_loader_init_perl(void) {
@@ -88,17 +50,221 @@
PERL_SET_CONTEXT(my_perl);
- PL_perl_destruct_level = 1;
+ PL_exit_flags |= PERL_EXIT_DESTRUCT_END; gplugin_perl_loader_uninit_perl(void) {
+ PERL_SET_CONTEXT(my_perl);
+static GPluginPluginInfo * +gplugin_perl_loader_call_gplugin_query(PerlInterpreter *interpreter, GError **error) { + GPluginPluginInfo *info = NULL; + PerlInterpreter *old = NULL; + PERL_SET_CONTEXT(interpreter); + ret = call_pv("gplugin_query", G_EVAL | G_NOARGS); + g_set_error_literal(error, GPLUGIN_DOMAIN, 0, + "gplugin_query did not return a GPluginPluginInfo"); + const gchar *errmsg = SvPVutf8_nolen(ERRSV); + g_set_error_literal(error, GPLUGIN_DOMAIN, 0, errmsg); + info = (GPluginPluginInfo *)gperl_get_object(POPs); + /* if we did get a real GPluginPluginInfo ref it because the perl + * code below will take it out of scope and delete it if its + * reference count is zero. + if(GPLUGIN_IS_PLUGIN_INFO(info)) { + g_object_ref(G_OBJECT(info)); +gplugin_perl_loader_call_boolean(PerlInterpreter *interpreter, + const gchar *func, GError **error) + PerlInterpreter *old = NULL; + PERL_SET_CONTEXT(interpreter); + count = call_pv(func, G_EVAL | G_SCALAR); + g_set_error(error, GPLUGIN_DOMAIN, 0, "%s did not return a value", + const gchar *errmsg = SvPVutf8_nolen(err); + g_set_error_literal(error, GPLUGIN_DOMAIN, 0, errmsg); +/****************************************************************************** + * GPluginLoaderInterface API + *****************************************************************************/ +gplugin_perl_loader_supported_extensions(G_GNUC_UNUSED GPluginLoader *l) { + return g_slist_append(NULL, "pl"); +gplugin_perl_loader_query(GPluginLoader *loader, + GPluginPlugin *plugin = NULL; + GPluginPluginInfo *info = NULL; + PerlInterpreter *interpreter = NULL; + const gchar *args[] = { "", filename }; + gchar **argv = (gchar **)args; + gint argc = 2, ret = 0; + interpreter = perl_alloc(); + PERL_SET_CONTEXT(interpreter); + PL_perl_destruct_level = 1; + perl_construct(interpreter); + ret = perl_parse(interpreter, gplugin_perl_loader_xs_init, argc, argv, NULL); + const gchar *errmsg = "unknown error"; + errmsg = SvPVutf8_nolen(ERRSV); + g_set_error_literal(error, GPLUGIN_DOMAIN, 0, errmsg); + perl_destruct(interpreter); + perl_free(interpreter); + ret = perl_run(interpreter); + const gchar *errmsg = "unknown error"; + errmsg = SvPVutf8_nolen(ERRSV); + g_set_error_literal(error, GPLUGIN_DOMAIN, 0, errmsg); + perl_destruct(interpreter); + perl_free(interpreter); + info = gplugin_perl_loader_call_gplugin_query(interpreter, error); + if(!GPLUGIN_IS_PLUGIN_INFO(info)) { + g_set_error_literal(error, GPLUGIN_DOMAIN, 0, "failed to query"); + GPLUGIN_PERL_TYPE_PLUGIN, + "interpreter", interpreter, + "loader", g_object_ref(loader), +gplugin_perl_loader_load(G_GNUC_UNUSED GPluginLoader *loader, + GPluginPerlPlugin *pplugin = GPLUGIN_PERL_PLUGIN(plugin); + PerlInterpreter *interpreter = NULL; + interpreter = gplugin_perl_plugin_get_interpreter(pplugin); + return gplugin_perl_loader_call_boolean(interpreter, "gplugin_load", +gplugin_perl_loader_unload(G_GNUC_UNUSED GPluginLoader *loader, + GPluginPerlPlugin *pplugin = GPLUGIN_PERL_PLUGIN(plugin); + PerlInterpreter *interpreter = NULL; + interpreter = gplugin_perl_plugin_get_interpreter(pplugin); + return gplugin_perl_loader_call_boolean(interpreter, "gplugin_unload", /******************************************************************************
@@ -113,7 +279,7 @@
GPluginLoaderClass *loader_class = GPLUGIN_LOADER_CLASS(klass);
loader_class->supported_extensions =
- gplugin_perl_loader_class_supported_extensions;
+ gplugin_perl_loader_supported_extensions; loader_class->query = gplugin_perl_loader_query;
loader_class->load = gplugin_perl_loader_load;
loader_class->unload = gplugin_perl_loader_unload;
--- a/perl/gplugin-perl-loader.h Sat Feb 15 21:14:07 2020 -0600
+++ b/perl/gplugin-perl-loader.h Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -31,4 +31,3 @@
#endif /* GPLUGIN_PERL_PLUGIN_LOADER_H */
--- a/perl/gplugin-perl-plugin.c Sat Feb 15 21:14:07 2020 -0600
+++ b/perl/gplugin-perl-plugin.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -20,12 +20,6 @@
-/* perl define's _() to something completely different that we don't use. So
- * we undef it so that we can use it for gettext.
/******************************************************************************
*****************************************************************************/
--- a/perl/gplugin-perl-plugin.h Sat Feb 15 21:14:07 2020 -0600
+++ b/perl/gplugin-perl-plugin.h Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -21,8 +21,11 @@
#include <gplugin-native.h>
+#define PERL_NO_GET_CONTEXT +/* perl define's _() to something completely different that we don't use. So + * we undef it so that we can use it for gettext. --- a/perl/meson.build Sat Feb 15 21:14:07 2020 -0600
+++ b/perl/meson.build Tue Feb 25 22:30:11 2020 -0600
@@ -14,24 +14,35 @@
+ # make sure we have the perl executable, we need it to figure out the PERL = find_program('perl')
- PERL_CFLAGS = run_command(PERL, '-MExtUtils::Embed', '-e', 'ccopts').stdout()
- PERL_LDFLAGS = run_command(PERL, '-MExtUtils::Embed', '-e', 'ldopts').stdout()
- message('PERL_CFLAGS ' + PERL_CFLAGS)
- message('PERL_LDFLAGS ' + PERL_LDFLAGS)
+ # make sure we have the gobject introspection perl module. + '-e use Glib::Object::Introspection;', - PERL_CFLAGS = PERL_CFLAGS.split()
- PERL_LDFLAGS = PERL_LDFLAGS.split()
+ perl_dep = declare_dependency( + compile_args : run_command(PERL, '-MExtUtils::Embed', '-e', 'ccopts', check : true).stdout().split(), + link_args : run_command(PERL, '-MExtUtils::Embed', '-e', 'ldopts', check : true).stdout().split(), + glib_perl_dep = declare_dependency( + compile_args : run_command(PERL, '-MConfig', '-e', 'print "-I$Config{vendorarch}/Glib/Install"', check : true).stdout().split(), + link_args : run_command(PERL, '-MConfig', '-e', 'print "$Config{vendorarch}/auto/Glib/Glib.so"', check : true).stdout().split(), shared_library('gplugin-perl',
- link_args : PERL_LDFLAGS,
- dependencies : [gplugin_dep],
+ dependencies : [GMODULE, gplugin_dep, perl_dep, glib_perl_dep], install_dir : join_paths(get_option('libdir'), 'gplugin')
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/perl/tests/meson.build Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,12 @@
+e = executable('test-perl-loader', 'test-perl-loader.c', + '-DPERL_LOADER_DIR="@0@"'.format(join_paths(meson.current_build_dir(), '..')), + '-DPERL_PLUGIN_DIR="@0@/plugins"'.format(meson.current_source_dir()), + link_with : gplugin_loader_tests, + dependencies : [GLIB, GOBJECT, gplugin_dep, perl_dep]) --- a/perl/tests/plugins/basic.pl Sat Feb 15 21:14:07 2020 -0600
+++ b/perl/tests/plugins/basic.pl Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,4 @@
-# Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+# Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> # This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -20,30 +19,25 @@
Glib::Object::Introspection->setup(basename => "GPlugin", version => "0.0", package=> "GPlugin");
-sub gplugin_plugin_query() {
return GPlugin::PluginInfo->new(
- id => "gplugin-perl/basic-plugin",
- abi_version => 0x01000001,
+ id => "gplugin/perl-basic-plugin", + abi_version => 0x01020304, - authors => ("Gary Kramlich <grim\@reaperworld.com>"),
+ authors => ("author1"), - license_id => "license id",
+ license_id => "license", description => "description",
-sub gplugin_plugin_load() {
-sub gplugin_plugin_unload() {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/perl/tests/plugins/dependent.pl Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,35 @@
+# Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, see <http://www.gnu.org/licenses/>. +use Glib::Object::Introspection; +Glib::Object::Introspection->setup(basename => "GPlugin", version => "0.0", package=> "GPlugin"); + return GPlugin::PluginInfo->new( + id => "gplugin/perl-dependent-plugin", + dependencies => ['dependency1', 'dependency2'], --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/perl/tests/plugins/load-exception.pl Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,36 @@
+# Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, see <http://www.gnu.org/licenses/>. +use Glib::Object::Introspection; +Glib::Object::Introspection->setup(basename => "GPlugin", version => "0.0", package=> "GPlugin"); + return GPlugin::PluginInfo->new( + id => "gplugin/perl-load-exception", --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/perl/tests/plugins/load-failed.pl Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,34 @@
+# Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, see <http://www.gnu.org/licenses/>. +use Glib::Object::Introspection; +Glib::Object::Introspection->setup(basename => "GPlugin", version => "0.0", package=> "GPlugin"); + return GPlugin::PluginInfo->new( + id => "gplugin/perl-load-failed", --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/perl/tests/plugins/unload-failed.pl Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,34 @@
+# Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, see <http://www.gnu.org/licenses/>. +use Glib::Object::Introspection; +Glib::Object::Introspection->setup(basename => "GPlugin", version => "0.0", package=> "GPlugin"); + return GPlugin::PluginInfo->new( + id => "gplugin/perl-unload-failed", --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/perl/tests/test-perl-loader.c Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,30 @@
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. +#include <gplugin/gplugin-loader-tests.h> +main(gint argc, gchar **argv) { + g_test_init(&argc, &argv, NULL); + gplugin_loader_tests_main(PERL_LOADER_DIR, PERL_PLUGIN_DIR, "perl"); --- a/po/POTFILES Sat Feb 15 21:14:07 2020 -0600
+++ b/po/POTFILES Tue Feb 25 22:30:11 2020 -0600
@@ -24,12 +24,11 @@
perl/gplugin-perl-loader.c
perl/gplugin-perl-plugin.c
-python/gplugin-python-core.c
-python/gplugin-python-loader.c
-python/gplugin-python-plugin.c
-python/gplugin-python-test-pygobject.c
-python/gplugin-python-utils.c
-ruby/gplugin-ruby-protect.c
+python/gplugin-python3-core.c +python/gplugin-python3-loader.c +python/gplugin-python3-plugin.c +python/gplugin-python3-test-pygobject.c +python/gplugin-python3-utils.c --- a/python/gplugin-python-core.c Sat Feb 15 21:14:07 2020 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#include <gplugin-native.h>
-#include <glib/gi18n-lib.h>
-#include "gplugin-python-loader.h"
-#include "gplugin-python-plugin.h"
-G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
- const gchar * const authors[] = {
- "Gary Kramlich <grim@reaperworld.com>",
- return gplugin_plugin_info_new(
- "gplugin/python-loader",
- GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
- "name", "Python Plugin Loader",
- "version", GPLUGIN_VERSION,
- "license-id", "LGPL-2.0-or-later",
- "summary", "A plugin that can load python plugins",
- "description", "This plugin allows the loading of plugins written in "
- "the python programming language.",
- "website", GPLUGIN_WEBSITE,
-G_MODULE_EXPORT gboolean
-gplugin_load(GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
- gplugin_python_plugin_register(plugin);
- gplugin_python_loader_register(plugin);
- gplugin_manager_register_loader(GPLUGIN_PYTHON_TYPE_LOADER);
-G_MODULE_EXPORT gboolean
-gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- _("The Python loader can not be unloaded")
--- a/python/gplugin-python-loader.c Sat Feb 15 21:14:07 2020 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,377 +0,0 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#include "gplugin-python-loader.h"
-#include "gplugin-python-plugin.h"
-#include "gplugin-python-utils.h"
-struct _GPluginPythonLoader {
- PyThreadState *py_thread_state;
-G_DEFINE_DYNAMIC_TYPE(GPluginPythonLoader, gplugin_python_loader, GPLUGIN_TYPE_LOADER);
-/******************************************************************************
- * GPluginLoader Implementation
- *****************************************************************************/
-gplugin_python_loader_class_supported_extensions(G_GNUC_UNUSED GPluginLoaderClass *klass) {
- return g_slist_append(NULL, "py");
-gplugin_python_loader_query(GPluginLoader *loader,
- G_GNUC_UNUSED GError **error)
- GPluginPlugin *plugin = NULL;
- PyObject *pyinfo = NULL, *args = NULL;
- PyObject *module = NULL, *package_list = NULL, *module_dict = NULL;
- PyObject *query = NULL, *load = NULL, *unload = NULL;
- PyGILState_STATE state;
- gchar *module_name = NULL, *dir_name = NULL;
- state = pyg_gil_state_ensure();
- /* create package_list as a tuple to handle 'import foo.bar' */
- package_list = PyTuple_New(0);
- /* now figure out the module name from the filename */
- module_name = gplugin_python_filename_to_module(filename);
- /* grab the dirname since we need it on sys.path to import the module */
- dir_name = g_path_get_dirname(filename);
- gplugin_python_add_module_path(dir_name);
- /* import the module */
- module = PyImport_ImportModuleEx(module_name, NULL, NULL, package_list);
- g_warning(_("Failed to query %s"), filename);
- /* clean some stuff up */
- Py_DECREF(package_list);
- pyg_gil_state_release(state);
- /* clean some stuff up */
- Py_DECREF(package_list);
- /* at this point we have the module, lets find the query, load, and unload
- module_dict = PyModule_GetDict(module);
- query = PyDict_GetItemString(module_dict, "gplugin_query");
- g_warning(_("Failed to find the gplugin_query function in %s"),
- pyg_gil_state_release(state);
- if(!PyCallable_Check(query)) {
- g_warning(_("Found gplugin_query in %s but it is not a "
- pyg_gil_state_release(state);
- load = PyDict_GetItemString(module_dict, "gplugin_load");
- g_warning(_("Failed to find the gplugin_load function in %s"),
- pyg_gil_state_release(state);
- if(!PyCallable_Check(load)) {
- g_warning(_("Found gplugin_load in %s but it is not a "
- pyg_gil_state_release(state);
- unload = PyDict_GetItemString(module_dict, "gplugin_unload");
- g_warning(_("Failed to find the gplugin_unload function in %s"),
- pyg_gil_state_release(state);
- if(!PyCallable_Check(unload)) {
- g_warning(_("Found gplugin_unload in %s but it is not a "
- pyg_gil_state_release(state);
- /* now that we have everything, call the query method and get the plugin's
- pyinfo = PyObject_Call(query, args, NULL);
- info = pygobject_get(pyinfo);
- /* now that we have everything, create the plugin */
- GPLUGIN_PYTHON_TYPE_PLUGIN,
- pyg_gil_state_release(state);
-gplugin_python_loader_load(G_GNUC_UNUSED GPluginLoader *loader,
- PyObject *load = NULL, *pyplugin = NULL, *result = NULL;
- g_object_get(G_OBJECT(plugin), "load-func", &load, NULL);
- pyplugin = pygobject_new(G_OBJECT(plugin));
- result = PyObject_CallFunctionObjArgs(load, pyplugin, NULL);
- if (PyErr_Occurred()) {
- *error = gplugin_python_exception_to_gerror();
- ret = PyObject_IsTrue(result);
- g_set_error_literal(error, GPLUGIN_DOMAIN, 0,
- _("Failed to load plugin"));
-gplugin_python_loader_unload(G_GNUC_UNUSED GPluginLoader *loader,
- PyObject *unload = NULL, *pyplugin = NULL, *result = NULL;
- g_object_get(G_OBJECT(plugin), "unload-func", &unload, NULL);
- pyplugin = pygobject_new(G_OBJECT(plugin));
- result = PyObject_CallFunctionObjArgs(unload, pyplugin, NULL);
- ret = PyObject_IsTrue(result);
- g_set_error_literal(error, GPLUGIN_DOMAIN, 0,
- _("Failed to unload plugin"));
-/******************************************************************************
- *****************************************************************************/
-gplugin_python_loader_init_pygobject(void) {
- pygobject_init(3, 0, 0);
- PyObject *type = NULL, *value = NULL, *tb = NULL, *obj = NULL;
- PyErr_Fetch(&type, &value, &tb);
- obj = PyUnicode_AsUTF8String(value);
- g_warning("Failed to initialize PyGObject : %s", PyBytes_AsString(obj));
- /* disable g_log redirections */
- pyg_disable_warning_redirections();
-gplugin_python_loader_init_gettext(void) {
- PyObject *module_dict = NULL, *install = NULL;
- PyObject *gettext = NULL, *result = NULL;
- gettext = PyImport_ImportModule("gettext");
- g_warning("Failed to import gettext");
- module_dict = PyModule_GetDict(gettext);
- install = PyDict_GetItemString(module_dict, "install");
- result = PyObject_CallFunction(install, "ss", GETTEXT_PACKAGE, LOCALEDIR);
-gplugin_python_loader_init_python(void) {
- wchar_t *argv[] = { NULL, NULL };
- /* Initializes Python */
- if(!Py_IsInitialized())
- Py_InitializeEx(FALSE);
- argv[0] = Py_DecodeLocale(g_get_prgname(), NULL);
- g_warning("Could not convert program name to wchar_t string.");
- /* setup sys.path according to
- * https://docs.python.org/3/c-api/init.html#PySys_SetArgvEx
- PySys_SetArgvEx(1, argv, 0);
- PyMem_RawFree(argv[0]);
- /* initialize pygobject */
- if(gplugin_python_loader_init_pygobject()) {
- if(gplugin_python_loader_init_gettext()) {
-/******************************************************************************
- *****************************************************************************/
-gplugin_python_loader_init(G_GNUC_UNUSED GPluginPythonLoader *loader) {
-gplugin_python_loader_class_finalize(G_GNUC_UNUSED GPluginPythonLoaderClass *klass)
-gplugin_python_loader_class_init(GPluginPythonLoaderClass *klass) {
- GPluginLoaderClass *loader_class = GPLUGIN_LOADER_CLASS(klass);
- loader_class->supported_extensions =
- gplugin_python_loader_class_supported_extensions;
- loader_class->query = gplugin_python_loader_query;
- loader_class->load = gplugin_python_loader_load;
- loader_class->unload = gplugin_python_loader_unload;
-/******************************************************************************
- *****************************************************************************/
-gplugin_python_loader_register(GPluginNativePlugin *native) {
- gplugin_python_loader_register_type(G_TYPE_MODULE(native));
- gplugin_python_loader_init_python();
--- a/python/gplugin-python-loader.h Sat Feb 15 21:14:07 2020 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#ifndef GPLUGIN_PYTHON_LOADER_H
-#define GPLUGIN_PYTHON_LOADER_H
-#include <gplugin-native.h>
-#define GPLUGIN_PYTHON_TYPE_LOADER (gplugin_python_loader_get_type())
-G_DECLARE_FINAL_TYPE(GPluginPythonLoader, gplugin_python_loader, GPLUGIN_PYTHON, LOADER, GPluginLoader)
-void gplugin_python_loader_register(GPluginNativePlugin *native);
-#endif /* GPLUGIN_PYTHON_LOADER_H */
--- a/python/gplugin-python-plugin.c Sat Feb 15 21:14:07 2020 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,277 +0,0 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#include "gplugin-python-plugin.h"
-/******************************************************************************
- *****************************************************************************/
-struct _GPluginPythonPlugin {
- GPluginPluginInfo *info;
- GPluginPluginState state;
-/******************************************************************************
- *****************************************************************************/
- PROP_FILENAME = N_PROPERTIES,
-static GParamSpec *properties[N_PROPERTIES] = {NULL,};
-/* I hate forward declarations... */
-static void gplugin_python_plugin_iface_init(GPluginPluginInterface *iface);
-G_DEFINE_DYNAMIC_TYPE_EXTENDED(
- G_IMPLEMENT_INTERFACE(GPLUGIN_TYPE_PLUGIN, gplugin_python_plugin_iface_init)
-/******************************************************************************
- * GPluginPlugin Implementation
- *****************************************************************************/
-gplugin_python_plugin_iface_init(G_GNUC_UNUSED GPluginPluginInterface *iface) {
-/******************************************************************************
- *****************************************************************************/
-gplugin_python_plugin_set_module(GPluginPythonPlugin *plugin,
- g_return_if_fail(GPLUGIN_IS_PLUGIN(plugin));
- g_return_if_fail(module);
- Py_CLEAR(plugin->module);
- plugin->module = module;
-gplugin_python_plugin_get_load_func(GPluginPythonPlugin *plugin) {
- g_return_val_if_fail(GPLUGIN_PYTHON_IS_PLUGIN(plugin), NULL);
-gplugin_python_plugin_set_load_func(GPluginPythonPlugin *plugin,
- g_return_if_fail(GPLUGIN_PYTHON_IS_PLUGIN(plugin));
- g_return_if_fail(func != NULL);
- Py_CLEAR(plugin->load);
-gplugin_python_plugin_get_unload_func(GPluginPythonPlugin *plugin) {
- g_return_val_if_fail(GPLUGIN_PYTHON_IS_PLUGIN(plugin), NULL);
-gplugin_python_plugin_set_unload_func(GPluginPythonPlugin *plugin,
- g_return_if_fail(GPLUGIN_PYTHON_IS_PLUGIN(plugin));
- g_return_if_fail(func != NULL);
- Py_CLEAR(plugin->unload);
-/******************************************************************************
- *****************************************************************************/
-gplugin_python_plugin_get_property(GObject *obj, guint param_id, GValue *value,
- GPluginPythonPlugin *plugin = GPLUGIN_PYTHON_PLUGIN(obj);
- g_value_set_pointer(value, plugin->module);
- g_value_set_pointer(value,
- gplugin_python_plugin_get_load_func(plugin));
- g_value_set_pointer(value,
- gplugin_python_plugin_get_unload_func(plugin));
- g_value_set_string(value, plugin->filename);
- g_value_set_object(value, plugin->loader);
- g_value_set_object(value, plugin->info);
- g_value_set_enum(value, plugin->state);
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
-gplugin_python_plugin_set_property(GObject *obj, guint param_id,
- const GValue *value, GParamSpec *pspec)
- GPluginPythonPlugin *plugin = GPLUGIN_PYTHON_PLUGIN(obj);
- gplugin_python_plugin_set_module(plugin,
- g_value_get_pointer(value));
- gplugin_python_plugin_set_load_func(plugin,
- g_value_get_pointer(value));
- gplugin_python_plugin_set_unload_func(plugin,
- g_value_get_pointer(value));
- plugin->filename = g_value_dup_string(value);
- plugin->loader = g_value_dup_object(value);
- plugin->info = g_value_dup_object(value);
- plugin->state = g_value_get_enum(value);
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
-gplugin_python_plugin_finalize(GObject *obj) {
- GPluginPythonPlugin *plugin = GPLUGIN_PYTHON_PLUGIN(obj);
- Py_CLEAR(plugin->module);
- Py_CLEAR(plugin->load);
- Py_CLEAR(plugin->unload);
- g_clear_pointer(&plugin->filename, g_free);
- g_clear_object(&plugin->loader);
- g_clear_object(&plugin->info);
- G_OBJECT_CLASS(gplugin_python_plugin_parent_class)->finalize(obj);
-gplugin_python_plugin_init(G_GNUC_UNUSED GPluginPythonPlugin *plugin) {
-gplugin_python_plugin_class_finalize(G_GNUC_UNUSED GPluginPythonPluginClass *klass)
-gplugin_python_plugin_class_init(GPluginPythonPluginClass *klass) {
- GObjectClass *obj_class = G_OBJECT_CLASS(klass);
- obj_class->get_property = gplugin_python_plugin_get_property;
- obj_class->set_property = gplugin_python_plugin_set_property;
- obj_class->finalize = gplugin_python_plugin_finalize;
- properties[PROP_MODULE] = g_param_spec_pointer(
- "The python module object",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
- properties[PROP_LOAD_FUNC] = g_param_spec_pointer(
- "load-func", "load-func",
- "The python load function",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
- properties[PROP_UNLOAD_FUNC] = g_param_spec_pointer(
- "unload-func", "unload-func",
- "The python unload function",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
- g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
- /* add our overrides */
- g_object_class_override_property(obj_class, PROP_FILENAME, "filename");
- g_object_class_override_property(obj_class, PROP_LOADER, "loader");
- g_object_class_override_property(obj_class, PROP_INFO, "info");
- g_object_class_override_property(obj_class, PROP_STATE, "state");
-/******************************************************************************
- *****************************************************************************/
-gplugin_python_plugin_register(GPluginNativePlugin *native) {
- gplugin_python_plugin_register_type(G_TYPE_MODULE(native));
--- a/python/gplugin-python-plugin.h Sat Feb 15 21:14:07 2020 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#ifndef GPLUGIN_PYTHON_PLUGIN_H
-#define GPLUGIN_PYTHON_PLUGIN_H
-#include <gplugin-native.h>
-#define GPLUGIN_PYTHON_TYPE_PLUGIN (gplugin_python_plugin_get_type())
-G_DECLARE_FINAL_TYPE(GPluginPythonPlugin, gplugin_python_plugin, GPLUGIN_PYTHON, PLUGIN, GObject)
-void gplugin_python_plugin_register(GPluginNativePlugin *native);
-#endif /* GPLUGIN_PYTHON_PLUGIN_H */
--- a/python/gplugin-python-test-pygobject.c Sat Feb 15 21:14:07 2020 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
-main(gint argc, gchar *argv[]) {
- wchar_t *wargv[] = { NULL, NULL };
- /* initialize python */
- if(!Py_IsInitialized())
- Py_InitializeEx(FALSE);
- len = mbstowcs(NULL, argv[0], 0);
- wargv[0] = g_new0(wchar_t, len + 1);
- len = mbstowcs(wargv[0], argv[0], len + 1);
- if(len == (size_t)-1) {
-#if PY_VERSION_HEX < 0x03010300
- PySys_SetArgv(1, wargv);
- PyRun_SimpleString("import sys; sys.path.pop(0)\n");
- PySys_SetArgvEx(1, wargv, 0);
- /* initialize pygobject */
- pygobject_init(3, 0, 0);
--- a/python/gplugin-python-utils.c Sat Feb 15 21:14:07 2020 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,112 +0,0 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#include <gplugin/gplugin.h>
-#include "gplugin-python-utils.h"
-gplugin_python_filename_to_module(const gchar *filename) {
- gchar *e = NULL, *r = NULL;
- g_return_val_if_fail(filename != NULL, NULL);
- /* first make sure we just have a filename */
- base = g_path_get_basename(filename);
- /* now find the last . for the extension */
- e = g_utf8_strrchr(base, g_utf8_strlen(base, -1), g_utf8_get_char("."));
- /* now copy the module name into r */
- r = g_malloc(e - base + 1);
- memcpy(r, base, e - base);
- /* free the basename */
-gplugin_python_add_module_path(const gchar *module_path) {
- PyObject *sys_path = NULL, *path = NULL;
- sys_path = PySys_GetObject("path");
- path = PyUnicode_FromString(module_path);
- if(PySequence_Contains(sys_path, path) == 0) {
- PyList_Insert(sys_path, 0, path);
-gplugin_python_exception_to_gerror(void) {
- PyObject *type = NULL, *value = NULL, *trace = NULL;
- PyObject *type_name = NULL, *value_str = NULL, *obj = NULL;
- PyErr_Fetch(&type, &value, &trace);
- PyErr_NormalizeException(&type, &value, &trace);
- type_name = PyObject_GetAttrString(type, "__name__");
- value_str = PyObject_Str(value);
- /* now decode the utf8 into a string we can use */
- obj = PyUnicode_AsUTF8String(type_name);
- obj = PyUnicode_AsUTF8String(value_str);
- error = g_error_new(GPLUGIN_DOMAIN, 0, "%s: %s",
- PyBytes_AsString(type_name),
- PyBytes_AsString(value_str));
--- a/python/gplugin-python-utils.h Sat Feb 15 21:14:07 2020 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#ifndef GPLUGIN_PYTHON_UTILS_H
-#define GPLUGIN_PYTHON_UTILS_H
-#define GPLUGIN_PYTHON_DOMAIN (g_quark_from_static_string("gplugin-python"))
-gchar *gplugin_python_filename_to_module(const gchar *filename);
-gboolean gplugin_python_add_module_path(const gchar *module_path);
-GError *gplugin_python_exception_to_gerror(void);
-#endif /* GPLUGIN_PYTHON_UTILS_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/python/gplugin-python3-core.c Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,74 @@
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. +#include <gplugin-native.h> +#include <glib/gi18n-lib.h> +#include "gplugin-python3-loader.h" +#include "gplugin-python3-plugin.h" +G_MODULE_EXPORT GPluginPluginInfo * +gplugin_query(G_GNUC_UNUSED GError **error) { + const gchar * const authors[] = { + "Gary Kramlich <grim@reaperworld.com>", + return gplugin_plugin_info_new( + "gplugin/python3-loader", + GPLUGIN_NATIVE_PLUGIN_ABI_VERSION, + "name", "Python Plugin Loader", + "version", GPLUGIN_VERSION, + "license-id", "LGPL-2.0-or-later", + "summary", "A plugin that can load python plugins", + "description", "This plugin allows the loading of plugins written in " + "the python programming language.", + "website", GPLUGIN_WEBSITE, +G_MODULE_EXPORT gboolean +gplugin_load(GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) + gplugin_python3_plugin_register(plugin); + gplugin_python3_loader_register(plugin); + return gplugin_manager_register_loader(GPLUGIN_PYTHON3_TYPE_LOADER, error); +G_MODULE_EXPORT gboolean +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin, + _("The Python loader can not be unloaded") --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/python/gplugin-python3-loader.c Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,376 @@
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. +#include "gplugin-python3-loader.h" +#include "gplugin-python3-plugin.h" +#include "gplugin-python3-utils.h" +#include <glib/gi18n-lib.h> +struct _GPluginPython3Loader { + PyThreadState *py_thread_state; +G_DEFINE_DYNAMIC_TYPE(GPluginPython3Loader, gplugin_python3_loader, GPLUGIN_TYPE_LOADER); +/****************************************************************************** + * GPluginLoader Implementation + *****************************************************************************/ +gplugin_python3_loader_supported_extensions(G_GNUC_UNUSED GPluginLoader *l) { + return g_slist_append(NULL, "py"); +gplugin_python3_loader_query(GPluginLoader *loader, + G_GNUC_UNUSED GError **error) + GPluginPlugin *plugin = NULL; + PyObject *pyinfo = NULL, *args = NULL; + PyObject *module = NULL, *package_list = NULL, *module_dict = NULL; + PyObject *query = NULL, *load = NULL, *unload = NULL; + PyGILState_STATE state; + gchar *module_name = NULL, *dir_name = NULL; + state = pyg_gil_state_ensure(); + /* create package_list as a tuple to handle 'import foo.bar' */ + package_list = PyTuple_New(0); + /* now figure out the module name from the filename */ + module_name = gplugin_python3_filename_to_module(filename); + /* grab the dirname since we need it on sys.path to import the module */ + dir_name = g_path_get_dirname(filename); + gplugin_python3_add_module_path(dir_name); + /* import the module */ + module = PyImport_ImportModuleEx(module_name, NULL, NULL, package_list); + g_warning(_("Failed to query %s"), filename); + /* clean some stuff up */ + Py_DECREF(package_list); + pyg_gil_state_release(state); + /* clean some stuff up */ + Py_DECREF(package_list); + /* at this point we have the module, lets find the query, load, and unload + module_dict = PyModule_GetDict(module); + query = PyDict_GetItemString(module_dict, "gplugin_query"); + g_warning(_("Failed to find the gplugin_query function in %s"), + pyg_gil_state_release(state); + if(!PyCallable_Check(query)) { + g_warning(_("Found gplugin_query in %s but it is not a " + pyg_gil_state_release(state); + load = PyDict_GetItemString(module_dict, "gplugin_load"); + g_warning(_("Failed to find the gplugin_load function in %s"), + pyg_gil_state_release(state); + if(!PyCallable_Check(load)) { + g_warning(_("Found gplugin_load in %s but it is not a " + pyg_gil_state_release(state); + unload = PyDict_GetItemString(module_dict, "gplugin_unload"); + g_warning(_("Failed to find the gplugin_unload function in %s"), + pyg_gil_state_release(state); + if(!PyCallable_Check(unload)) { + g_warning(_("Found gplugin_unload in %s but it is not a " + pyg_gil_state_release(state); + /* now that we have everything, call the query method and get the plugin's + pyinfo = PyObject_Call(query, args, NULL); + info = pygobject_get(pyinfo); + /* now that we have everything, create the plugin */ + GPLUGIN_PYTHON3_TYPE_PLUGIN, + pyg_gil_state_release(state); +gplugin_python3_loader_load(G_GNUC_UNUSED GPluginLoader *loader, + PyObject *load = NULL, *pyplugin = NULL, *result = NULL; + g_object_get(G_OBJECT(plugin), "load-func", &load, NULL); + pyplugin = pygobject_new(G_OBJECT(plugin)); + result = PyObject_CallFunctionObjArgs(load, pyplugin, NULL); + if (PyErr_Occurred()) { + *error = gplugin_python3_exception_to_gerror(); + ret = PyObject_IsTrue(result); + g_set_error_literal(error, GPLUGIN_DOMAIN, 0, + _("Failed to load plugin")); +gplugin_python3_loader_unload(G_GNUC_UNUSED GPluginLoader *loader, + PyObject *unload = NULL, *pyplugin = NULL, *result = NULL; + g_object_get(G_OBJECT(plugin), "unload-func", &unload, NULL); + pyplugin = pygobject_new(G_OBJECT(plugin)); + result = PyObject_CallFunctionObjArgs(unload, pyplugin, NULL); + ret = PyObject_IsTrue(result); + g_set_error_literal(error, GPLUGIN_DOMAIN, 0, + _("Failed to unload plugin")); +/****************************************************************************** + *****************************************************************************/ +gplugin_python3_loader_init_pygobject(void) { + pygobject_init(3, 0, 0); + PyObject *type = NULL, *value = NULL, *tb = NULL, *obj = NULL; + PyErr_Fetch(&type, &value, &tb); + obj = PyUnicode_AsUTF8String(value); + g_warning("Failed to initialize PyGObject : %s", PyBytes_AsString(obj)); + /* disable g_log redirections */ + pyg_disable_warning_redirections(); +gplugin_python3_loader_init_gettext(void) { + PyObject *module_dict = NULL, *install = NULL; + PyObject *gettext = NULL, *result = NULL; + gettext = PyImport_ImportModule("gettext"); + g_warning("Failed to import gettext"); + module_dict = PyModule_GetDict(gettext); + install = PyDict_GetItemString(module_dict, "install"); + result = PyObject_CallFunction(install, "ss", GETTEXT_PACKAGE, LOCALEDIR); +gplugin_python3_loader_init_python(void) { + wchar_t *argv[] = { NULL, NULL }; + /* Initializes Python */ + if(!Py_IsInitialized()) + Py_InitializeEx(FALSE); + argv[0] = Py_DecodeLocale(g_get_prgname(), NULL); + g_warning("Could not convert program name to wchar_t string."); + /* setup sys.path according to + * https://docs.python.org/3/c-api/init.html#PySys_SetArgvEx + PySys_SetArgvEx(1, argv, 0); + PyMem_RawFree(argv[0]); + /* initialize pygobject */ + if(gplugin_python3_loader_init_pygobject()) { + if(gplugin_python3_loader_init_gettext()) { +/****************************************************************************** + * GObject Implementation + *****************************************************************************/ +gplugin_python3_loader_init(G_GNUC_UNUSED GPluginPython3Loader *loader) { +gplugin_python3_loader_class_finalize(G_GNUC_UNUSED GPluginPython3LoaderClass *klass) +gplugin_python3_loader_class_init(GPluginPython3LoaderClass *klass) { + GPluginLoaderClass *loader_class = GPLUGIN_LOADER_CLASS(klass); + loader_class->supported_extensions = + gplugin_python3_loader_supported_extensions; + loader_class->query = gplugin_python3_loader_query; + loader_class->load = gplugin_python3_loader_load; + loader_class->unload = gplugin_python3_loader_unload; +/****************************************************************************** + *****************************************************************************/ +gplugin_python3_loader_register(GPluginNativePlugin *native) { + gplugin_python3_loader_register_type(G_TYPE_MODULE(native)); + gplugin_python3_loader_init_python(); --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/python/gplugin-python3-loader.h Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,33 @@
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. +#ifndef GPLUGIN_PYTHON3_LOADER_H +#define GPLUGIN_PYTHON3_LOADER_H +#include <gplugin-native.h> +#define GPLUGIN_PYTHON3_TYPE_LOADER (gplugin_python3_loader_get_type()) +G_DECLARE_FINAL_TYPE(GPluginPython3Loader, gplugin_python3_loader, GPLUGIN_PYTHON3, LOADER, GPluginLoader) +void gplugin_python3_loader_register(GPluginNativePlugin *native); +#endif /* GPLUGIN_PYTHON3_LOADER_H */ --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/python/gplugin-python3-plugin.c Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,276 @@
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. +#include "gplugin-python3-plugin.h" +/****************************************************************************** + *****************************************************************************/ +struct _GPluginPython3Plugin { + GPluginPluginInfo *info; + GPluginPluginState state; +/****************************************************************************** + *****************************************************************************/ + PROP_FILENAME = N_PROPERTIES, +static GParamSpec *properties[N_PROPERTIES] = {NULL,}; +/* I hate forward declarations... */ +static void gplugin_python3_plugin_iface_init(GPluginPluginInterface *iface); +G_DEFINE_DYNAMIC_TYPE_EXTENDED( + gplugin_python3_plugin, + G_IMPLEMENT_INTERFACE(GPLUGIN_TYPE_PLUGIN, gplugin_python3_plugin_iface_init) +/****************************************************************************** + * GPluginPlugin Implementation + *****************************************************************************/ +gplugin_python3_plugin_iface_init(G_GNUC_UNUSED GPluginPluginInterface *iface) { +/****************************************************************************** + *****************************************************************************/ +gplugin_python3_plugin_set_module(GPluginPython3Plugin *plugin, + g_return_if_fail(GPLUGIN_IS_PLUGIN(plugin)); + g_return_if_fail(module); + Py_CLEAR(plugin->module); + plugin->module = module; +gplugin_python3_plugin_get_load_func(GPluginPython3Plugin *plugin) { + g_return_val_if_fail(GPLUGIN_PYTHON3_IS_PLUGIN(plugin), NULL); +gplugin_python3_plugin_set_load_func(GPluginPython3Plugin *plugin, + g_return_if_fail(GPLUGIN_PYTHON3_IS_PLUGIN(plugin)); + g_return_if_fail(func != NULL); + Py_CLEAR(plugin->load); +gplugin_python3_plugin_get_unload_func(GPluginPython3Plugin *plugin) { + g_return_val_if_fail(GPLUGIN_PYTHON3_IS_PLUGIN(plugin), NULL); +gplugin_python3_plugin_set_unload_func(GPluginPython3Plugin *plugin, + g_return_if_fail(GPLUGIN_PYTHON3_IS_PLUGIN(plugin)); + g_return_if_fail(func != NULL); + Py_CLEAR(plugin->unload); +/****************************************************************************** + * GObject Implementation + *****************************************************************************/ +gplugin_python3_plugin_get_property(GObject *obj, guint param_id, GValue *value, + GPluginPython3Plugin *plugin = GPLUGIN_PYTHON3_PLUGIN(obj); + g_value_set_pointer(value, plugin->module); + g_value_set_pointer(value, + gplugin_python3_plugin_get_load_func(plugin)); + g_value_set_pointer(value, + gplugin_python3_plugin_get_unload_func(plugin)); + g_value_set_string(value, plugin->filename); + g_value_set_object(value, plugin->loader); + g_value_set_object(value, plugin->info); + g_value_set_enum(value, plugin->state); + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); +gplugin_python3_plugin_set_property(GObject *obj, guint param_id, + const GValue *value, GParamSpec *pspec) + GPluginPython3Plugin *plugin = GPLUGIN_PYTHON3_PLUGIN(obj); + gplugin_python3_plugin_set_module(plugin, + g_value_get_pointer(value)); + gplugin_python3_plugin_set_load_func(plugin, + g_value_get_pointer(value)); + gplugin_python3_plugin_set_unload_func(plugin, + g_value_get_pointer(value)); + plugin->filename = g_value_dup_string(value); + plugin->loader = g_value_dup_object(value); + plugin->info = g_value_dup_object(value); + plugin->state = g_value_get_enum(value); + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); +gplugin_python3_plugin_finalize(GObject *obj) { + GPluginPython3Plugin *plugin = GPLUGIN_PYTHON3_PLUGIN(obj); + Py_CLEAR(plugin->module); + Py_CLEAR(plugin->load); + Py_CLEAR(plugin->unload); + g_clear_pointer(&plugin->filename, g_free); + g_clear_object(&plugin->loader); + g_clear_object(&plugin->info); + G_OBJECT_CLASS(gplugin_python3_plugin_parent_class)->finalize(obj); +gplugin_python3_plugin_init(G_GNUC_UNUSED GPluginPython3Plugin *plugin) { +gplugin_python3_plugin_class_finalize(G_GNUC_UNUSED GPluginPython3PluginClass *klass) +gplugin_python3_plugin_class_init(GPluginPython3PluginClass *klass) { + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + obj_class->get_property = gplugin_python3_plugin_get_property; + obj_class->set_property = gplugin_python3_plugin_set_property; + obj_class->finalize = gplugin_python3_plugin_finalize; + properties[PROP_MODULE] = g_param_spec_pointer( + "The python module object", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY + properties[PROP_LOAD_FUNC] = g_param_spec_pointer( + "load-func", "load-func", + "The python load function", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY + properties[PROP_UNLOAD_FUNC] = g_param_spec_pointer( + "unload-func", "unload-func", + "The python unload function", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY + g_object_class_install_properties(obj_class, N_PROPERTIES, properties); + /* add our overrides */ + g_object_class_override_property(obj_class, PROP_FILENAME, "filename"); + g_object_class_override_property(obj_class, PROP_LOADER, "loader"); + g_object_class_override_property(obj_class, PROP_INFO, "info"); + g_object_class_override_property(obj_class, PROP_STATE, "state"); +/****************************************************************************** + *****************************************************************************/ +gplugin_python3_plugin_register(GPluginNativePlugin *native) { + gplugin_python3_plugin_register_type(G_TYPE_MODULE(native)); --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/python/gplugin-python3-plugin.h Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,33 @@
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. +#ifndef GPLUGIN_PYTHON3_PLUGIN_H +#define GPLUGIN_PYTHON3_PLUGIN_H +#include <gplugin-native.h> +#define GPLUGIN_PYTHON3_TYPE_PLUGIN (gplugin_python3_plugin_get_type()) +G_DECLARE_FINAL_TYPE(GPluginPython3Plugin, gplugin_python3_plugin, GPLUGIN_PYTHON3, PLUGIN, GObject) +void gplugin_python3_plugin_register(GPluginNativePlugin *native); +#endif /* GPLUGIN_PYTHON3_PLUGIN_H */ --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/python/gplugin-python3-test-pygobject.c Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,65 @@
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. +main(gint argc, gchar *argv[]) { + wchar_t *wargv[] = { NULL, NULL }; + /* initialize python */ + if(!Py_IsInitialized()) + Py_InitializeEx(FALSE); + len = mbstowcs(NULL, argv[0], 0); + wargv[0] = g_new0(wchar_t, len + 1); + len = mbstowcs(wargv[0], argv[0], len + 1); + if(len == (size_t)-1) { +#if PY_VERSION_HEX < 0x03010300 + PySys_SetArgv(1, wargv); + PyRun_SimpleString("import sys; sys.path.pop(0)\n"); + PySys_SetArgvEx(1, wargv, 0); + /* initialize pygobject */ + pygobject_init(3, 0, 0); --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/python/gplugin-python3-utils.c Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,111 @@
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. +#include <gplugin/gplugin.h> +#include "gplugin-python3-utils.h" +gplugin_python3_filename_to_module(const gchar *filename) { + gchar *e = NULL, *r = NULL; + g_return_val_if_fail(filename != NULL, NULL); + /* first make sure we just have a filename */ + base = g_path_get_basename(filename); + /* now find the last . for the extension */ + e = g_utf8_strrchr(base, g_utf8_strlen(base, -1), g_utf8_get_char(".")); + /* now copy the module name into r */ + r = g_malloc(e - base + 1); + memcpy(r, base, e - base); + /* free the basename */ +gplugin_python3_add_module_path(const gchar *module_path) { + PyObject *sys_path = NULL, *path = NULL; + sys_path = PySys_GetObject("path"); + path = PyUnicode_FromString(module_path); + if(PySequence_Contains(sys_path, path) == 0) { + PyList_Insert(sys_path, 0, path); +gplugin_python3_exception_to_gerror(void) { + PyObject *type = NULL, *value = NULL, *trace = NULL; + PyObject *type_name = NULL, *value_str = NULL, *obj = NULL; + PyErr_Fetch(&type, &value, &trace); + PyErr_NormalizeException(&type, &value, &trace); + type_name = PyObject_GetAttrString(type, "__name__"); + value_str = PyObject_Str(value); + /* now decode the utf8 into a string we can use */ + obj = PyUnicode_AsUTF8String(type_name); + obj = PyUnicode_AsUTF8String(value_str); + error = g_error_new(GPLUGIN_DOMAIN, 0, "%s: %s", + PyBytes_AsString(type_name), + PyBytes_AsString(value_str)); --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/python/gplugin-python3-utils.h Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,33 @@
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. +#ifndef GPLUGIN_PYTHON3_UTILS_H +#define GPLUGIN_PYTHON3_UTILS_H +gchar *gplugin_python3_filename_to_module(const gchar *filename); +gboolean gplugin_python3_add_module_path(const gchar *module_path); +GError *gplugin_python3_exception_to_gerror(void); +#endif /* GPLUGIN_PYTHON3_UTILS_H */ --- a/python/meson.build Sat Feb 15 21:14:07 2020 -0600
+++ b/python/meson.build Tue Feb 25 22:30:11 2020 -0600
@@ -1,19 +1,19 @@
+if get_option('python3') if not get_option('gobject-introspection')
error('Python plugin requires GObject Introspection.')
- GPLUGIN_PYTHON_SOURCES = [
- 'gplugin-python-core.c',
- 'gplugin-python-loader.c',
- 'gplugin-python-plugin.c',
- 'gplugin-python-utils.c',
+ GPLUGIN_PYTHON3_SOURCES = [ + 'gplugin-python3-core.c', + 'gplugin-python3-loader.c', + 'gplugin-python3-plugin.c', + 'gplugin-python3-utils.c', - GPLUGIN_PYTHON_HEADERS = [
- 'gplugin-python-loader.h',
- 'gplugin-python-plugin.h',
- 'gplugin-python-utils.h',
+ GPLUGIN_PYTHON3_HEADERS = [ + 'gplugin-python3-loader.h', + 'gplugin-python3-plugin.h', + 'gplugin-python3-utils.h', PYTHON3 = dependency('python3-embed', version: '>=3.5.0', required: false)
@@ -24,37 +24,37 @@
PYGOBJECT = dependency('pygobject-3.0', version: '>=3.0.0')
# Compile and run our python-gi test program
- python_gi_test = compiler.run(files('gplugin-python-test-pygobject.c'),
+ python3_gi_test = compiler.run(files('gplugin-python3-test-pygobject.c'), dependencies : [GLIB, PYTHON3, PYGOBJECT],
- if not python_gi_test.compiled() or python_gi_test.returncode() != 0
- error('pygobject does not work with python3')
+ if not python3_gi_test.compiled() or python3_gi_test.returncode() != 0 + error('pygobject does not work with Python3') - gplugin_python_inc = include_directories('.')
- gplugin_python = shared_library('gplugin-python3',
- GPLUGIN_PYTHON_SOURCES,
- GPLUGIN_PYTHON_HEADERS,
+ gplugin_python3_inc = include_directories('.') + gplugin_python3 = shared_library('gplugin-python3', + GPLUGIN_PYTHON3_SOURCES, + GPLUGIN_PYTHON3_HEADERS, dependencies : [PYTHON3, PYGOBJECT, gplugin_dep],
install_dir : join_paths(get_option('libdir'), 'gplugin')
- gplugin_python_dep = declare_dependency(
- include_directories : gplugin_python_inc,
- link_with : gplugin_python,
+ gplugin_python3_dep = declare_dependency( + include_directories : gplugin_python3_inc, + link_with : gplugin_python3, - gplugin_python_static = static_library('gplugin-python-static',
- GPLUGIN_PYTHON_SOURCES,
- GPLUGIN_PYTHON_HEADERS,
+ gplugin_python3_static = static_library('gplugin-python3-static', + GPLUGIN_PYTHON3_SOURCES, + GPLUGIN_PYTHON3_HEADERS, dependencies : [PYTHON3, PYGOBJECT, gplugin_dep],
- gplugin_python_static_dep = declare_dependency(
- include_directories : gplugin_python_inc,
- link_with : gplugin_python_static,
+ gplugin_python3_static_dep = declare_dependency( + include_directories : gplugin_python3_inc, + link_with : gplugin_python3_static,
--- a/python/tests/meson.build Sat Feb 15 21:14:07 2020 -0600
+++ b/python/tests/meson.build Tue Feb 25 22:30:11 2020 -0600
@@ -1,26 +1,22 @@
+if get_option('python3') -e = executable('test-python-loader', 'test-python-loader.c',
+e = executable('test-python3-loader', 'test-python3-loader.c', include_directories : include_directories('.'),
- '-DPYTHON_LOADER_DIR="@0@"'.format(join_paths(meson.current_build_dir(), '..')),
- '-DPYTHON_PLUGIN_DIR="@0@/plugins"'.format(meson.current_source_dir()),
+ '-DPYTHON3_LOADER_DIR="@0@"'.format(join_paths(meson.current_build_dir(), '..')), + '-DPYTHON3_PLUGIN_DIR="@0@/plugins"'.format(meson.current_source_dir()), link_with : gplugin_loader_tests,
dependencies : [GLIB, GOBJECT, PYTHON3, PYGOBJECT, gplugin_dep])
-test('Python loader', e)
+test('Python3 loader', e) # we can't see the symbols in gplugin-python externally, so use the static
-e = executable('test-python-utils', 'test-python-utils.c',
+e = executable('test-python3-utils', 'test-python3-utils.c', include_directories : include_directories('.'),
- '-DPYTHON_LOADER_DIR="@0@"'.format(join_paths(meson.current_build_dir(), '..')),
- '-DPYTHON_PLUGIN_DIR="@0@/plugins"'.format(meson.current_source_dir()),
link_with : [gplugin_loader_tests],
dependencies : [GLIB, GOBJECT, PYTHON3, PYGOBJECT,
- gplugin_python_static_dep])
+ gplugin_python3_static_dep]) +test('Python3 utils', e)
--- a/python/tests/plugins/basic.py Sat Feb 15 21:14:07 2020 -0600
+++ b/python/tests/plugins/basic.py Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
-# Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+# Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> # This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -16,9 +16,10 @@
from gi.repository import GPlugin
return GPlugin.PluginInfo(
- id='gplugin/python-basic-plugin',
+ id='gplugin/python3-basic-plugin', @@ -30,10 +31,10 @@
description='description',
def gplugin_load(plugin):
def gplugin_unload(plugin):
--- a/python/tests/plugins/dependent.py Sat Feb 15 21:14:07 2020 -0600
+++ b/python/tests/plugins/dependent.py Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
-# Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+# Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> # This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -16,16 +16,17 @@
from gi.repository import GPlugin
return GPlugin.PluginInfo(
- id='gplugin/python-dependent-plugin',
+ id='gplugin/python3-dependent-plugin', dependencies=['dependency1', 'dependency2'],
def gplugin_load(plugin):
def gplugin_unload(plugin):
--- a/python/tests/plugins/load-exception.py Sat Feb 15 21:14:07 2020 -0600
+++ b/python/tests/plugins/load-exception.py Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
-# Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+# Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> # This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -16,9 +16,10 @@
from gi.repository import GPlugin
return GPlugin.PluginInfo(
- id="gplugin/python-load-exception",
+ id="gplugin/python3-load-exception", @@ -28,5 +29,3 @@
def gplugin_unload(plugin):
--- a/python/tests/plugins/load-failed.py Sat Feb 15 21:14:07 2020 -0600
+++ b/python/tests/plugins/load-failed.py Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
-# Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+# Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> # This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -16,9 +16,10 @@
from gi.repository import GPlugin
return GPlugin.PluginInfo(
- id="gplugin/python-load-failed",
+ id="gplugin/python3-load-failed", @@ -28,5 +29,3 @@
def gplugin_unload(plugin):
--- a/python/tests/plugins/unload-failed.py Sat Feb 15 21:14:07 2020 -0600
+++ b/python/tests/plugins/unload-failed.py Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
-# Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
+# Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> # This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -16,9 +16,10 @@
from gi.repository import GPlugin
return GPlugin.PluginInfo(
- id="gplugin/python-unload-failed",
+ id="gplugin/python3-unload-failed", @@ -28,5 +29,3 @@
def gplugin_unload(plugin):
--- a/python/tests/test-python-loader.c Sat Feb 15 21:14:07 2020 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#include <gplugin/gplugin-loader-tests.h>
-/******************************************************************************
- *****************************************************************************/
-main(gint argc, gchar **argv) {
- g_test_init(&argc, &argv, NULL);
- gplugin_loader_tests_main(PYTHON_LOADER_DIR, PYTHON_PLUGIN_DIR, "python");
--- a/python/tests/test-python-utils.c Sat Feb 15 21:14:07 2020 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
- * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#include "gplugin-python-utils.h"
-/******************************************************************************
- * filename to module tests
- *****************************************************************************/
-test_filename_to_module_NULL_subprocess(void) {
- gplugin_python_filename_to_module(NULL);
-test_filename_to_module_NULL(void) {
- g_test_trap_subprocess("/loaders/python/utils/filename_to_module/NULL/subprocess", 0, 0);
- g_test_trap_assert_failed();
-test_filename_to_module_empty(void) {
- gchar *module = gplugin_python_filename_to_module("");
- g_assert_cmpstr(module, ==, "");
-test_filename_to_module_no_extension(void) {
- gchar *module = gplugin_python_filename_to_module("foo");
- g_assert_cmpstr(module, ==, "foo");
-/******************************************************************************
- *****************************************************************************/
-main(gint argc, gchar **argv) {
- g_test_init(&argc, &argv, NULL);
- g_test_add_func("/loaders/python/utils/filename_to_module/NULL",
- test_filename_to_module_NULL);
- g_test_add_func("/loaders/python/utils/filename_to_module/NULL/subprocess",
- test_filename_to_module_NULL_subprocess);
- g_test_add_func("/loaders/python/utils/filename_to_module/empty",
- test_filename_to_module_empty);
- g_test_add_func("/loaders/python/utils/filename_to_module/no-extension",
- test_filename_to_module_no_extension);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/python/tests/test-python3-loader.c Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,33 @@
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. +#include <gplugin/gplugin-loader-tests.h> +/****************************************************************************** + *****************************************************************************/ +main(gint argc, gchar **argv) { + g_test_init(&argc, &argv, NULL); + gplugin_loader_tests_main(PYTHON3_LOADER_DIR, PYTHON3_PLUGIN_DIR, "python3"); --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/python/tests/test-python3-utils.c Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,75 @@
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. +#include "gplugin-python3-utils.h" +/****************************************************************************** + * filename to module tests + *****************************************************************************/ +test_filename_to_module_NULL_subprocess(void) { + gplugin_python3_filename_to_module(NULL); +test_filename_to_module_NULL(void) { + g_test_trap_subprocess("/loaders/python/utils/filename_to_module/NULL/subprocess", 0, 0); + g_test_trap_assert_failed(); +test_filename_to_module_empty(void) { + gchar *module = gplugin_python3_filename_to_module(""); + g_assert_cmpstr(module, ==, ""); +test_filename_to_module_no_extension(void) { + gchar *module = gplugin_python3_filename_to_module("foo"); + g_assert_cmpstr(module, ==, "foo"); +/****************************************************************************** + *****************************************************************************/ +main(gint argc, gchar **argv) { + g_test_init(&argc, &argv, NULL); + g_test_add_func("/loaders/python/utils/filename_to_module/NULL", + test_filename_to_module_NULL); + g_test_add_func("/loaders/python/utils/filename_to_module/NULL/subprocess", + test_filename_to_module_NULL_subprocess); + g_test_add_func("/loaders/python/utils/filename_to_module/empty", + test_filename_to_module_empty); + g_test_add_func("/loaders/python/utils/filename_to_module/no-extension", + test_filename_to_module_no_extension); --- a/tcc/gplugin-tcc-core.c Sat Feb 15 21:14:07 2020 -0600
+++ b/tcc/gplugin-tcc-core.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -51,15 +51,11 @@
-gplugin_load(GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+gplugin_load(GPluginNativePlugin *plugin, GError **error) { gplugin_tcc_loader_register(plugin);
gplugin_tcc_plugin_register(plugin);
- gplugin_manager_register_loader(GPLUGIN_TCC_TYPE_LOADER);
+ return gplugin_manager_register_loader(GPLUGIN_TCC_TYPE_LOADER, error); @@ -75,4 +71,3 @@
--- a/tcc/gplugin-tcc-loader.c Sat Feb 15 21:14:07 2020 -0600
+++ b/tcc/gplugin-tcc-loader.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -19,7 +19,7 @@
#include "gplugin-tcc-plugin.h"
+#include <glib/gi18n-lib.h> @@ -33,12 +33,8 @@
* GPluginLoaderInterface API
*****************************************************************************/
-gplugin_tcc_loader_class_supported_extensions(G_GNUC_UNUSED const GPluginLoaderClass *klass) {
- exts = g_slist_append(exts, "c");
+gplugin_tcc_loader_supported_extensions(G_GNUC_UNUSED GPluginLoader *l) { + return g_list_append(NULL, "c"); @@ -164,7 +160,7 @@
GPluginLoaderClass *loader_class = GPLUGIN_LOADER_CLASS(klass);
loader_class->supported_extensions =
- gplugin_tcc_loader_class_supported_extensions;
+ gplugin_tcc_loader_supported_extensions; loader_class->query = gplugin_tcc_loader_query;
loader_class->load = gplugin_tcc_loader_load;
loader_class->unload = gplugin_tcc_loader_unload;
--- a/tcc/gplugin-tcc-loader.h Sat Feb 15 21:14:07 2020 -0600
+++ b/tcc/gplugin-tcc-loader.h Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -30,4 +30,3 @@
#endif /* GPLUGIN_TCC_LOADER_H */
--- a/tcc/gplugin-tcc-plugin.c Sat Feb 15 21:14:07 2020 -0600
+++ b/tcc/gplugin-tcc-plugin.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -204,4 +204,3 @@
--- a/tcc/gplugin-tcc-plugin.h Sat Feb 15 21:14:07 2020 -0600
+++ b/tcc/gplugin-tcc-plugin.h Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -38,4 +38,3 @@
#endif /* GPLUGIN_TCC_PLUGIN_H */
--- a/tcc/tests/plugins/basic-plugin.c Sat Feb 15 21:14:07 2020 -0600
+++ b/tcc/tests/plugins/basic-plugin.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -53,4 +53,3 @@
--- a/tcc/tests/plugins/dependent.c Sat Feb 15 21:14:07 2020 -0600
+++ b/tcc/tests/plugins/dependent.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -47,4 +47,3 @@
--- a/tcc/tests/plugins/load-exception.c Sat Feb 15 21:14:07 2020 -0600
+++ b/tcc/tests/plugins/load-exception.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -39,4 +39,3 @@
--- a/tcc/tests/plugins/load-failed.c Sat Feb 15 21:14:07 2020 -0600
+++ b/tcc/tests/plugins/load-failed.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -39,4 +39,3 @@
--- a/tcc/tests/plugins/unload-failed.c Sat Feb 15 21:14:07 2020 -0600
+++ b/tcc/tests/plugins/unload-failed.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -39,4 +39,3 @@
--- a/tcc/tests/test-tcc-loader.c Sat Feb 15 21:14:07 2020 -0600
+++ b/tcc/tests/test-tcc-loader.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -28,4 +28,3 @@
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vala/tests/genie-plugins/basic.gs Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,49 @@
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. +class BasicPluginInfo : GPlugin.PluginInfo + authors : array of string = {"author1"} + id: "gplugin/genie-basic-plugin", + abi_version: 0x01020304, + description: "description" +def gplugin_query(out error : Error) : GPlugin.PluginInfo + return new BasicPluginInfo() +def gplugin_load(plugin : GPlugin.Plugin, out error : Error) : bool +def gplugin_unload(plugin : GPlugin.Plugin, out error : Error) : bool --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vala/tests/genie-plugins/dependent.gs Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,41 @@
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. +class DependentPluginInfo : GPlugin.PluginInfo + dependencies : array of string = {"dependency1", "dependency2"} + id: "gplugin/genie-dependent-plugin", + dependencies: dependencies +def gplugin_query(out error : Error) : GPlugin.PluginInfo + return new DependentPluginInfo() +def gplugin_load(plugin : GPlugin.Plugin, out error : Error) : bool +def gplugin_unload(plugin : GPlugin.Plugin, out error : Error) : bool --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vala/tests/genie-plugins/load-exception.gs Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,38 @@
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. +class LoadExceptionPluginInfo : GPlugin.PluginInfo + id: "gplugin/genie-load-exception" +def gplugin_query(out error : Error) : GPlugin.PluginInfo + return new LoadExceptionPluginInfo() +def gplugin_load(plugin : GPlugin.Plugin, out error : Error) : bool + error = new Error(Quark.from_string("gplugin"), 0, "explode") +def gplugin_unload(plugin : GPlugin.Plugin, out error : Error) : bool --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vala/tests/genie-plugins/load-failed.gs Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,38 @@
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. +class LoadFailedPluginInfo : GPlugin.PluginInfo + id: "gplugin/genie-load-failed" +def gplugin_query(out error : Error) : GPlugin.PluginInfo + return new LoadFailedPluginInfo() +def gplugin_load(plugin : GPlugin.Plugin, out error : Error) : bool +def gplugin_unload(plugin : GPlugin.Plugin, out error : Error) : bool --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vala/tests/genie-plugins/meson.build Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,17 @@
+ shared_library('genie-basic-plugin', 'basic.gs', + dependencies : [gplugin_dep, gplugin_vapi]) + shared_library('genie-dependent-plugin', 'dependent.gs', + dependencies : [gplugin_dep, gplugin_vapi]) + shared_library('load-exception-plugin', 'load-exception.gs', + dependencies : [gplugin_dep, gplugin_vapi]) + shared_library('load-failed-plugin', 'load-failed.gs', + dependencies : [gplugin_dep, gplugin_vapi]) + shared_library('unload-failed-plugin', 'unload-failed.gs', + dependencies : [gplugin_dep, gplugin_vapi]) --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vala/tests/genie-plugins/unload-failed.gs Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,38 @@
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. +class UnloadFailedPluginInfo : GPlugin.PluginInfo + id: "gplugin/genie-unload-failed" +def gplugin_query(out error : Error) : GPlugin.PluginInfo + return new UnloadFailedPluginInfo() +def gplugin_load(plugin : GPlugin.Plugin, out error : Error) : bool +def gplugin_unload(plugin : GPlugin.Plugin, out error : Error) : bool --- a/vala/tests/meson.build Sat Feb 15 21:14:07 2020 -0600
+++ b/vala/tests/meson.build Tue Feb 25 22:30:11 2020 -0600
@@ -9,6 +9,16 @@
dependencies : [GLIB, GOBJECT, gplugin_dep])
+e = executable('test-genie-loading', 'test-genie-loading.c', + include_directories : include_directories('.'), + '-DGENIE_PLUGIN_DIR="@0@/genie-plugins"'.format(meson.current_build_dir()), + link_with : gplugin_loader_tests, + dependencies : [GLIB, GOBJECT, gplugin_dep]) +test('Genie loading', e) --- a/vala/tests/plugins/basic.vala Sat Feb 15 21:14:07 2020 -0600
+++ b/vala/tests/plugins/basic.vala Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2019 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
--- a/vala/tests/plugins/dependent.vala Sat Feb 15 21:14:07 2020 -0600
+++ b/vala/tests/plugins/dependent.vala Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2019 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
--- a/vala/tests/plugins/load-exception.vala Sat Feb 15 21:14:07 2020 -0600
+++ b/vala/tests/plugins/load-exception.vala Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2019 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
--- a/vala/tests/plugins/load-failed.vala Sat Feb 15 21:14:07 2020 -0600
+++ b/vala/tests/plugins/load-failed.vala Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2019 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
--- a/vala/tests/plugins/unload-failed.vala Sat Feb 15 21:14:07 2020 -0600
+++ b/vala/tests/plugins/unload-failed.vala Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2019 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vala/tests/test-genie-loading.c Tue Feb 25 22:30:11 2020 -0600
@@ -0,0 +1,33 @@
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. +#include <gplugin/gplugin-loader-tests.h> +/****************************************************************************** + *****************************************************************************/ +main(gint argc, gchar **argv) { + g_test_init(&argc, &argv, NULL); + gplugin_loader_tests_main(NULL, GENIE_PLUGIN_DIR, "genie"); --- a/vala/tests/test-vala-loading.c Sat Feb 15 21:14:07 2020 -0600
+++ b/vala/tests/test-vala-loading.c Tue Feb 25 22:30:11 2020 -0600
@@ -1,5 +1,5 @@
- * Copyright (C) 2011-2019 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -31,4 +31,3 @@