--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/.clang-format Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,165 @@
+AccessModifierOffset: -2 +AlignAfterOpenBracket: AlwaysBreak +AlignConsecutiveMacros: false +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: DontAlign +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: false +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: TopLevel +AlwaysBreakAfterReturnType: TopLevelDefinitions +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes +BinPackParameters: false + AfterControlStatement: false + AfterObjCDeclaration: false + AfterExternBlock: false + SplitEmptyFunction: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Custom +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 2 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: false +# With clang-format-11, change: + - Regex: '^[<"](aio|arpa/inet|assert|complex|cpio|ctype|curses|dirent|dlfcn|errno|fcntl|fenv|float|fmtmsg|fnmatch|ftw|glob|grp|iconv|inttypes|iso646|langinfo|libgen|limits|locale|math|monetary|mqueue|ndbm|netdb|net/if|netinet/in|netinet/tcp|nl_types|poll|pthread|pwd|regex|sched|search|semaphore|setjmp|signal|spawn|stdalign|stdarg|stdatomic|stdbool|stddef|stdint|stdio|stdlib|stdnoreturn|string|strings|stropts|sys/ipc|syslog|sys/mman|sys/msg|sys/resource|sys/select|sys/sem|sys/shm|sys/socket|sys/stat|sys/statvfs|sys/time|sys/times|sys/types|sys/uio|sys/un|sys/utsname|sys/wait|tar|term|termios|tgmath|threads|time|trace|uchar|ulimit|uncntrl|unistd|utime|utmpx|wchar|wctype|wordexp)\.h[">]$' + - Regex: '^<(glib-|gmodule)' + # With clang-format-11, change: + - Regex: '^<(gio/|glib/|gobject/)' + # With clang-format-11, change: + - Regex: '^<gplugin\.h>' + - Regex: '^<gplugin-[^/]+\.h>' + # With clang-format-11, change: + # With clang-format-11, change: + - Regex: '^<gplugin-gtk/' + # With clang-format-11, change: + # Other libraries' headers + # Our (internal) headers +IncludeIsMainRegex: '(Test)?$' +IndentPPDirectives: None +IndentWrappedFunctionNames: false +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '^G_STMT_START$' +MacroBlockEnd: '^G_STMT_END$' +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: Never +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInContainerLiterals: false +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +UseTab: ForContinuationAndIndentation --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/.reviewboardrc Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,5 @@
+REVIEWBOARD_URL = "https://reviews.imfreedom.org/" +REPOSITORY = "gplugin/gplugin" +REPOSITORY_TYPE = "mercurial" +LAND_DEST_BRANCH = "develop" --- a/ChangeLog Thu Nov 07 23:09:55 2019 -0600
+++ b/ChangeLog Sat Sep 05 20:05:36 2020 -0500
@@ -1,8 +1,56 @@
+ * Changed the website to the repository on keep.imfreedom.org. + * Removed an unnecessary meson version check. (Gary Kramlich) + * Bumped the required meson version to 0.50.0. (Gary Kramlich) + * Removed gplugin-version.sh.in as it was used in the cmake build system. + * Fixed licenses throughout the codebase. (Richard Laager) + * Removed GPluginVersionCompareFunc and the GPluginPluginInfo::version-func + property as they aren't necessary with semantic versioning. (Gary Kramlich) + * Added new plugin state UNLOAD_FAILED. When a plugin fails to unload, it + now goes to UNLOAD_FAILED instead of LOADED. (Gary Kramlich) + * Added gplugin_manager_foreach and GPluginManagerForeachFunc to make it + easier to operate on all plugins. (Gary Kramlich) + * Added GPluginManager::unload-plugin-failed signal that gets emitted when + a plugin fails to unload. + * Renamed the GPluginManager::load-failed signal to + GPluginManager::load-plugin-failed and added the error, if any, that the + plugin returned. (Gary Kramlich) + * Added gplugin_manager_find_plugin_with_newest_version. (Gary Kramlich) + * Added an "error" property to GPluginPlugin with a getter. (Gary Kramlich) + * Removed the error parameter from the "plugin-load-failed" and + "plugin-unload-failed" signals. Call gplugin_plugin_get_error instead. + * Updated the GPluginGtkView widget to disable entries if there are in the + GPLUGIN_PLUGIN_STATE_LOAD_FAILED state. (Gary Kramlich) + * Updated the GPluginGtkPluginInfo widget to display the "error" property if + it is set, or "(none)". (Gary Kramlich) + * 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. * Synchronize GPluginGtkStore with the plugin manager, make the enabled
toggle button work in GPluginGtkView, and allow developers to decide
whether or not to show column headers in GPlugingGtkView. (PR #37)
* Added error messages when the unload method of a plugin loader is called.
@@ -151,7 +199,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/HACKING Thu Nov 07 23:09:55 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-GPlugin uses hgflow[1] for development. All development takes place on the
-develop branch which leaves default to be a stable release clone. All long
-term feature/bug fix work should take place on a feature branch that when
-closed, gets merged to develop.
-Releases are forked from develop and create a new branch for any testing/bug
-fixes. When a release is deemed done, it's merged back into develop and into
-default. hgflow takes care of all of this for us.
-To add a feature please fork https://bitbucket.org/gplugin/gplugin. Then clone
-your fork. Once you have your fork cloned and hgflow setup and installed, type
- hg flow feature start $NAME_OF_YOUR_FEATURE$
-This will create a new branch for you to do your work on. When you submit a
-pull request, make sure it's this branch that you're requesting I pull.
-[1] https://bitbucket.org/yujiewu/hgflow
--- a/HACKING.OSX Thu Nov 07 23:09:55 2019 -0600
+++ b/HACKING.OSX Sat Sep 05 20:05:36 2020 -0500
@@ -4,35 +4,16 @@
support fink or macports, please let me know and I will merge your pull
-Both the Lua and Python loaders are currently broken as we can't build the
-gobject-introspection targets. Currently the only way to build is with:
+Currently there is no known way to build the Perl loader on MacOS. So you +**MUST** run meson with `-Dperl5=false`.
-export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:$(brew --prefix libffi)/lib/pkgconfig"
-meson -Dlua=false -Dpython=false -Dgobject-introspection=false build
-For the Lua loader to work, you need to install lgi from luarocks either
+For the Lua loader to work, you need to install `lgi` from luarocks either systemwide or to a virtual environment created by LuaDist, vert, or something
-When you're building lgi against homebrew you'll have to set the
-PKG_CONFIG_PATH environment variable since homebrew does not install libffi
-systemwide. This is easily done via:
- export PKG_CONFIG_PATH=$(brew --prefix libffi)/lib/pkgconfig
+along those lines, then you just need to run `luarocks install lgi`. -and then running "luarocks install lgi"
-If you're using homebrew, you need to install pygobject3 with
+If you're using homebrew, you need to install `pygobject3`. - brew install pygobject3 --with-python3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/HACKING.md Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,100 @@
+GPlugin uses [clang-format][1] to automatically format code. Version 9 (or +higher) is required. Earlier versions will fail on the options in the +You can use clang-format in one or more of the following ways: +* Integrate it into your editor. The [clang-format page][1] has examples. +* Use a Mercurial [hook script][2]. +* Run `ninja clang-format` from your build directory. +* Worst case, run `clang-format -i SOME_FILE` manually. +GObject and GPlugin have functions which take pairs of name/value arguments: +* `gplugin_plugin_info_new()` +If code calling one of these functions with such pairs has to be wrapped, the +pairs are easier to read and edit with manual formatting to group the name and +value on the same line (but otherwise following the usual formatting that +clang-format would apply): +Debian and derivatives (e.g. Ubuntu) ship clang-format version 9 in a package +named `clang-format-9`. The package named `clang-format` is currently an +older version. Additionally, the `clang-format-9` package will not place a +`clang-format` in the `$PATH`. Install as follows: +sudo apt install clang-format-9 +sudo update-alternatives --set clang-format /usr/bin/clang-format-9 +GPlugin uses [Convey][3] for CI. You can run the integration tests locally. +To initially setup Convey, which requires Docker: +1. Install Convey. You can use a pre-built binary from [convey's Downloads + page][4]; put that (or a symlink) in your `$PATH` named `convey`. + For now, avoid version 0.14. +2. Install Docker. On Debian systems, use: `sudo apt install docker.io` +3. Add yourself to the `docker` group. Adding yourself to a group does not + add that group to your existing session, so the first time you will need to + get a shell in that group with `newgrp docker` or by rebooting. +To run all of the integration tests, run the "all" metaplan: +To run a specific test/platform, run the plan directly: +convey alpine-edge-amd64 +To get a list of metaplans and their plans: +GPlugin uses [hgflow][5] for development. All development takes place on the +develop branch which leaves default to be a stable release clone. All long +term feature/bug fix work should take place on a feature branch that when +closed, gets merged to develop. +Releases are forked from develop and create a new branch for any testing/bug +fixes. When a release is deemed done, it's merged back into develop and into +default. hgflow takes care of all of this for us. +To add a feature please clone `https://keep.imfreedom.org/gplugin/gplugin`. +Once you have your fork cloned and hgflow setup and installed, type: +hg flow feature start $NAME_OF_YOUR_FEATURE$ +This will create a new branch for you to do your work on. When your work has +been completed, please open a review request at +[reviews.imfreedom.org](https://reviews.imfreedom.org). +[1]: https://clang.llvm.org/docs/ClangFormat.html +[2]: https://hg.mozilla.org/projects/nss/file/default/coreconf/precommit.clang-format.sh +[3]: https://keep.imfreedom.org/grim/convey +[4]: https://bintray.com/pidgin/releases/convey +[5]: https://hg.sr.ht/~wu/hgflow --- a/HISTORY.md Thu Nov 07 23:09:55 2019 -0600
+++ b/HISTORY.md Sat Sep 05 20:05:36 2020 -0500
@@ -32,10 +32,10 @@
but come on, that should be a one time cost to the library author, instead of
an additional startup cost to the plugin author. STRIKE TWO!
-So with two strikes down, I continued researching libpeas, by now working on a
-plugin for rhythmbox, and just found the API to be clunky and poorly
-documented. Now maybe I just wasn't finding the write documentation, but this
+So with two strikes down, I continued researching libpeas, and discovered that +you can only use one language other than the native loader. We, the Pidgin, +developers have always aimed to support as many languages as possible, and this +just wasn't going to cut it. So there was STRIKE THREE! Libpeas had struck out for me, and as such I started GPlugin the very next day!
--- a/INSTALL.md Thu Nov 07 23:09:55 2019 -0600
+++ b/INSTALL.md Sat Sep 05 20:05:36 2020 -0500
@@ -1,6 +1,7 @@
GPlugin depends on the following at a bare minimum:
* gobject-introspection, libgirepository1.0-dev
@@ -9,6 +10,7 @@
A full build (enabled by default) depends on the following:
* python3-dev, python-gi-dev, python3-gi
* liblua5.1-0-dev, lua-lgi
@@ -19,9 +21,9 @@
-GPlugin uses meson (http://mesonbuild.com/) as its build system. As such
-compiling is a little bit different than your typical ./configure, make,
-sudo make install. But luckily for you, not too much different.
+GPlugin uses [meson](http://mesonbuild.com/) as its build system. As such +compiling is a little bit different than your typical `./configure`, `make`, Meson requires you to build in a separate directory than your source. As such,
these instructions use a separate build directory.
@@ -35,5 +37,5 @@
If you want/need to tweak the build system (to enable/disable certain loaders)
-you can do so at any time by using mesonconf in the build directory.
+you can do so at any time by using `meson configure` in the build directory. --- a/README.md Thu Nov 07 23:09:55 2019 -0600
+++ b/README.md Sat Sep 05 20:05:36 2020 -0500
@@ -1,5 +1,10 @@
+[ ![Download](https://api.bintray.com/packages/pidgin/releases/GPlugin/images/download.svg) ](https://bintray.com/pidgin/releases/GPlugin/_latestVersion) +[ ![Issues](https://img.shields.io/badge/Issues-YouTrack-ee3b8b.svg) ](https://issues.imfreedom.org/issues/GPLUGIN) GPlugin is a GObject based library that implements a reusable plugin system.
It supports loading plugins in multiple other languages via loaders. It relies
heavily on [GObjectIntrospection](https://gi.readthedocs.io/) to expose its API
@@ -7,13 +12,7 @@
It has a simple API which makes it very easy to use in your application.
For more information on using GPlugin in your application, please see the
-[embedding](Embedding) page.
-Default: [![Default Build Status](https://bamboo.pidgin.im/plugins/servlet/wittified/build-status/GPLUG-GPLUGIN)](https://bamboo.pidgin.im/browse/GPLUG-GPLUGIN)
-Develop: [![Develop Build Status](https://bamboo.pidgin.im/plugins/servlet/wittified/build-status/GPLUG-GPLUGIN0)](https://bamboo.pidgin.im/browse/GPLUG-GPLUGIN0/)
+[embedding](https://docs.pidgin.im/gplugin/latest/chapter-embedding.html) page. @@ -25,8 +24,5 @@
-The API reference for the `default` branch can be found at
-[docs.pidgin.im/gplugin/default](https://docs.pidgin.im/gplugin/default).
-The in-development API reference for the `develop` branch can be found at
-[docs.pidgin.im/gplugin/develop](https://docs.pidgin.im/gplugin/develop).
+The in-development API reference for the development branch can be found at +[docs.pidgin.im/gplugin/latest](https://docs.pidgin.im/gplugin/latest/). --- a/convey.yml Thu Nov 07 23:09:55 2019 -0600
+++ b/convey.yml Sat Sep 05 20:05:36 2020 -0500
@@ -6,7 +6,7 @@
- - DOCS_BUILD_IMAGE=${REGISTRY}/${REPOSITORY}:debian-buster-amd64
+ - DOCS_BUILD_IMAGE=${REGISTRY}/${REPOSITORY}:debian-bullseye-amd64 @@ -15,22 +15,22 @@
+ - debian-bullseye-arm64 + - debian-bullseye-armhf
- opensuse-tumbleweed-amd64
@@ -116,15 +116,23 @@
- tasks: [import, build, export]
- environment: [DISTRO=debian, VERSION=buster]
+ environment: [TARGET=clang-format] - - tasks: [import, build, export]
+ - tasks: [import, build-target] environment: [DISTRO=debian, VERSION=bullseye]
- tasks: [import, build, export]
+ environment: [DISTRO=debian, VERSION=bullseye, ARCH=arm64] + - tasks: [import, build, export] + environment: [DISTRO=debian, VERSION=bullseye, ARCH=armhf] + - tasks: [import, build, export] environment: [TARGET=dist]
@@ -136,10 +144,6 @@
- tasks: [import, build, export]
- environment: [DISTRO=fedora, VERSION=29]
- - tasks: [import, build, export]
environment: [DISTRO=fedora, VERSION=30]
@@ -148,6 +152,10 @@
environment: [DISTRO=fedora, VERSION=31]
- tasks: [import, build, export]
+ environment: [DISTRO=fedora, VERSION=32] + - tasks: [import, build, export] environment: [DISTRO=fedora, VERSION=rawhide]
@@ -177,6 +185,11 @@
+ environment: [TARGET=i18n] + - tasks: [import, build-target, export-target] environment: [DISTRO=mingw, VERSION=w64, ARCH=i686, PKGBUILD_DIR=mingw-cross]
@@ -196,6 +209,7 @@
+ - PVS_IGNORED_CODES=V568 - tasks: [import, build-target]
@@ -213,16 +227,8 @@
- tasks: [import, build-target]
- environment: [DISTRO=ubuntu, VERSION=bionic]
- - tasks: [import, build, export]
- environment: [DISTRO=ubuntu, VERSION=cosmic]
- - tasks: [import, build, export]
- environment: [DISTRO=ubuntu, VERSION=disco]
+ environment: [DISTRO=ubuntu, VERSION=focal] - tasks: [import, build, export]
@@ -236,10 +242,6 @@
- tasks: [import-artifacts, publish-deb, publish-debsrc]
tasks: [import-artifacts, publish-deb, publish-debsrc]
@@ -253,15 +255,7 @@
tasks: [import-artifacts, publish-rpm]
- tasks: [import-artifacts, publish-deb, publish-debsrc]
- tasks: [import-artifacts, publish-deb, publish-debsrc]
tasks: [import-artifacts, publish-deb, publish-debsrc]
@@ -269,16 +263,25 @@
- - elementary-juno-amd64
- opensuse-tumbleweed-amd64
+ - debian-bullseye-arm64 + - debian-bullseye-armhf --- a/gplugin-gtk-viewer/gplugin-gtk-viewer-window.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin-gtk-viewer/gplugin-gtk-viewer-window.c Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -15,38 +14,41 @@
* 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-gtk-viewer-window.h" -#include "gplugin-gtk-viewer-window.h"
struct _GPluginGtkViewerWindow {
-G_DEFINE_TYPE(GPluginGtkViewerWindow, gplugin_gtk_viewer_window, GTK_TYPE_WINDOW)
+ GPluginGtkViewerWindow, + gplugin_gtk_viewer_window, /******************************************************************************
*****************************************************************************/
-gplugin_gtk_viewer_window_init(GPluginGtkViewerWindow *window) {
+gplugin_gtk_viewer_window_init(GPluginGtkViewerWindow *window) gtk_widget_init_template(GTK_WIDGET(window));
-gplugin_gtk_viewer_window_class_init(GPluginGtkViewerWindowClass *klass) {
+gplugin_gtk_viewer_window_class_init(GPluginGtkViewerWindowClass *klass) gtk_widget_class_set_template_from_resource(
- "/org/bitbucket/gplugin/gplugin/viewer/window.ui"
+ "/org/bitbucket/gplugin/gplugin/viewer/window.ui"); /******************************************************************************
*****************************************************************************/
-GtkWidget *gplugin_gtk_viewer_window_new(void) {
- return GTK_WIDGET(g_object_new(
- GPLUGIN_GTK_VIEWER_TYPE_WINDOW,
+gplugin_gtk_viewer_window_new(void) + return GTK_WIDGET(g_object_new(GPLUGIN_GTK_VIEWER_TYPE_WINDOW, NULL)); --- a/gplugin-gtk-viewer/gplugin-gtk-viewer-window.h Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin-gtk-viewer/gplugin-gtk-viewer-window.h Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -25,7 +24,12 @@
#define GPLUGIN_GTK_VIEWER_TYPE_WINDOW (gplugin_gtk_viewer_window_get_type())
-G_DECLARE_FINAL_TYPE(GPluginGtkViewerWindow, gplugin_gtk_viewer_window, GPLUGIN_GTK_VIEWER, WINDOW, GtkWindow)
+ GPluginGtkViewerWindow, + gplugin_gtk_viewer_window, --- a/gplugin-gtk-viewer/gplugin-gtk-viewer.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin-gtk-viewer/gplugin-gtk-viewer.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,8 +20,8 @@
-#include <gplugin/gplugin.h>
-#include <gplugin-gtk/gplugin-gtk.h>
+#include <gplugin-gtk.h> /******************************************************************************
@@ -34,9 +34,10 @@
*****************************************************************************/
-window_closed_cb(G_GNUC_UNUSED GtkWidget *w,
- G_GNUC_UNUSED GdkEvent *e,
- G_GNUC_UNUSED gpointer d)
+ G_GNUC_UNUSED GtkWidget *w, + G_GNUC_UNUSED GdkEvent *e, + G_GNUC_UNUSED gpointer d) @@ -44,16 +45,20 @@
-selection_changed_cb(GtkTreeSelection *sel, gpointer data) {
+selection_changed_cb(GtkTreeSelection *sel, gpointer data) GPluginGtkPluginInfo *info = GPLUGIN_GTK_PLUGIN_INFO(data);
GPluginPlugin *plugin = NULL;
GtkTreeModel *model = NULL;
if(gtk_tree_selection_get_selected(sel, &model, &iter)) {
- gtk_tree_model_get(model, &iter,
- GPLUGIN_GTK_STORE_PLUGIN_COLUMN, &plugin,
+ GPLUGIN_GTK_STORE_PLUGIN_COLUMN, gplugin_gtk_plugin_info_set_plugin(info, plugin);
@@ -63,10 +68,11 @@
*****************************************************************************/
-internal_cb(G_GNUC_UNUSED const gchar *n,
- G_GNUC_UNUSED const gchar *v,
- G_GNUC_UNUSED gpointer d,
- G_GNUC_UNUSED GError **e)
+ G_GNUC_UNUSED const gchar *n, + G_GNUC_UNUSED const gchar *v, + G_GNUC_UNUSED gpointer d, + G_GNUC_UNUSED GError **e) @@ -74,10 +80,11 @@
-no_default_cb(G_GNUC_UNUSED const gchar *n,
- G_GNUC_UNUSED const gchar *v,
- G_GNUC_UNUSED gpointer d,
- G_GNUC_UNUSED GError **e)
+ G_GNUC_UNUSED const gchar *n, + G_GNUC_UNUSED const gchar *v, + G_GNUC_UNUSED gpointer d, + G_GNUC_UNUSED GError **e) add_default_paths = FALSE;
@@ -85,10 +92,11 @@
-version_cb(G_GNUC_UNUSED const gchar *n,
- G_GNUC_UNUSED const gchar *v,
- G_GNUC_UNUSED gpointer d,
- G_GNUC_UNUSED GError **e)
+ G_GNUC_UNUSED const gchar *n, + G_GNUC_UNUSED const gchar *v, + G_GNUC_UNUSED gpointer d, + G_GNUC_UNUSED GError **e) @@ -98,7 +106,8 @@
GtkWidget *window = NULL, *grid = NULL, *sw = NULL;
GtkWidget *view = NULL, *info = NULL;
GtkTreeSelection *sel = NULL;
@@ -106,8 +115,11 @@
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "GPlugin Viewer");
gtk_container_set_border_width(GTK_CONTAINER(window), 12);
- g_signal_connect(G_OBJECT(window), "delete-event",
- G_CALLBACK(window_closed_cb), NULL);
+ G_CALLBACK(window_closed_cb), gtk_grid_set_row_homogeneous(GTK_GRID(grid), TRUE);
@@ -115,10 +127,11 @@
gtk_container_add(GTK_CONTAINER(window), grid);
sw = gtk_scrolled_window_new(NULL, NULL);
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
- GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
+ gtk_scrolled_window_set_policy( + GTK_SCROLLED_WINDOW(sw), + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN); gtk_grid_attach(GTK_GRID(grid), sw, 0, 0, 1, 1);
view = gplugin_gtk_view_new();
@@ -129,8 +142,11 @@
gtk_grid_attach(GTK_GRID(grid), info, 1, 0, 1, 1);
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
- g_signal_connect(G_OBJECT(sel), "changed",
- G_CALLBACK(selection_changed_cb), info);
+ G_CALLBACK(selection_changed_cb), @@ -138,6 +154,7 @@
/******************************************************************************
*****************************************************************************/
static GOptionEntry entries[] = {
"internal", 'i', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
@@ -159,9 +176,11 @@
NULL, 0, 0, 0, NULL, NULL, NULL,
-main(gint argc, gchar **argv) {
+main(gint argc, gchar **argv) GOptionContext *ctx = NULL;
GtkWidget *window = NULL;
@@ -212,4 +231,3 @@
--- a/gplugin-gtk-viewer/meson.build Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin-gtk-viewer/meson.build Sat Sep 05 20:05:36 2020 -0500
@@ -23,7 +23,7 @@
output : 'gplugin-gtk-viewer.1',
- install_dir : join_paths(get_option('mandir'), 'man1'))
+ install_dir : get_option('mandir') / 'man1') --- a/gplugin-gtk/data/plugin-info.ui Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin-gtk/data/plugin-info.ui Sat Sep 05 20:05:36 2020 -0500
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.22.1 -->
+<!-- Generated with glade 3.22.2 --> <requires lib="gtk+" version="3.10"/>
<template class="GPluginGtkPluginInfo" parent="GtkBox">
@@ -208,7 +208,7 @@
<property name="yalign">0</property>
- <property name="expand">True</property>
+ <property name="expand">False</property> <property name="fill">True</property>
<property name="position">1</property>
@@ -240,7 +240,48 @@
- <object class="GtkLabel" id="dependencies">
+ <object class="GtkBox" id="dependencies_box"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">6</property> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <object class="GtkLabel" id="error_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Error</property> + <property name="xalign">0</property> + <property name="yalign">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + <object class="GtkLabel" id="error"> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
@@ -256,7 +297,7 @@
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">6</property>
+ <property name="position">7</property> @@ -517,7 +558,7 @@
<property name="expand">True</property>
<property name="fill">True</property>
- <property name="position">7</property>
+ <property name="position">8</property> @@ -535,6 +576,7 @@
<widget name="loader_label"/>
<widget name="internal_label"/>
<widget name="load_on_query_label"/>
+ <widget name="error_label"/> --- a/gplugin-gtk/gplugin-gtk-plugin-info.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin-gtk/gplugin-gtk-plugin-info.c Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -15,16 +15,17 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
#include <gplugin-gtk/gplugin-gtk-plugin-info.h>
-#include <gplugin/gplugin.h>
+#include <glib/gi18n-lib.h> * 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. @@ -46,6 +47,7 @@
@@ -53,7 +55,8 @@
- GtkWidget *dependencies;
+ GtkWidget *dependencies_box; @@ -71,7 +74,9 @@
-static GParamSpec *properties[N_PROPERTIES] = {NULL,};
+static GParamSpec *properties[N_PROPERTIES] = { G_DEFINE_TYPE(GPluginGtkPluginInfo, gplugin_gtk_plugin_info, GTK_TYPE_BOX);
@@ -79,8 +84,9 @@
*****************************************************************************/
-gplugin_gtk_plugin_info_expander_activate(GtkExpander *expander,
- G_GNUC_UNUSED gpointer data)
+gplugin_gtk_plugin_info_expander_activate( + G_GNUC_UNUSED gpointer data) if(gtk_expander_get_expanded(expander))
gtk_expander_set_label(expander, "More");
@@ -92,16 +98,17 @@
*****************************************************************************/
-_gplugin_gtk_plugin_info_refresh(GPluginGtkPluginInfo *info,
+_gplugin_gtk_plugin_info_refresh(GPluginGtkPluginInfo *info) GtkWidget *widget = NULL;
GList *children = NULL, *iter = NULL;
gchar *name = NULL, *version = NULL, *website = NULL;
gchar *summary = NULL, *description = NULL, *id = NULL, *abi_version = NULL;
+ gchar **dependencies = NULL; guint32 abi_version_uint;
gboolean loq = FALSE, internal = FALSE;
const gchar *filename = NULL;
@@ -112,12 +119,19 @@
gtk_widget_destroy(GTK_WIDGET(iter->data));
+ /* remove all the children from the dependencies box */ + children = gtk_container_get_children(GTK_CONTAINER(info->dependencies_box)); + for(iter = children; iter; iter = iter->next) + gtk_widget_destroy(GTK_WIDGET(iter->data)); /* now get the info if we can */
- if(GPLUGIN_IS_PLUGIN(plugin)) {
- GPluginPluginInfo *plugin_info = gplugin_plugin_get_info(plugin);
- GPluginLoader *plugin_loader = gplugin_plugin_get_loader(plugin);
+ if(GPLUGIN_IS_PLUGIN(info->plugin)) { + GPluginPluginInfo *plugin_info = gplugin_plugin_get_info(info->plugin); + GPluginLoader *plugin_loader = gplugin_plugin_get_loader(info->plugin); - filename = gplugin_plugin_get_filename(plugin);
+ filename = gplugin_plugin_get_filename(info->plugin); + error = gplugin_plugin_get_error(info->plugin); if(plugin_loader && GPLUGIN_IS_LOADER(plugin_loader)) {
const char *loader_name = G_OBJECT_TYPE_NAME(plugin_loader);
@@ -125,30 +139,37 @@
g_object_unref(G_OBJECT(plugin_loader));
- g_object_get(G_OBJECT(plugin_info),
- "abi_version", &abi_version_uint,
- "description", &description,
+ "abi_version", &abi_version_uint, + "description", &description, + "dependencies", &dependencies, /* fanagle the plugin name */
- markup = g_markup_printf_escaped("<span font_size=\"large\" "
- "font_weight=\"bold\">%s</span>",
- (name) ? name : "Unnamed");
+ markup = g_markup_printf_escaped( + "<span font_size=\"large\" " + "font_weight=\"bold\">%s</span>", + (name) ? name : "Unnamed"); /* fanagle the website */
- markup = g_markup_printf_escaped("<a href=\"%s\">%s</a>",
+ markup = g_markup_printf_escaped( + "<a href=\"%s\">%s</a>", @@ -163,10 +184,17 @@
gtk_label_set_text(GTK_LABEL(info->version), (version) ? version : "");
gtk_label_set_markup(GTK_LABEL(info->website), (website) ? website : "");
gtk_label_set_text(GTK_LABEL(info->summary), (summary) ? summary : "");
- gtk_label_set_text(GTK_LABEL(info->description), (description) ? description : "");
+ GTK_LABEL(info->description), + (description) ? description : ""); gtk_label_set_text(GTK_LABEL(info->id), (id) ? id : "");
+ GTK_LABEL(info->error), + (error) ? error->message : "(none)"); gtk_label_set_text(GTK_LABEL(info->filename), (filename) ? filename : "");
- gtk_label_set_text(GTK_LABEL(info->abi_version), (abi_version) ? abi_version : "");
+ GTK_LABEL(info->abi_version), + (abi_version) ? abi_version : ""); gtk_label_set_text(GTK_LABEL(info->loader), (loader) ? loader : "Unknown");
gtk_label_set_text(GTK_LABEL(info->internal), (internal) ? "Yes" : "No");
gtk_label_set_text(GTK_LABEL(info->load_on_query), (loq) ? "Yes" : "No");
@@ -177,6 +205,7 @@
@@ -186,19 +215,64 @@
widget = gtk_label_new(authors[i]);
gtk_widget_set_halign(widget, GTK_ALIGN_START);
gtk_widget_set_valign(widget, GTK_ALIGN_START);
- gtk_box_pack_start(GTK_BOX(info->authors_box), widget, TRUE, TRUE, 0);
+ GTK_BOX(info->authors_box), + /* set the dependencies */ + for(i = 0; dependencies[i]; i++) { + widget = gtk_label_new(dependencies[i]); + gtk_widget_set_halign(widget, GTK_ALIGN_START); + gtk_widget_set_valign(widget, GTK_ALIGN_START); + GTK_BOX(info->dependencies_box), + gtk_widget_show(widget); + widget = gtk_label_new(_("(none)")); + GTK_BOX(info->dependencies_box), + gtk_widget_show(widget); + g_strfreev(dependencies); +/****************************************************************************** + *****************************************************************************/ +gplugin_gtk_plugin_info_state_cb(GObject *obj, GParamSpec *pspec, gpointer data) + _gplugin_gtk_plugin_info_refresh(GPLUGIN_GTK_PLUGIN_INFO(data)); /******************************************************************************
*****************************************************************************/
-gplugin_gtk_plugin_info_set_property(GObject *obj, guint prop_id,
- const GValue *value, GParamSpec *pspec)
+gplugin_gtk_plugin_info_set_property( GPluginGtkPluginInfo *info = GPLUGIN_GTK_PLUGIN_INFO(obj);
@@ -213,15 +287,17 @@
-gplugin_gtk_plugin_info_get_property(GObject *obj, guint prop_id,
- GValue *value, GParamSpec *pspec)
+gplugin_gtk_plugin_info_get_property( GPluginGtkPluginInfo *info = GPLUGIN_GTK_PLUGIN_INFO(obj);
- g_value_set_object(value,
- gplugin_gtk_plugin_info_get_plugin(info));
+ g_value_set_object(value, gplugin_gtk_plugin_info_get_plugin(info)); G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
@@ -230,21 +306,30 @@
-gplugin_gtk_plugin_info_finalize(GObject *obj) {
+gplugin_gtk_plugin_info_finalize(GObject *obj) GPluginGtkPluginInfo *info = GPLUGIN_GTK_PLUGIN_INFO(obj);
+ if(info->signal_id != 0) { + g_signal_handler_disconnect(G_OBJECT(info->plugin), info->signal_id); g_clear_object(&info->plugin);
G_OBJECT_CLASS(gplugin_gtk_plugin_info_parent_class)->finalize(obj);
-gplugin_gtk_plugin_info_init(GPluginGtkPluginInfo *info) {
+gplugin_gtk_plugin_info_init(GPluginGtkPluginInfo *info) gtk_widget_init_template(GTK_WIDGET(info));
-gplugin_gtk_plugin_info_class_init(GPluginGtkPluginInfoClass *klass) {
+gplugin_gtk_plugin_info_class_init(GPluginGtkPluginInfoClass *klass) GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
GObjectClass *obj_class = G_OBJECT_CLASS(klass);
@@ -254,34 +339,82 @@
properties[PROP_PLUGIN] = g_param_spec_object(
"The GPluginPlugin who's info should be displayed",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT); gtk_widget_class_set_template_from_resource(
- "/org/bitbucket/gplugin/gplugin-gtk/plugin-info.ui"
+ "/org/bitbucket/gplugin/gplugin-gtk/plugin-info.ui"); - gtk_widget_class_bind_template_child(widget_class, GPluginGtkPluginInfo, name);
- gtk_widget_class_bind_template_child(widget_class, GPluginGtkPluginInfo, version);
- gtk_widget_class_bind_template_child(widget_class, GPluginGtkPluginInfo, authors_box);
- gtk_widget_class_bind_template_child(widget_class, GPluginGtkPluginInfo, website);
- gtk_widget_class_bind_template_child(widget_class, GPluginGtkPluginInfo, summary);
- gtk_widget_class_bind_template_child(widget_class, GPluginGtkPluginInfo, description);
- gtk_widget_class_bind_template_child(widget_class, GPluginGtkPluginInfo, dependencies);
- gtk_widget_class_bind_template_child(widget_class, GPluginGtkPluginInfo, expander);
- gtk_widget_class_bind_template_child(widget_class, GPluginGtkPluginInfo, id);
- gtk_widget_class_bind_template_child(widget_class, GPluginGtkPluginInfo, filename);
- gtk_widget_class_bind_template_child(widget_class, GPluginGtkPluginInfo, abi_version);
- gtk_widget_class_bind_template_child(widget_class, GPluginGtkPluginInfo, loader);
- gtk_widget_class_bind_template_child(widget_class, GPluginGtkPluginInfo, internal);
- gtk_widget_class_bind_template_child(widget_class, GPluginGtkPluginInfo, load_on_query);
+ gtk_widget_class_bind_template_child( + gtk_widget_class_bind_template_child( + gtk_widget_class_bind_template_child( + gtk_widget_class_bind_template_child( + gtk_widget_class_bind_template_child( + gtk_widget_class_bind_template_child( + gtk_widget_class_bind_template_child( + gtk_widget_class_bind_template_child( - gtk_widget_class_bind_template_callback(widget_class, gplugin_gtk_plugin_info_expander_activate);
+ gtk_widget_class_bind_template_child( + gtk_widget_class_bind_template_child( + gtk_widget_class_bind_template_child( + gtk_widget_class_bind_template_child( + gtk_widget_class_bind_template_child( + gtk_widget_class_bind_template_child( + gtk_widget_class_bind_template_child( + gtk_widget_class_bind_template_callback( + gplugin_gtk_plugin_info_expander_activate); /******************************************************************************
@@ -297,42 +430,64 @@
* Returns: (transfer full): The new #GPluginGtkView widget.
-gplugin_gtk_plugin_info_new(void) {
+gplugin_gtk_plugin_info_new(void) return GTK_WIDGET(g_object_new(GPLUGIN_GTK_TYPE_PLUGIN_INFO, NULL));
* 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,
+gplugin_gtk_plugin_info_set_plugin( + GPluginGtkPluginInfo *info, g_return_if_fail(GPLUGIN_GTK_IS_PLUGIN_INFO(info));
+ if(info->signal_id != 0 && GPLUGIN_IS_PLUGIN(info->plugin)) { + g_signal_handler_disconnect(info->plugin, info->signal_id); if(g_set_object(&info->plugin, plugin)) {
- _gplugin_gtk_plugin_info_refresh(info, plugin);
+ _gplugin_gtk_plugin_info_refresh(info); + /* Connect a signal to refresh when the plugin's state changes. We + * can't use g_signal_connect_object because the plugin object never + * gets destroyed, as the manager and the loader both keep a reference + * to it and the GPluginGtkPluginInfo widget is reused for all plugins + * so that all means that we just have to manage the callback + info->signal_id = g_signal_connect( + G_CALLBACK(gplugin_gtk_plugin_info_state_cb), * 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) {
+gplugin_gtk_plugin_info_get_plugin(GPluginGtkPluginInfo *info) g_return_val_if_fail(GPLUGIN_GTK_IS_PLUGIN_INFO(info), NULL);
- return (info->plugin) ? GPLUGIN_PLUGIN(g_object_ref(G_OBJECT(info->plugin))) : NULL;
+ return (info->plugin) ? GPLUGIN_PLUGIN(g_object_ref(G_OBJECT(info->plugin))) --- a/gplugin-gtk/gplugin-gtk-plugin-info.h Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin-gtk/gplugin-gtk-plugin-info.h Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -15,7 +15,8 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#if !defined(GPLUGIN_GTK_GLOBAL_HEADER_INSIDE) && !defined(GPLUGIN_GTK_COMPILATION)
+#if !defined(GPLUGIN_GTK_GLOBAL_HEADER_INSIDE) && \ + !defined(GPLUGIN_GTK_COMPILATION) #error "only <gplugin/gplugin-gtk.h> may be included directly"
@@ -32,14 +33,20 @@
#define GPLUGIN_GTK_TYPE_PLUGIN_INFO (gplugin_gtk_plugin_info_get_type())
-G_DECLARE_FINAL_TYPE(GPluginGtkPluginInfo, gplugin_gtk_plugin_info, GPLUGIN_GTK, PLUGIN_INFO, GtkBox)
+ gplugin_gtk_plugin_info, GtkWidget *gplugin_gtk_plugin_info_new(void);
-void gplugin_gtk_plugin_info_set_plugin(GPluginGtkPluginInfo *info, GPluginPlugin *plugin);
+void gplugin_gtk_plugin_info_set_plugin( + GPluginGtkPluginInfo *info, + GPluginPlugin *plugin); GPluginPlugin *gplugin_gtk_plugin_info_get_plugin(GPluginGtkPluginInfo *info);
#endif /* GPLUGIN_GTK_PLUGIN_INFO_H */
--- a/gplugin-gtk/gplugin-gtk-store.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin-gtk/gplugin-gtk-store.c Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -15,16 +15,15 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#include <gplugin/gplugin.h>
#include <gplugin-gtk/gplugin-gtk-store.h>
* 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. @@ -35,6 +34,9 @@
* GPluginGtkStoreColumns:
+ * @GPLUGIN_GTK_STORE_ENABLED_COLUMN: The disabled column. This is used when a + * plugin is in a state that can't be + * changed. So the row should be disabled. * @GPLUGIN_GTK_STORE_LOADED_COLUMN: The loaded column.
* @GPLUGIN_GTK_STORE_PLUGIN_COLUMN: The plugin column.
* @GPLUGIN_GTK_STORE_MARKUP_COLUMN: The markup column.
@@ -59,6 +61,7 @@
*****************************************************************************/
static const GType column_types[] = {
@@ -69,69 +72,106 @@
*****************************************************************************/
-gplugin_gtk_store_add_plugin(GPluginGtkStore *store, GPluginPlugin *plugin) {
+gplugin_gtk_store_add_plugin(GPluginGtkStore *store, GPluginPlugin *plugin) GPluginPluginInfo *info = gplugin_plugin_get_info(plugin);
GPluginPluginState state = gplugin_plugin_get_state(plugin);
GString *str = g_string_new("");
gchar *name = NULL, *summary = NULL;
+ gboolean loaded = FALSE, enabled = TRUE; - g_object_get(G_OBJECT(info),
- g_string_append_printf(str, "<b>%s</b>\n",
- (name) ? name : "<i>Unnamed</i>");
- g_string_append_printf(str, "%s",
- (summary) ? summary : "<i>No Summary</i>");
+ g_string_append_printf( + (name) ? name : "<i>Unnamed</i>"); + g_string_append_printf( + (summary) ? summary : "<i>No Summary</i>"); + loaded = (state == GPLUGIN_PLUGIN_STATE_LOADED); + if(state == GPLUGIN_PLUGIN_STATE_UNLOAD_FAILED) { gtk_list_store_append(GTK_LIST_STORE(store), &iter);
- gtk_list_store_set(GTK_LIST_STORE(store), &iter,
- GPLUGIN_GTK_STORE_LOADED_COLUMN, state == GPLUGIN_PLUGIN_STATE_LOADED,
- GPLUGIN_GTK_STORE_PLUGIN_COLUMN, g_object_ref(plugin),
- GPLUGIN_GTK_STORE_MARKUP_COLUMN, str->str,
+ GPLUGIN_GTK_STORE_LOADED_COLUMN, + GPLUGIN_GTK_STORE_ENABLED_COLUMN, + GPLUGIN_GTK_STORE_PLUGIN_COLUMN, + GPLUGIN_GTK_STORE_MARKUP_COLUMN, g_string_free(str, TRUE);
g_object_unref(G_OBJECT(info));
-gplugin_gtk_store_add_plugin_by_id(GPluginGtkStore *store, const gchar * id) {
+gplugin_gtk_store_add_plugin_by_id(GPluginGtkStore *store, const gchar *id) GSList *plugins = NULL, *l = NULL;
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); -gplugin_gtk_store_update_plugin_state_cb(GtkTreeModel *model, GtkTreePath *path,
- GtkTreeIter *iter, gpointer data)
+gplugin_gtk_store_update_plugin_state_cb( GPluginPlugin *plugin_a = GPLUGIN_PLUGIN(data);
GPluginPlugin *plugin_b = NULL;
- GPLUGIN_GTK_STORE_PLUGIN_COLUMN, &plugin_b,
+ GPLUGIN_GTK_STORE_PLUGIN_COLUMN, if(plugin_a == plugin_b) {
- gboolean loaded = gplugin_plugin_get_state(plugin_a) == GPLUGIN_PLUGIN_STATE_LOADED;
+ GPluginPluginState state = gplugin_plugin_get_state(plugin_a); + gboolean loaded = (state == GPLUGIN_PLUGIN_STATE_LOADED); + gboolean enabled = TRUE; + if(state == GPLUGIN_PLUGIN_STATE_UNLOAD_FAILED) { - GTK_LIST_STORE(model), iter,
- GPLUGIN_GTK_STORE_LOADED_COLUMN, loaded,
+ GPLUGIN_GTK_STORE_LOADED_COLUMN, + GPLUGIN_GTK_STORE_ENABLED_COLUMN, /* tell gplugin_gtk_store_update_plugin_state that we're done */
@@ -143,29 +183,42 @@
-gplugin_gtk_store_update_plugin_state(GPluginGtkStore *store,
+gplugin_gtk_store_update_plugin_state( + GPluginGtkStore *store, gplugin_gtk_store_update_plugin_state_cb,
/******************************************************************************
*****************************************************************************/
-gplugin_gtk_store_plugin_loaded_cb(GObject *manager, GPluginPlugin *plugin,
+gplugin_gtk_store_plugin_loaded_cb( gplugin_gtk_store_update_plugin_state(GPLUGIN_GTK_STORE(data), plugin);
-gplugin_gtk_store_plugin_unloaded_cb(GObject *manager, GPluginPlugin *plugin,
+gplugin_gtk_store_plugin_unloaded_cb( + gplugin_gtk_store_update_plugin_state(GPLUGIN_GTK_STORE(data), plugin); +gplugin_gtk_store_plugin_unload_failed_cb( + G_GNUC_UNUSED GObject *manager, gplugin_gtk_store_update_plugin_state(GPLUGIN_GTK_STORE(data), plugin);
@@ -174,7 +227,8 @@
*****************************************************************************/
-gplugin_gtk_store_constructed(GObject *obj) {
+gplugin_gtk_store_constructed(GObject *obj) @@ -182,33 +236,49 @@
ids = gplugin_manager_list_plugins();
for(l = ids; l; l = l->next)
- gplugin_gtk_store_add_plugin_by_id(GPLUGIN_GTK_STORE(obj),
- (const gchar *)l->data);
+ gplugin_gtk_store_add_plugin_by_id( + GPLUGIN_GTK_STORE(obj), + (const gchar *)l->data); manager = gplugin_manager_get_instance();
- g_signal_connect(manager, "loaded-plugin",
- G_CALLBACK(gplugin_gtk_store_plugin_loaded_cb), obj);
- g_signal_connect(manager, "unloaded-plugin",
- G_CALLBACK(gplugin_gtk_store_plugin_unloaded_cb), obj);
+ G_CALLBACK(gplugin_gtk_store_plugin_loaded_cb), + G_CALLBACK(gplugin_gtk_store_plugin_unloaded_cb), + "unload-plugin-failed", + G_CALLBACK(gplugin_gtk_store_plugin_unload_failed_cb), -gplugin_gtk_store_dispose(GObject *obj) {
+gplugin_gtk_store_dispose(GObject *obj) G_OBJECT_CLASS(gplugin_gtk_store_parent_class)->dispose(obj);
-gplugin_gtk_store_init(GPluginGtkStore *store) {
- GType *types = (GType *)gplugin_gtk_get_store_column_types();
+gplugin_gtk_store_init(GPluginGtkStore *store) + GType *types = (GType *)gplugin_gtk_store_get_column_types(); - gtk_list_store_set_column_types(GTK_LIST_STORE(store),
- GPLUGIN_GTK_STORE_N_COLUMNS,
+ gtk_list_store_set_column_types( + GPLUGIN_GTK_STORE_N_COLUMNS, -gplugin_gtk_store_class_init(GPluginGtkStoreClass *klass) {
+gplugin_gtk_store_class_init(GPluginGtkStoreClass *klass) GObjectClass *obj_class = G_OBJECT_CLASS(klass);
obj_class->constructed = gplugin_gtk_store_constructed;
@@ -222,26 +292,27 @@
- * 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) {
+gplugin_gtk_store_new(void) return GPLUGIN_GTK_STORE(g_object_new(GPLUGIN_GTK_TYPE_STORE, NULL));
- * 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 Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin-gtk/gplugin-gtk-store.h Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -15,7 +15,8 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#if !defined(GPLUGIN_GTK_GLOBAL_HEADER_INSIDE) && !defined(GPLUGIN_GTK_COMPILATION)
+#if !defined(GPLUGIN_GTK_GLOBAL_HEADER_INSIDE) && \ + !defined(GPLUGIN_GTK_COMPILATION) #error "only <gplugin/gplugin-gtk.h> may be included directly"
@@ -30,9 +31,15 @@
#define GPLUGIN_GTK_TYPE_STORE (gplugin_gtk_store_get_type())
-G_DECLARE_FINAL_TYPE(GPluginGtkStore, gplugin_gtk_store, GPLUGIN_GTK, STORE, GtkListStore)
+ GPLUGIN_GTK_STORE_ENABLED_COLUMN, GPLUGIN_GTK_STORE_LOADED_COLUMN,
GPLUGIN_GTK_STORE_PLUGIN_COLUMN,
GPLUGIN_GTK_STORE_MARKUP_COLUMN,
@@ -43,9 +50,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 Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin-gtk/gplugin-gtk-view.c Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -15,17 +15,16 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#include <gplugin-gtk/gplugin-gtk-view.h>
#include <gplugin-gtk/gplugin-gtk-store.h>
-#include <gplugin/gplugin.h>
+#include <gplugin-gtk/gplugin-gtk-view.h> * 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. @@ -58,15 +57,18 @@
-static GParamSpec *properties[N_PROPERTIES] = {NULL,};
+static GParamSpec *properties[N_PROPERTIES] = { /******************************************************************************
*****************************************************************************/
-gplugin_gtk_view_plugin_toggled_cb(GtkCellRendererToggle *rend,
+gplugin_gtk_view_plugin_toggled_cb( + GtkCellRendererToggle *rend, GPluginGtkView *view = GPLUGIN_GTK_VIEW(data);
GPluginPlugin *plugin = NULL;
@@ -84,9 +86,9 @@
- GPLUGIN_GTK_STORE_PLUGIN_COLUMN, &plugin,
+ GPLUGIN_GTK_STORE_PLUGIN_COLUMN, if(!GPLUGIN_IS_PLUGIN(plugin)) {
@@ -124,15 +126,19 @@
G_DEFINE_TYPE(GPluginGtkView, gplugin_gtk_view, GTK_TYPE_TREE_VIEW);
-gplugin_gtk_view_set_property(GObject *obj, guint prop_id, const GValue *value,
+gplugin_gtk_view_set_property( GPluginGtkView *view = GPLUGIN_GTK_VIEW(obj);
- gplugin_gtk_view_set_show_internal(view,
- g_value_get_boolean(value));
+ gplugin_gtk_view_set_show_internal( + g_value_get_boolean(value)); G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
@@ -141,15 +147,19 @@
-gplugin_gtk_view_get_property(GObject *obj, guint prop_id, GValue *value,
+gplugin_gtk_view_get_property( GPluginGtkView *view = GPLUGIN_GTK_VIEW(obj);
- g_value_set_boolean(value,
- gplugin_gtk_view_get_show_internal(view));
+ gplugin_gtk_view_get_show_internal(view)); G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
@@ -158,17 +168,20 @@
-gplugin_gtk_view_constructed(GObject *obj) {
+gplugin_gtk_view_constructed(GObject *obj) G_OBJECT_CLASS(gplugin_gtk_view_parent_class)->constructed(obj);
-gplugin_gtk_view_dispose(GObject *obj) {
+gplugin_gtk_view_dispose(GObject *obj) G_OBJECT_CLASS(gplugin_gtk_view_parent_class)->dispose(obj);
-gplugin_gtk_view_init(GPluginGtkView *view) {
+gplugin_gtk_view_init(GPluginGtkView *view) GtkTreeViewColumn *col = NULL;
GtkCellRenderer *rend = NULL;
@@ -179,12 +192,21 @@
rend = gtk_cell_renderer_toggle_new();
gtk_tree_view_column_pack_start(col, rend, FALSE);
- g_signal_connect(G_OBJECT(rend), "toggled",
- G_CALLBACK(gplugin_gtk_view_plugin_toggled_cb), view);
+ G_CALLBACK(gplugin_gtk_view_plugin_toggled_cb), gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
- gtk_tree_view_column_add_attribute(col, rend, "active",
- GPLUGIN_GTK_STORE_LOADED_COLUMN);
+ gtk_tree_view_column_set_attributes( + GPLUGIN_GTK_STORE_LOADED_COLUMN, + GPLUGIN_GTK_STORE_ENABLED_COLUMN, /* create the markup column */
col = gtk_tree_view_column_new();
@@ -195,12 +217,19 @@
gtk_tree_view_column_pack_start(col, rend, TRUE);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
- gtk_tree_view_column_add_attribute(col, rend, "markup",
- GPLUGIN_GTK_STORE_MARKUP_COLUMN);
+ gtk_tree_view_column_set_attributes( + GPLUGIN_GTK_STORE_MARKUP_COLUMN, + GPLUGIN_GTK_STORE_ENABLED_COLUMN, -gplugin_gtk_view_class_init(GPluginGtkViewClass *klass) {
+gplugin_gtk_view_class_init(GPluginGtkViewClass *klass) GObjectClass *obj_class = G_OBJECT_CLASS(klass);
obj_class->get_property = gplugin_gtk_view_get_property;
@@ -216,11 +245,11 @@
* Whether or not to show internal plugins.
properties[PROP_SHOW_INTERNAL] = g_param_spec_boolean(
- "show-internal", "show-internal",
"Whether or not to show internal plugins",
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
@@ -232,33 +261,36 @@
- * Creates a new GPluginGtkView.
+ * Creates a new #GPluginGtkView. * Returns: (transfer full): The new view.
-gplugin_gtk_view_new(void) {
+gplugin_gtk_view_new(void) GPluginGtkStore *store = gplugin_gtk_store_new();
- ret = g_object_new(GPLUGIN_GTK_TYPE_VIEW,
- "model", GTK_TREE_MODEL(store),
+ "model", GTK_TREE_MODEL(store), * 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
-gplugin_gtk_view_set_show_internal(GPluginGtkView *view,
- gboolean show_internal)
+gplugin_gtk_view_set_show_internal(GPluginGtkView *view, gboolean show_internal) g_return_if_fail(GPLUGIN_GTK_IS_VIEW(view));
@@ -269,14 +301,14 @@
* gplugin_gtk_view_get_show_internal:
- * @view: The #GPluginGtkView instance
+ * @view: The #GPluginGtkView instance. * Returns whether or not @view is showing internal plugins.
-gplugin_gtk_view_get_show_internal(GPluginGtkView *view) {
+gplugin_gtk_view_get_show_internal(GPluginGtkView *view) g_return_val_if_fail(GPLUGIN_GTK_IS_VIEW(view), FALSE);
return view->show_internal;
--- a/gplugin-gtk/gplugin-gtk-view.h Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin-gtk/gplugin-gtk-view.h Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -15,7 +15,8 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#if !defined(GPLUGIN_GTK_GLOBAL_HEADER_INSIDE) && !defined(GPLUGIN_GTK_COMPILATION)
+#if !defined(GPLUGIN_GTK_GLOBAL_HEADER_INSIDE) && \ + !defined(GPLUGIN_GTK_COMPILATION) #error "only <gplugin/gplugin-gtk.h> may be included directly"
@@ -30,14 +31,20 @@
#define GPLUGIN_GTK_TYPE_VIEW (gplugin_gtk_view_get_type())
-G_DECLARE_FINAL_TYPE(GPluginGtkView, gplugin_gtk_view, GPLUGIN_GTK, VIEW, GtkTreeView)
GtkWidget *gplugin_gtk_view_new(void);
-void gplugin_gtk_view_set_show_internal(GPluginGtkView *view, gboolean show_internal);
+void gplugin_gtk_view_set_show_internal( + gboolean show_internal); gboolean gplugin_gtk_view_get_show_internal(GPluginGtkView *view);
#endif /* GPLUGIN_GTK_VIEW_H */
--- a/gplugin-gtk/gplugin-gtk.h.in Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin-gtk/gplugin-gtk.h.in Sat Sep 05 20:05:36 2020 -0500
@@ -1,18 +1,18 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> - * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * 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/>. @@ -26,4 +26,3 @@
#undef GPLUGIN_GTK_GLOBAL_HEADER_INSIDE
#endif /* GPLUGIN_GTK_H */
--- a/gplugin-gtk/gplugin-gtk.xml.in Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin-gtk/gplugin-gtk.xml.in Sat Sep 05 20:05:36 2020 -0500
@@ -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 Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin-gtk/meson.build Sat Sep 05 20:05:36 2020 -0500
@@ -49,14 +49,14 @@
output : 'gplugin-gtk.h',
- install_dir : join_paths(get_option('includedir'), 'gplugin-1.0'))
+ install_dir : get_option('includedir') / 'gplugin-1.0') gplugin_gtk_xml = configure_file(
input : 'gplugin-gtk.xml.in',
output: 'gplugin-gtk.xml',
configuration : version_conf,
- install_dir : join_paths(get_option('datadir'), 'glade', 'catalogs'),
+ install_dir : get_option('datadir') / 'glade' / 'catalogs', ###############################################################################
@@ -96,13 +96,13 @@
- description : 'Gtk+ widgets for GPlugin',
- version : meson.project_version(),
+ description : 'Gtk widgets for GPlugin', filebase : 'gplugin-gtk',
- libraries : gplugin_gtk,
- requires : ['glib-2.0', 'gobject-2.0', 'gmodule-2.0', 'gplugin'],
+ requires : [GLIB, GOBJECT, GMODULE], @@ -111,7 +111,7 @@
###############################################################################
###############################################################################
-if get_option('gobject-introspection')
+if get_option('introspection') gplugin_gtk_gir = gnome.generate_gir(
sources : GPLUGIN_GTK_SOURCES + GPLUGIN_GTK_HEADERS +
@@ -120,7 +120,7 @@
includes : [gplugin_gir[0], 'Gtk-3.0'],
namespace : 'GPluginGtk',
symbol_prefix : 'gplugin_gtk',
- nsversion : '@0@.0'.format(GPLUGIN_MAJOR_VERSION),
export_packages: ['gplugin-gtk'],
extra_args : ['--quiet', '-DGPLUGIN_GTK_COMPILATION'])
--- a/gplugin-gtk/reference/gplugin-gtk-docs.xml Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin-gtk/reference/gplugin-gtk-docs.xml Sat Sep 05 20:05:36 2020 -0500
@@ -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 Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin-gtk/reference/meson.build Sat Sep 05 20:05:36 2020 -0500
@@ -15,7 +15,7 @@
- '--extra-dir', join_paths(meson.current_build_dir(), '../../gplugin/reference')
+ '--extra-dir=' + (meson.build_root() / '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,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin-query/gplugin-query.c Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,368 @@
+ * 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/>. +/****************************************************************************** + *****************************************************************************/ +static gint verbosity = 0; +static gboolean show_internal = FALSE; +static gboolean output_paths = FALSE; +static gboolean exit_early = FALSE; +/****************************************************************************** + *****************************************************************************/ + G_GNUC_UNUSED const gchar *n, + G_GNUC_UNUSED const gchar *v, + G_GNUC_UNUSED gpointer d, + G_GNUC_UNUSED GError **e) + G_GNUC_UNUSED const gchar *n, + G_GNUC_UNUSED const gchar *v, + G_GNUC_UNUSED gpointer d, + G_GNUC_UNUSED GError **e) + G_GNUC_UNUSED const gchar *n, + G_GNUC_UNUSED const gchar *v, + G_GNUC_UNUSED gpointer d, + G_GNUC_UNUSED GError **e) + G_GNUC_UNUSED const gchar *n, + G_GNUC_UNUSED const gchar *v, + G_GNUC_UNUSED gpointer d, + G_GNUC_UNUSED GError **e) + printf("gplugin-query %s\n", GPLUGIN_VERSION); + G_GNUC_UNUSED const gchar *n, + G_GNUC_UNUSED const gchar *v, + G_GNUC_UNUSED gpointer d, + G_GNUC_UNUSED GError **e) +output_plugin(const gchar *id) + GSList *plugins = NULL, *l = NULL; + gboolean first = TRUE, header_output = FALSE; +#define MAIN_FORMAT_NEL " " FORMAT ": " +#define MAIN_FORMAT MAIN_FORMAT_NEL "%s\n" +#define STR_OR_EMPTY(str) ((str) ? (str) : "") + plugins = gplugin_manager_find_plugins(id); + printf("%s not found\n", id); + for(l = plugins; l; l = l->next) { + GPluginPlugin *plugin = GPLUGIN_PLUGIN(l->data); + GPluginPluginInfo *info = gplugin_plugin_get_info(plugin); + gboolean internal, loq; + gchar *license_id, *license_text, *license_url; + gchar *icon_name, *summary, *description, *category, *website; + gchar **authors, **dependencies; + internal = gplugin_plugin_info_get_internal(info); + if(!show_internal && internal) + "abi-version", &abi_version, + "license-id", &license_id, + "license-text", &license_text, + "license-url", &license_url, + "icon-name", &icon_name, + "description", &description, + "dependencies", &dependencies, + printf(MAIN_FORMAT, "name", STR_OR_EMPTY(name)); + printf(MAIN_FORMAT, "category", STR_OR_EMPTY(category)); + printf(MAIN_FORMAT, "version", STR_OR_EMPTY(version)); + printf(MAIN_FORMAT, "license", STR_OR_EMPTY(license_id)); + printf(MAIN_FORMAT, "license url", STR_OR_EMPTY(license_url)); + printf(MAIN_FORMAT, "summary", STR_OR_EMPTY(summary)); + printf(MAIN_FORMAT_NEL, "authors"); + for(i = 0; authors[i]; i++) { + printf("%s\n", STR_OR_EMPTY(authors[i])); + printf(MAIN_FORMAT, "website", STR_OR_EMPTY(website)); + STR_OR_EMPTY(gplugin_plugin_get_filename(plugin))); + GPluginLoader *loader = gplugin_plugin_get_loader(plugin); + printf(MAIN_FORMAT_NEL "%08x\n", "abi version", abi_version); + printf(MAIN_FORMAT, "internal", (internal) ? "yes" : "no"); + printf(MAIN_FORMAT, "load on query", (loq) ? "yes" : "no"); + printf(MAIN_FORMAT, "loader", G_OBJECT_TYPE_NAME(loader)); + g_object_unref(G_OBJECT(loader)); + printf(MAIN_FORMAT, "description", STR_OR_EMPTY(description)); + printf(MAIN_FORMAT_NEL, "dependencies"); + for(i = 0; dependencies[i]; i++) { + printf("%s\n", STR_OR_EMPTY(dependencies[i])); + g_strfreev(dependencies); + g_object_unref(G_OBJECT(info)); + g_slist_free_full(plugins, g_object_unref); +output_plugins(GList *plugins) + gboolean ret = TRUE, first = TRUE; + for(l = plugins; l; l = l->next) { + if(!output_plugin(l->data)) +/****************************************************************************** + *****************************************************************************/ +static GOptionEntry entries[] = { + "internal", 'i', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, + internal_cb, N_("Show internal plugins"), + "verbose", 'v', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, + verbosity_cb, N_("Increase verbosity"), + "full-verbose", 'V', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, + full_verbosity_cb, N_("Increase verbosity to eleven"), + "version", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, + version_cb, N_("Display the version and exit"), + "list", 'L', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, + list_cb, N_("Display all search paths and exit"), + NULL, 0, 0, 0, NULL, NULL, NULL, +main(gint argc, gchar **argv) + GOptionContext *ctx = NULL; + GOptionGroup *group = NULL; + ctx = g_option_context_new("PLUGIN-ID..."); + g_option_context_set_summary(ctx, _("Query installed plugins")); + g_option_context_set_translation_domain(ctx, GETTEXT_PACKAGE); + g_option_context_add_main_entries(ctx, entries, NULL); + group = gplugin_get_option_group(); + g_option_context_add_group(ctx, group); + g_option_context_parse(ctx, &argc, &argv, &error); + g_option_context_free(ctx); + fprintf(stderr, "%s\n", error->message); + for(path = gplugin_manager_get_paths(); path; path = path->next) { + printf("%s\n", (gchar *)path->data); + gplugin_manager_refresh(); + /* check if the user gave us atleast one plugin, and output them */ + GQueue *plugins = g_queue_new(); + for(i = 1; i < argc; i++) { + if(strlen(argv[i]) == 0) + g_queue_push_tail(plugins, argv[i]); + if(!output_plugins(plugins->head)) + GList *plugins = gplugin_manager_list_plugins(); + if(!output_plugins(plugins)) --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin-query/meson.build Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,17 @@
+gplugin_query = executable('gplugin-query', + dependencies : [gplugin_dep, GLIB, GOBJECT], +if get_option('help2man') + custom_target('gplugin-query.1', + '--name=Query installed plugins', '--section=1', + '--help-option=--help-all', '--no-info', + '--output', '@OUTPUT@', + output : 'gplugin-query.1', + install_dir : get_option('mandir') / 'man1') --- a/gplugin-version.sh.in Thu Nov 07 23:09:55 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-export GPLUGIN_VERSION=@GPLUGIN_MAJOR_VERSION@.@GPLUGIN_MINOR_VERSION@.@GPLUGIN_MICRO_VERSION@
--- a/gplugin/gplugin-core.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin-core.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,20 +16,19 @@
+#include <glib/gi18n-lib.h> #include <gplugin/gplugin-core.h>
+#include <gplugin/gplugin-plugin.h> #include <gplugin/gplugin-private.h>
-#include <gplugin/gplugin-plugin.h>
- * @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. /******************************************************************************
@@ -60,7 +59,8 @@
bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
@@ -73,7 +73,7 @@
* Uninitializes the GPlugin library
gplugin_manager_private_uninit();
--- a/gplugin/gplugin-core.h Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin-core.h Sat Sep 05 20:05:36 2020 -0500
@@ -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 Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin-file-tree.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,13 +17,14 @@
#include "gplugin-file-tree.h"
+#include <glib/gi18n-lib.h> /******************************************************************************
*****************************************************************************/
-gplugin_file_tree_entry_new(const gchar *filename) {
+gplugin_file_tree_entry_new(const gchar *filename) GPluginFileTreeEntry *entry = NULL;
g_return_val_if_fail(filename, NULL);
@@ -35,8 +36,8 @@
/* we have to use e->filename, because g_utf8_strrchr returns a pointer
* in the string given too it, and not a new copy.
- entry->extension = g_utf8_strrchr(entry->filename, -1,
+ g_utf8_strrchr(entry->filename, -1, g_utf8_get_char(".")); /* if we have an extension, we need to iterate past the . */
@@ -46,7 +47,8 @@
-gplugin_file_tree_entry_free(GPluginFileTreeEntry *entry) {
+gplugin_file_tree_entry_free(GPluginFileTreeEntry *entry) @@ -60,10 +62,11 @@
*****************************************************************************/
-gplugin_file_tree_free_helper(GNode *n, G_GNUC_UNUSED gpointer d) {
+gplugin_file_tree_free_helper(GNode *n, G_GNUC_UNUSED gpointer d) GPluginFileTreeEntry *e = n->data;
gplugin_file_tree_entry_free(e);
@@ -81,7 +84,8 @@
* GPluginFileTreeEntry instance for the files in that directory.
-gplugin_file_tree_new(GList *paths) {
+gplugin_file_tree_new(GList *paths) @@ -97,9 +101,10 @@
dir = g_dir_open(path, 0, &error);
- g_debug(_("Failed to open %s: %s"),
- (error->message) ? error->message : _("unknown failure"));
+ _("Failed to open %s: %s"), + (error->message) ? error->message : _("unknown failure")); @@ -115,11 +120,16 @@
/* now run through all of the files and add then to the dir node */
while((filename = g_dir_read_name(dir)) != NULL) {
+ gchar *test_filename = g_build_filename(path, filename, NULL); - entry = gplugin_file_tree_entry_new(filename);
- file = g_node_new(entry);
+ if(g_file_test(test_filename, G_FILE_TEST_IS_REGULAR)) { + entry = gplugin_file_tree_entry_new(filename); + file = g_node_new(entry); - g_node_prepend(node_dir, file);
+ g_node_prepend(node_dir, file); @@ -136,13 +146,17 @@
* Free's a previously created file tree.
-gplugin_file_tree_free(GNode *root) {
+gplugin_file_tree_free(GNode *root) - g_node_traverse(root, G_POST_ORDER,
- G_TRAVERSE_LEAVES | G_TRAVERSE_NON_LEAVES,
- -1, gplugin_file_tree_free_helper, NULL);
+ G_TRAVERSE_LEAVES | G_TRAVERSE_NON_LEAVES, + gplugin_file_tree_free_helper,
--- a/gplugin/gplugin-file-tree.h Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin-file-tree.h Sat Sep 05 20:05:36 2020 -0500
@@ -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 Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin-loader-tests.c Sat Sep 05 20:05:36 2020 -0500
@@ -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 @@
@@ -35,13 +34,14 @@
*****************************************************************************/
-gplugin_test_loader_full(gconstpointer d) {
+gplugin_test_loader_full(gconstpointer d) GPluginPlugin *plugin = NULL;
GPluginPluginInfo *info = NULL;
- const gchar * const r_authors[] = { "author1", NULL };
+ const gchar *const r_authors[] = {"author1", NULL}; id = g_strdup_printf("gplugin/%s-basic-plugin", (const gchar *)d);
@@ -54,8 +54,7 @@
g_assert_cmpstr(gplugin_plugin_info_get_id(info), ==, id);
- g_assert_cmpuint(gplugin_plugin_info_get_abi_version(info), ==,
+ g_assert_cmpuint(gplugin_plugin_info_get_abi_version(info), ==, 0x01020304); g_assert_cmpstr(gplugin_plugin_info_get_name(info), ==, "basic plugin");
authors = (gchar **)gplugin_plugin_info_get_authors(info);
@@ -66,30 +65,39 @@
g_assert_cmpstr(gplugin_plugin_info_get_version(info), ==, "version");
g_assert_cmpstr(gplugin_plugin_info_get_license_id(info), ==, "license");
g_assert_cmpstr(gplugin_plugin_info_get_summary(info), ==, "summary");
- g_assert_cmpstr(gplugin_plugin_info_get_description(info), ==,
+ gplugin_plugin_info_get_description(info), g_assert_cmpstr(gplugin_plugin_info_get_website(info), ==, "website");
g_object_unref(G_OBJECT(info));
- g_assert_cmpint(gplugin_plugin_get_state(plugin), ==,
- GPLUGIN_PLUGIN_STATE_QUERIED);
+ gplugin_plugin_get_state(plugin), + GPLUGIN_PLUGIN_STATE_QUERIED); gplugin_manager_load_plugin(plugin, &error);
g_assert_no_error(error);
- g_assert_cmpint(gplugin_plugin_get_state(plugin), ==,
- GPLUGIN_PLUGIN_STATE_LOADED);
+ gplugin_plugin_get_state(plugin), + GPLUGIN_PLUGIN_STATE_LOADED); gplugin_manager_unload_plugin(plugin, &error);
g_assert_no_error(error);
- g_assert_cmpint(gplugin_plugin_get_state(plugin), ==,
- GPLUGIN_PLUGIN_STATE_QUERIED);
+ gplugin_plugin_get_state(plugin), + GPLUGIN_PLUGIN_STATE_QUERIED); g_object_unref(G_OBJECT(plugin));
-gplugin_test_loader_load_failed(gconstpointer d) {
+gplugin_test_loader_load_failed(gconstpointer d) GPluginPlugin *plugin = NULL;
@@ -102,15 +110,26 @@
ret = gplugin_manager_load_plugin(plugin, &error);
g_assert_error(error, GPLUGIN_DOMAIN, 0);
- g_assert_cmpint(gplugin_plugin_get_state(plugin), ==,
- GPLUGIN_PLUGIN_STATE_LOAD_FAILED);
+ gplugin_plugin_get_state(plugin), + GPLUGIN_PLUGIN_STATE_LOAD_FAILED); + /* make sure that the plugin's error was set */ + error = gplugin_plugin_get_error(plugin); + g_assert_error(error, GPLUGIN_DOMAIN, 0); g_object_unref(G_OBJECT(plugin));
-gplugin_test_loader_load_exception(gconstpointer d) {
+gplugin_test_loader_load_exception(gconstpointer d) GPluginPlugin *plugin = NULL;
@@ -123,15 +142,26 @@
ret = gplugin_manager_load_plugin(plugin, &error);
g_assert_error(error, GPLUGIN_DOMAIN, 0);
- g_assert_cmpint(gplugin_plugin_get_state(plugin), ==,
- GPLUGIN_PLUGIN_STATE_LOAD_FAILED);
+ gplugin_plugin_get_state(plugin), + GPLUGIN_PLUGIN_STATE_LOAD_FAILED); + /* make sure that the plugin's error was set */ + error = gplugin_plugin_get_error(plugin); + g_assert_error(error, GPLUGIN_DOMAIN, 0); g_object_unref(G_OBJECT(plugin));
-gplugin_test_loader_unload_failed(gconstpointer d) {
+gplugin_test_loader_unload_failed(gconstpointer d) GPluginPlugin *plugin = NULL;
@@ -145,25 +175,38 @@
ret = gplugin_manager_load_plugin(plugin, &error);
g_assert_no_error(error);
- g_assert_cmpint(gplugin_plugin_get_state(plugin), ==,
- GPLUGIN_PLUGIN_STATE_LOADED);
+ gplugin_plugin_get_state(plugin), + GPLUGIN_PLUGIN_STATE_LOADED); ret = gplugin_manager_unload_plugin(plugin, &error);
g_assert_error(error, GPLUGIN_DOMAIN, 0);
- g_assert_cmpint(gplugin_plugin_get_state(plugin), ==,
- GPLUGIN_PLUGIN_STATE_LOADED);
+ gplugin_plugin_get_state(plugin), + GPLUGIN_PLUGIN_STATE_UNLOAD_FAILED); + /* make sure that the plugin's error was set */ + error = gplugin_plugin_get_error(plugin); + g_assert_error(error, GPLUGIN_DOMAIN, 0); g_object_unref(G_OBJECT(plugin));
-gplugin_test_loader_dependencies(gconstpointer d) {
+gplugin_test_loader_dependencies(gconstpointer d) GPluginPlugin *plugin = NULL;
GPluginPluginInfo *info = NULL;
- const gchar * const r_deps[] = { "dependency1", "dependency2", NULL };
+ const gchar *const r_deps[] = {"dependency1", "dependency2", NULL}; id = g_strdup_printf("gplugin/%s-dependent-plugin", (const gchar *)d);
@@ -185,16 +228,17 @@
*****************************************************************************/
static GPluginTestLoaderFunction test_functions[] = {
- { "/loaders/%s/full", gplugin_test_loader_full },
- { "/loaders/%s/load-failed", gplugin_test_loader_load_failed },
- { "/loaders/%s/load-exception", gplugin_test_loader_load_exception },
- { "/loaders/%s/unload-failed", gplugin_test_loader_unload_failed },
- { "/loaders/%s/dependencies", gplugin_test_loader_dependencies },
+ {"/loaders/%s/full", gplugin_test_loader_full}, + {"/loaders/%s/load-failed", gplugin_test_loader_load_failed}, + {"/loaders/%s/load-exception", gplugin_test_loader_load_exception}, + {"/loaders/%s/unload-failed", gplugin_test_loader_unload_failed}, + {"/loaders/%s/dependencies", gplugin_test_loader_dependencies}, -gplugin_loader_tests_add_tests(const gchar *short_name) {
+gplugin_loader_tests_add_tests(const gchar *short_name) for(i = 0; test_functions[i].path; i++) {
@@ -207,8 +251,10 @@
-gplugin_loader_tests_main(const gchar *loader_dir, const gchar *plugin_dir,
- const gchar *short_name)
+gplugin_loader_tests_main( + const gchar *loader_dir, + const gchar *plugin_dir, + const gchar *short_name) @@ -224,4 +270,3 @@
gplugin_loader_tests_add_tests(short_name);
--- a/gplugin/gplugin-loader-tests.h Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin-loader-tests.h Sat Sep 05 20:05:36 2020 -0500
@@ -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,9 +24,11 @@
void gplugin_loader_tests_add_tests(const gchar *short_name);
-void gplugin_loader_tests_main(const gchar *loader_dir, const gchar *plugin_dir, const gchar *short_name);
+void gplugin_loader_tests_main( + const gchar *loader_dir, + const gchar *plugin_dir, + const gchar *short_name); #endif /* GPLUGIN_OPTIONS_H */
--- a/gplugin/gplugin-loader.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin-loader.c Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -15,9 +15,16 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
+#include <gplugin/gplugin-core.h> #include <gplugin/gplugin-loader.h>
-#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. @@ -26,18 +33,9 @@
- * 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,20 +50,22 @@
* @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);
-gplugin_loader_init(G_GNUC_UNUSED GPluginLoader *loader) {
+gplugin_loader_init(G_GNUC_UNUSED GPluginLoader *loader) -gplugin_loader_class_init(G_GNUC_UNUSED GPluginLoaderClass *klass) {
+gplugin_loader_class_init(G_GNUC_UNUSED GPluginLoaderClass *klass) /******************************************************************************
@@ -74,18 +74,21 @@
* 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,
- const gchar *filename, GError **error)
+gplugin_loader_query_plugin( GPluginLoaderClass *klass = NULL;
@@ -104,18 +107,20 @@
* 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,
- GPluginPlugin *plugin, GError **error)
+gplugin_loader_load_plugin( GPluginLoaderClass *klass = NULL;
@@ -129,9 +134,12 @@
ret = klass->load(loader, plugin, error);
- if (!ret && error && *error == NULL) {
- g_set_error(error, GPLUGIN_DOMAIN, 0,
- "Failed to load plugin : unknown");
+ if(!ret && error && *error == NULL) { + "Failed to load plugin : unknown"); @@ -139,18 +147,20 @@
* 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,
- GPluginPlugin *plugin, GError **error)
+gplugin_loader_unload_plugin( GPluginLoaderClass *klass = NULL;
@@ -164,30 +174,39 @@
if(klass && klass->unload)
ret = klass->unload(loader, plugin, error);
- if (!ret && error && *error == NULL) {
- g_set_error(error, GPLUGIN_DOMAIN, 0,
- "Failed to unload plugin : unknown");
+ if(!ret && error && *error == NULL) { + "Failed to unload plugin : unknown"); - * 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; - if(klass->supported_extensions)
- return klass->supported_extensions(klass);
+ g_return_val_if_fail(GPLUGIN_IS_LOADER(loader), NULL); + klass = GPLUGIN_LOADER_GET_CLASS(loader); + if(klass != NULL && klass->supported_extensions) { + return klass->supported_extensions(loader);
--- a/gplugin/gplugin-loader.h Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin-loader.h Sat Sep 05 20:05:36 2020 -0500
@@ -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,7 +28,12 @@
#define GPLUGIN_TYPE_LOADER (gplugin_loader_get_type())
-G_DECLARE_DERIVABLE_TYPE(GPluginLoader, gplugin_loader, GPLUGIN, LOADER, GObject)
+G_DECLARE_DERIVABLE_TYPE( /* circular include so this needs to be after the G_DECLARE_* marcro */
#include <gplugin/gplugin-plugin.h>
@@ -38,25 +43,36 @@
- GSList *(*supported_extensions)(GPluginLoaderClass *klass);
+ GSList *(*supported_extensions)(GPluginLoader *loader); + *query)(GPluginLoader *loader, const gchar *filename, GError **error); - GPluginPlugin *(*query)(GPluginLoader *loader, const gchar *filename, GError **error);
- gboolean (*load)(GPluginLoader *loader, GPluginPlugin *plugin, GError **error);
- gboolean (*unload)(GPluginLoader *loader, GPluginPlugin *plugin, GError **error);
+ *load)(GPluginLoader *loader, GPluginPlugin *plugin, GError **error); + *unload)(GPluginLoader *loader, GPluginPlugin *plugin, GError **error); -GSList *gplugin_loader_class_get_supported_extensions(GPluginLoaderClass *klass);
+GSList *gplugin_loader_get_supported_extensions(GPluginLoader *loader); +GPluginPlugin *gplugin_loader_query_plugin( -GPluginPlugin *gplugin_loader_query_plugin(GPluginLoader *loader, const gchar *filename, GError **error);
-gboolean gplugin_loader_load_plugin(GPluginLoader *loader, GPluginPlugin *plugin, GError **error);
-gboolean gplugin_loader_unload_plugin(GPluginLoader *loader, GPluginPlugin *plugin, GError **error);
+gboolean gplugin_loader_load_plugin( +gboolean gplugin_loader_unload_plugin( #endif /* GPLUGIN_LOADER_H */
--- a/gplugin/gplugin-manager.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin-manager.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,17 +19,14 @@
-#include <gplugin/gplugin-manager.h>
-#include <gplugin/gplugin-core.h>
+#include <glib/gi18n-lib.h> +#include <gplugin-native.h> +#include <gplugin/gplugin-core.h> +#include <gplugin/gplugin-file-tree.h> +#include <gplugin/gplugin-manager.h> #include <gplugin/gplugin-private.h>
-#include <gplugin/gplugin-native.h>
-#include <gplugin/gplugin-file-tree.h>
* SECTION:gplugin-manager
@@ -39,6 +36,15 @@
* loading, unloading, querying, checking for new plugins, and so on.
+ * GPluginManagerForeachFunc: + * @id: The id of the plugin. + * @plugins: A #GSList of each plugin that has the id @id. + * @data: User data passed to gplugin_manager_foreach(). + * A callback function for gplugin_manager_foreach(). /******************************************************************************
*****************************************************************************/
@@ -48,6 +54,7 @@
@@ -61,7 +68,8 @@
GHashTable *plugins_filename_view;
+ GHashTable *loaders_by_extension; @@ -76,47 +84,76 @@
GList *(*get_paths)(GPluginManager *manager);
- void (*register_loader)(GPluginManager *manager, GType type);
- void (*unregister_loader)(GPluginManager *manager, GType type);
+ *register_loader)(GPluginManager *manager, GType type, GError **error); + gboolean (*unregister_loader)( + GPluginManager *manager, void (*refresh)(GPluginManager *manager);
+ GPluginManager *manager, + GPluginManagerForeachFunc func, GSList *(*find_plugins)(GPluginManager *manager, const gchar *id);
+ GSList *(*find_plugins_with_state)( + GPluginManager *manager, + GPluginPluginState state); GList *(*list_plugins)(GPluginManager *manager);
- GSList *(*get_plugin_dependencies)(GPluginManager *manager, GPluginPlugin *plugin, GError **error);
+ GSList *(*get_plugin_dependencies)( + GPluginManager *manager, - gboolean (*load_plugin)(GPluginManager *manager,
- gboolean (*unload_plugin)(GPluginManager *manager,
+ gboolean (*load_plugin)( + GPluginManager *manager, + gboolean (*unload_plugin)( + GPluginManager *manager, - gboolean (*loading_plugin)(GObject *manager,
- void (*loaded_plugin)(GObject *manager,
- GPluginPlugin *plugin);
+ gboolean (*loading_plugin)( + void (*loaded_plugin)(GObject *manager, GPluginPlugin *plugin); void (*load_failed)(GObject *manager, GPluginPlugin *plugin);
- gboolean (*unloading_plugin)(GObject *manager,
- void (*unloaded_plugin)(GObject *manager,
- GPluginPlugin *plugin);
+ gboolean (*unloading_plugin)( + void (*unloaded_plugin)(GObject *manager, GPluginPlugin *plugin); + void (*unload_plugin_failed)(GObject *manager, GPluginPlugin *plugin); -#define GPLUGIN_TYPE_MANAGER (gplugin_manager_get_type())
-#define GPLUGIN_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GPLUGIN_TYPE_MANAGER, GPluginManager))
-#define GPLUGIN_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GPLUGIN_TYPE_MANAGER, GPluginManagerClass))
-#define GPLUGIN_IS_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GPLUGIN_TYPE_MANAGER))
-#define GPLUGIN_IS_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GPLUGIN_TYPE_MANAGER))
-#define GPLUGIN_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GPLUGIN_TYPE_MANAGER, GPluginManagerClass))
+#define GPLUGIN_TYPE_MANAGER (gplugin_manager_get_type()) +#define GPLUGIN_MANAGER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), GPLUGIN_TYPE_MANAGER, GPluginManager)) +#define GPLUGIN_MANAGER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST( \ + GPLUGIN_TYPE_MANAGER, \ +#define GPLUGIN_IS_MANAGER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GPLUGIN_TYPE_MANAGER)) +#define GPLUGIN_IS_MANAGER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GPLUGIN_TYPE_MANAGER)) +#define GPLUGIN_MANAGER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS( \ + GPLUGIN_TYPE_MANAGER, \ -#define GPLUGIN_MANAGER_INSTANCE (GPLUGIN_MANAGER(gplugin_manager_get_instance()))
+#define GPLUGIN_MANAGER_INSTANCE \ + (GPLUGIN_MANAGER(gplugin_manager_get_instance())) G_DEFINE_TYPE(GPluginManager, gplugin_manager, G_TYPE_OBJECT);
@@ -124,15 +161,19 @@
*****************************************************************************/
GPluginManager *instance = NULL;
-static guint signals[N_SIGNALS] = {0, };
-const gchar *dependency_pattern = "^(?P<id>.+?)((?P<op>\\<=|\\<|==|=|\\>=|\\>)(?P<version>.+))?$";
+static guint signals[N_SIGNALS] = { +const gchar *dependency_pattern = + "^(?P<id>.+?)((?P<op>\\<=|\\<|==|=|\\>=|\\>)(?P<version>.+))?$"; GRegex *dependency_regex = NULL;
/******************************************************************************
*****************************************************************************/
-gplugin_manager_str_hash(gconstpointer v) {
+gplugin_manager_str_hash(gconstpointer v) @@ -140,9 +181,10 @@
-gplugin_manager_remove_list_value(G_GNUC_UNUSED gpointer k,
- G_GNUC_UNUSED gpointer d)
+gplugin_manager_remove_list_value( + G_GNUC_UNUSED gpointer k, + G_GNUC_UNUSED gpointer d) @@ -156,100 +198,212 @@
+ * 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); +gplugin_manager_foreach_unload_plugin( + G_GNUC_UNUSED gpointer data) + gchar *id = (gchar *)key; + for(l = (GList *)value; l; l = l->next) { + GPluginPlugin *plugin = GPLUGIN_PLUGIN(l->data); + GPluginLoader *loader = NULL; + if(gplugin_plugin_get_state(plugin) != GPLUGIN_PLUGIN_STATE_LOADED) { + loader = gplugin_plugin_get_loader(plugin); + if(!gplugin_loader_unload_plugin(loader, plugin, &error)) { + "failed to unload plugin with id %s: %s", + error ? error->message : "unknown"); + g_object_unref(G_OBJECT(loader)); +gplugin_manager_normalize_path(const gchar *path) + if(g_str_has_suffix(path, G_DIR_SEPARATOR_S)) { + return g_strdup_printf("%s%s", path, G_DIR_SEPARATOR_S); +gplugin_manager_compare_paths(gconstpointer a, gconstpointer b) + gchar *keya = NULL, *keyb = NULL; + keya = g_utf8_collate_key_for_filename((const gchar *)a, -1); + keyb = g_utf8_collate_key_for_filename((const gchar *)b, -1); + r = strcmp(keya, keyb); /******************************************************************************
*****************************************************************************/
-gplugin_manager_real_append_path(GPluginManager *manager,
+gplugin_manager_real_append_path(GPluginManager *manager, const gchar *path) + gchar *normalized = NULL;
+ normalized = gplugin_manager_normalize_path(path); - for(l = manager->paths->head; l; l = l->next)
- if(strcmp(l->data, path) == 0)
- g_queue_push_tail(manager->paths, g_strdup(path));
+ l = g_queue_find_custom( + gplugin_manager_compare_paths); + g_queue_push_tail(manager->paths, normalized); -gplugin_manager_real_prepend_path(GPluginManager *manager,
+gplugin_manager_real_prepend_path(GPluginManager *manager, const gchar *path) + gchar *normalized = NULL;
+ normalized = gplugin_manager_normalize_path(path); - for(l = manager->paths->head; l; l = l->next)
- if(strcmp(l->data, path) == 0)
- g_queue_push_head(manager->paths, g_strdup(path));
+ l = g_queue_find_custom( + gplugin_manager_compare_paths); + g_queue_push_head(manager->paths, normalized); -gplugin_manager_real_remove_path(GPluginManager *manager,
+gplugin_manager_real_remove_path(GPluginManager *manager, const gchar *path) - GList *l = NULL, *link = NULL;
+ gchar *normalized = NULL; g_return_if_fail(path != NULL);
- for(l = manager->paths->head; l; l = l->next)
- if(strcmp(l->data, path) == 0) {
+ normalized = gplugin_manager_normalize_path(path);
- g_queue_delete_link(manager->paths, link);
+ l = g_queue_find_custom( + gplugin_manager_compare_paths); + g_queue_delete_link(manager->paths, l); -gplugin_manager_real_remove_paths(GPluginManager *manager) {
- g_queue_clear(manager->paths);
+gplugin_manager_real_remove_paths(GPluginManager *manager) + g_queue_clear_full(manager->paths, g_free); -gplugin_manager_real_get_paths(GPluginManager *manager) {
+gplugin_manager_real_get_paths(GPluginManager *manager) return manager->paths->head;
-gplugin_manager_real_register_loader(GPluginManager *manager,
+gplugin_manager_real_register_loader( + GPluginManager *manager, 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)) { + _("loader %s was already registered"), /* 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"),
+ _("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));
+ 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 +411,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 +427,56 @@
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);
+ manager->loaders_by_extension, /* 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, - 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)) { + _("loader %s is not registered"), - 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 +488,14 @@
los = g_slist_remove(los, lo);
- g_hash_table_insert(manager->loaders, g_strdup(ext), los);
- g_hash_table_remove(manager->loaders, ext);
+ 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,12 +504,17 @@
- g_type_class_unref(klass);
+ manager->loaders = g_slist_remove(manager->loaders, loader); + g_object_unref(G_OBJECT(loader)); -gplugin_manager_real_refresh(GPluginManager *manager) {
+gplugin_manager_real_refresh(GPluginManager *manager) GList *error_messages = NULL, *l = NULL;
gchar *error_message = NULL;
@@ -374,57 +553,54 @@
/* Build the path and see if we need to probe it! */
filename = g_build_filename(path, e->filename, NULL);
- plugin = g_hash_table_lookup(manager->plugins_filename_view, filename);
+ plugin = g_hash_table_lookup( + manager->plugins_filename_view, if(plugin && GPLUGIN_IS_PLUGIN(plugin)) {
- GPluginPluginState state =
- gplugin_plugin_get_state(plugin);
+ 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 ||
- state == GPLUGIN_PLUGIN_STATE_LOADED)
+ state == GPLUGIN_PLUGIN_STATE_LOADED) { /* grab the list of loaders for this extension */
- for(l = g_hash_table_lookup(manager->loaders, e->extension); l;
- loader = GPLUGIN_LOADER(l->data);
- if(!GPLUGIN_IS_LOADER(loader)) {
+ l = g_hash_table_lookup( + manager->loaders_by_extension, + for(; l; l = l->next) { + if(!GPLUGIN_IS_LOADER(l->data)) { + loader = GPLUGIN_LOADER(l->data); /* Try to probe the plugin with the current loader */
- plugin = gplugin_loader_query_plugin(loader,
+ gplugin_loader_query_plugin(loader, filename, &error); - /* 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) {
- g_strdup_printf(_("failed to query '%s' with " \
- "loader '%s': %s"), filename,
- G_OBJECT_TYPE_NAME(loader),
- (error) ? error->message : _("Unknown"));
- error_messages = g_list_prepend(error_messages, error_message);
+ error_message = g_strdup_printf( + _("failed to query '%s' with " + G_OBJECT_TYPE_NAME(loader), + g_list_prepend(error_messages, error_message);
@@ -469,21 +645,28 @@
/* throw a warning if the info->id is NULL */
- g_strdup_printf(_("Plugin %s has a NULL id."),
- error_messages = g_list_prepend(error_messages, error_message);
+ error_message = g_strdup_printf( + _("Plugin %s has a NULL id."), + g_object_unref(G_OBJECT(info)); + g_list_prepend(error_messages, error_message); /* now insert into our view */
- g_hash_table_replace(manager->plugins_filename_view,
- g_object_ref(G_OBJECT(plugin)));
+ manager->plugins_filename_view, + g_object_ref(G_OBJECT(plugin))); /* Grab the list of plugins with our id and prepend the new
* plugin to it before updating it.
- l = g_hash_table_lookup(manager->plugins, id); //-V1004
+ l = g_hash_table_lookup(manager->plugins, id); for(ll = l; ll; ll = ll->next) {
GPluginPlugin *splugin = GPLUGIN_PLUGIN(ll->data);
gchar *sfilename = gplugin_plugin_get_filename(splugin);
@@ -505,26 +688,30 @@
- loaded = gplugin_loader_load_plugin(loader,
+ gplugin_loader_load_plugin(loader, plugin, &error);
- g_strdup_printf(_("failed to load %s during query: %s"),
- (error) ? error->message : _("Unknown"));
- error_messages = g_list_prepend(error_messages, error_message);
+ error_message = g_strdup_printf( + _("failed to load %s during query: %s"), + (error) ? error->message : _("Unknown")); + g_list_prepend(error_messages, error_message); - gplugin_plugin_set_state(plugin, GPLUGIN_PLUGIN_STATE_LOADED);
+ gplugin_plugin_set_state( + GPLUGIN_PLUGIN_STATE_LOADED); /* finally set the plugin state queried */
- gplugin_plugin_set_state(plugin, GPLUGIN_PLUGIN_STATE_QUERIED);
+ gplugin_plugin_set_state( + GPLUGIN_PLUGIN_STATE_QUERIED); /* if errors is greater than 0 set
* manager->refresh_needed to TRUE.
@@ -537,6 +724,10 @@
g_object_unref(G_OBJECT(info));
+ /* since the plugin is now stored in our hash tables we + * need to remove this function's reference to it. + g_object_unref(G_OBJECT(plugin)); @@ -558,31 +749,63 @@
gplugin_file_tree_free(root);
+gplugin_manager_real_foreach( + GPluginManager *manager, + GPluginManagerForeachFunc func, + gpointer id = NULL, plugins = NULL; + g_hash_table_iter_init(&iter, manager->plugins); + while(g_hash_table_iter_next(&iter, &id, &plugins)) { + func((gchar *)id, (GSList *)plugins, data); -gplugin_manager_real_find_plugins(GPluginManager *manager,
+gplugin_manager_real_find_plugins(GPluginManager *manager, const gchar *id) GSList *plugins_list = NULL, *l;
g_return_val_if_fail(id != NULL, NULL);
- for(l = g_hash_table_lookup(manager->plugins, id); l; l = l->next) {
- GPluginPlugin *plugin = NULL;
- plugin = GPLUGIN_PLUGIN(l->data);
- plugins_list = g_slist_prepend(plugins_list,
- g_object_ref(G_OBJECT(plugin)));
+ l = g_hash_table_lookup(manager->plugins, id); + plugins_list = g_slist_copy_deep(l, (GCopyFunc)g_object_ref, NULL); +gplugin_manager_real_find_plugins_with_state( + GPluginManager *manager, + GPluginPluginState state) + GSList *plugins = NULL; + g_hash_table_iter_init(&iter, manager->plugins); + while(g_hash_table_iter_next(&iter, NULL, &value)) { + for(l = (GSList *)value; l != NULL; l = l->next) { + GPluginPlugin *plugin = GPLUGIN_PLUGIN(l->data); + if(gplugin_plugin_get_state(plugin) == state) { + g_slist_prepend(plugins, g_object_ref(G_OBJECT(plugin))); -gplugin_manager_real_list_plugins(GPluginManager *manager) {
+gplugin_manager_real_list_plugins(GPluginManager *manager) GQueue *queue = g_queue_new();
@@ -601,178 +824,132 @@
-gplugin_manager_load_dependencies(GPluginPlugin *plugin,
- GPluginPluginInfo *info,
+gplugin_manager_load_dependencies( + GPluginPluginInfo *info, - 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)
+ for(l = dependencies; l != NULL; l = l->next) { + GPluginPlugin *dependency = GPLUGIN_PLUGIN(l->data); + gboolean loaded = FALSE;
- 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));
+ loaded = gplugin_manager_load_plugin(dependency, &ourerror);
+ if(!loaded || ourerror != NULL) { + g_propagate_error(error, ourerror);
+ g_slist_free_full(dependencies, g_object_unref); -gplugin_manager_real_get_plugin_dependencies(G_GNUC_UNUSED GPluginManager *manager,
+gplugin_manager_real_get_plugin_dependencies( + G_GNUC_UNUSED GPluginManager *manager, GPluginPluginInfo *info = NULL;
- const gchar * const *dependencies = NULL;
+ const gchar *const *dependencies = NULL; info = gplugin_plugin_get_info(plugin);
dependencies = gplugin_plugin_info_get_dependencies(info);
+ g_object_unref(G_OBJECT(info)); if(dependencies == NULL) {
- 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, over); + /* 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);
+ _("failed to find dependency %s for %s"), + gplugin_plugin_info_get_id(info)); + g_slist_free_full(ret, g_object_unref);
- ret = g_slist_prepend(ret, dep);
-gplugin_manager_real_load_plugin(GPluginManager *manager,
+gplugin_manager_real_load_plugin( + GPluginManager *manager, GPluginPluginInfo *info = NULL;
GPluginLoader *loader = NULL;
g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), FALSE);
@@ -784,16 +961,22 @@
/* now try to get the plugin info from the plugin */
info = gplugin_plugin_get_info(plugin);
- g_set_error(error, GPLUGIN_DOMAIN, 0,
- _("Plugin %s did not return value plugin info"),
- gplugin_plugin_get_filename(plugin));
+ gchar *filename = gplugin_plugin_get_filename(plugin); + _("Plugin %s did not return value plugin info"), gplugin_plugin_set_state(plugin, GPLUGIN_PLUGIN_STATE_LOAD_FAILED);
- if(!gplugin_manager_load_dependencies(plugin, info, error)) {
+ if(!gplugin_manager_load_dependencies(plugin, info, ret_error)) { g_object_unref(G_OBJECT(info));
@@ -805,41 +988,73 @@
loader = gplugin_plugin_get_loader(plugin);
if(!GPLUGIN_IS_LOADER(loader)) {
- g_set_error(error, GPLUGIN_DOMAIN, 0,
- _("The loader for %s is not a loader. This "
- "should not happened!"),
- gplugin_plugin_get_filename(plugin));
+ gchar *filename = gplugin_plugin_get_filename(plugin); + _("The loader for %s is not a loader. This " + "should not happened!"), gplugin_plugin_set_state(plugin, GPLUGIN_PLUGIN_STATE_LOAD_FAILED);
- g_signal_emit(manager, signals[SIG_LOADING], 0, plugin, error, &ret);
+ g_signal_emit(manager, signals[SIG_LOADING], 0, plugin, &error, &ret); + /* Set the plugin's error. */ + g_object_set(G_OBJECT(plugin), "error", error, NULL); + g_propagate_error(ret_error, error); gplugin_plugin_set_state(plugin, GPLUGIN_PLUGIN_STATE_LOAD_FAILED);
- ret = gplugin_loader_load_plugin(loader, plugin, error);
- gplugin_plugin_set_state(plugin, (ret) ? GPLUGIN_PLUGIN_STATE_LOADED :
- GPLUGIN_PLUGIN_STATE_LOAD_FAILED);
+ ret = gplugin_loader_load_plugin(loader, plugin, &error); + /* If the plugin successfully loaded but returned an error, ignore the + /* Likewise, make sure the plugin's error is set to NULL. */ + g_object_set(G_OBJECT(plugin), "error", NULL, NULL);
+ gplugin_plugin_set_state(plugin, GPLUGIN_PLUGIN_STATE_LOADED); g_signal_emit(manager, signals[SIG_LOADED], 0, plugin);
+ /* Set the error on the plugin as well. This has to be before we + * propagate the error, because error is invalidate at that point. + g_object_set(G_OBJECT(plugin), "error", error, NULL); + /* Set the state after the error is set, because people might connect + * to the notify signal on the state property. + gplugin_plugin_set_state(plugin, GPLUGIN_PLUGIN_STATE_LOAD_FAILED); g_signal_emit(manager, signals[SIG_LOAD_FAILED], 0, plugin);
+ g_propagate_error(ret_error, error); -gplugin_manager_real_unload_plugin(GPluginManager *manager,
+gplugin_manager_real_unload_plugin( + GPluginManager *manager, GPluginLoader *loader = NULL;
g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), FALSE);
@@ -849,76 +1064,121 @@
loader = gplugin_plugin_get_loader(plugin);
if(!GPLUGIN_IS_LOADER(loader)) {
- g_set_error_literal(error, GPLUGIN_DOMAIN, 0,
- _("Plugin loader is not a loader"));
+ _("Plugin loader is not a loader")); - g_signal_emit(manager, signals[SIG_UNLOADING], 0, plugin, error, &ret);
+ g_signal_emit(manager, signals[SIG_UNLOADING], 0, plugin, &error, &ret); + /* Set the plugin's error. */ + g_object_set(G_OBJECT(plugin), "error", error, NULL); + g_propagate_error(ret_error, error); + ret = gplugin_loader_unload_plugin(loader, plugin, &error); + /* If the plugin successfully loaded but returned an error, ignore the - ret = gplugin_loader_unload_plugin(loader, plugin, error);
+ /* Like, make sure the plugin's error is set to NULL. */ + g_object_set(G_OBJECT(plugin), "error", NULL, NULL); gplugin_plugin_set_state(plugin, GPLUGIN_PLUGIN_STATE_QUERIED);
+ g_signal_emit(manager, signals[SIG_UNLOADED], 0, plugin); + /* Set the error on the plugin as well. This has to be before we + * propagate the error, because error is invalidate at that point. + g_object_set(G_OBJECT(plugin), "error", error, NULL); - g_signal_emit(manager, signals[SIG_UNLOADED], 0, plugin, error);
+ /* Set the state after the error is set, because people might connect + * to the notify signal on the state property. + gplugin_plugin_set_state(plugin, GPLUGIN_PLUGIN_STATE_UNLOAD_FAILED); + g_signal_emit(manager, signals[SIG_UNLOAD_FAILED], 0, plugin); + g_propagate_error(ret_error, error); -gplugin_manager_loading_cb(G_GNUC_UNUSED GObject *manager,
- G_GNUC_UNUSED GPluginPlugin *plugin,
- G_GNUC_UNUSED GError **error)
+gplugin_manager_loading_cb( + G_GNUC_UNUSED GObject *manager, + G_GNUC_UNUSED GPluginPlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_manager_unloading_cb(G_GNUC_UNUSED GObject *manager,
- G_GNUC_UNUSED GPluginPlugin *plugin,
- G_GNUC_UNUSED GError **error)
+gplugin_manager_unloading_cb( + G_GNUC_UNUSED GObject *manager, + G_GNUC_UNUSED GPluginPlugin *plugin, + G_GNUC_UNUSED GError **error) /******************************************************************************
+ * GObject Implementation *****************************************************************************/
-gplugin_manager_finalize(GObject *obj) {
+gplugin_manager_finalize(GObject *obj) GPluginManager *manager = GPLUGIN_MANAGER(obj);
g_queue_free_full(manager->paths, g_free);
+ /* unload all of the loaded plugins */ + gplugin_manager_foreach_unload_plugin, /* free all the data in the plugins hash table and destroy it */
- g_hash_table_foreach_remove(manager->plugins,
- gplugin_manager_remove_list_value,
+ g_hash_table_foreach_remove( + gplugin_manager_remove_list_value, g_clear_pointer(&manager->plugins, g_hash_table_destroy);
/* 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,
- gplugin_manager_remove_list_value,
- g_clear_pointer(&manager->loaders, g_hash_table_destroy);
+ g_hash_table_foreach_remove( + manager->loaders_by_extension, + gplugin_manager_remove_list_value, + 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);
-gplugin_manager_class_init(GPluginManagerClass *klass) {
+gplugin_manager_class_init(GPluginManagerClass *klass) GObjectClass *obj_class = G_OBJECT_CLASS(klass);
- GPluginManagerClass *manager_class =
- GPLUGIN_MANAGER_CLASS(klass);
+ GPluginManagerClass *manager_class = GPLUGIN_MANAGER_CLASS(klass); obj_class->finalize = gplugin_manager_finalize;
@@ -928,17 +1188,20 @@
manager_class->remove_paths = gplugin_manager_real_remove_paths;
manager_class->get_paths = gplugin_manager_real_get_paths;
- manager_class->register_loader =
- gplugin_manager_real_register_loader;
- manager_class->unregister_loader =
- gplugin_manager_real_unregister_loader;
+ manager_class->register_loader = gplugin_manager_real_register_loader; + manager_class->unregister_loader = gplugin_manager_real_unregister_loader; manager_class->refresh = gplugin_manager_real_refresh;
+ manager_class->foreach = gplugin_manager_real_foreach; manager_class->find_plugins = gplugin_manager_real_find_plugins;
+ manager_class->find_plugins_with_state = + gplugin_manager_real_find_plugins_with_state; manager_class->list_plugins = gplugin_manager_real_list_plugins;
- manager_class->get_plugin_dependencies = gplugin_manager_real_get_plugin_dependencies;
+ manager_class->get_plugin_dependencies = + gplugin_manager_real_get_plugin_dependencies; manager_class->load_plugin = gplugin_manager_real_load_plugin;
manager_class->unload_plugin = gplugin_manager_real_unload_plugin;
@@ -958,17 +1221,18 @@
* Return FALSE to stop loading
- g_signal_new("loading-plugin",
- G_OBJECT_CLASS_TYPE(manager_class),
- G_STRUCT_OFFSET(GPluginManagerClass,
- gplugin_boolean_accumulator, NULL,
- G_TYPE_OBJECT, G_TYPE_POINTER);
+ signals[SIG_LOADING] = g_signal_new( + G_OBJECT_CLASS_TYPE(manager_class), + G_STRUCT_OFFSET(GPluginManagerClass, loading_plugin), + gplugin_boolean_accumulator, * GPluginManager::loaded-plugin:
@@ -977,36 +1241,36 @@
* emitted after a plugin is loaded.
- g_signal_new("loaded-plugin",
- G_OBJECT_CLASS_TYPE(manager_class),
- G_STRUCT_OFFSET(GPluginManagerClass,
+ signals[SIG_LOADED] = g_signal_new( + G_OBJECT_CLASS_TYPE(manager_class), + G_STRUCT_OFFSET(GPluginManagerClass, loaded_plugin), - * GPluginManager::load-failed:
+ * GPluginManager::load-plugin-failed: * @manager: The #GPluginPluginManager instance.
* @plugin: The #GPluginPlugin that failed to load.
* emitted after a plugin fails to load.
- signals[SIG_LOAD_FAILED] =
- g_signal_new("load-failed",
- G_OBJECT_CLASS_TYPE(manager_class),
- G_STRUCT_OFFSET(GPluginManagerClass, load_failed),
+ signals[SIG_LOAD_FAILED] = g_signal_new( + G_OBJECT_CLASS_TYPE(manager_class), + G_STRUCT_OFFSET(GPluginManagerClass, load_failed), * GPluginManager::unloading-plugin:
@@ -1017,40 +1281,63 @@
* Return FALSE to stop unloading
- signals[SIG_UNLOADING] =
- g_signal_new("unloading-plugin",
- G_OBJECT_CLASS_TYPE(manager_class),
- G_STRUCT_OFFSET(GPluginManagerClass,
- gplugin_boolean_accumulator, NULL,
- G_TYPE_OBJECT, G_TYPE_POINTER);
+ signals[SIG_UNLOADING] = g_signal_new( + G_OBJECT_CLASS_TYPE(manager_class), + G_STRUCT_OFFSET(GPluginManagerClass, unloading_plugin), + gplugin_boolean_accumulator, * GPluginManager::unloaded-plugin:
* @manager: the #gpluginpluginmanager instance. treat as a #gobject.
* @plugin: the #gpluginplugin that's about to be loaded.
- * emitted after a plugin is unloaded.
+ * emitted after a plugin is successfully unloaded. - signals[SIG_UNLOADED] =
- g_signal_new("unloaded-plugin",
- G_OBJECT_CLASS_TYPE(manager_class),
- G_STRUCT_OFFSET(GPluginManagerClass,
+ signals[SIG_UNLOADED] = g_signal_new( + G_OBJECT_CLASS_TYPE(manager_class), + G_STRUCT_OFFSET(GPluginManagerClass, unloaded_plugin), + * GPluginManager::unload-plugin-failed: + * @manager: The #GPluginManager instance. + * @plugin: The #GPluginPlugin instance that failed to unload. + * @error: A #GError instance. + * Emitted when @manager was asked to unload @plugin, but @plugin returned + * %FALSE when its unload function was called. + signals[SIG_UNLOAD_FAILED] = g_signal_new( + "unload-plugin-failed", + G_OBJECT_CLASS_TYPE(manager_class), + G_STRUCT_OFFSET(GPluginManagerClass, unload_plugin_failed), -gplugin_manager_init(GPluginManager *manager) {
+gplugin_manager_init(GPluginManager *manager) manager->paths = g_queue_new();
/* the plugins hashtable is keyed on a plugin id and holds a GSList of all
@@ -1065,40 +1352,53 @@
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
- g_hash_table_new_full(gplugin_manager_str_hash, g_str_equal,
+ manager->loaders_by_extension = g_hash_table_new_full( + gplugin_manager_str_hash, /******************************************************************************
*****************************************************************************/
-gplugin_manager_private_init(void) {
- if (instance != NULL) {
+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);
-gplugin_manager_private_uninit(void) {
+gplugin_manager_private_uninit(void) g_regex_unref(dependency_regex);
g_clear_object(&instance);
@@ -1110,12 +1410,13 @@
* 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.
-gplugin_manager_append_path(const gchar *path) {
+gplugin_manager_append_path(const gchar *path) GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE;
GPluginManagerClass *klass = NULL;
@@ -1129,12 +1430,13 @@
* 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.
-gplugin_manager_prepend_path(const gchar *path) {
+gplugin_manager_prepend_path(const gchar *path) GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE;
GPluginManagerClass *klass = NULL;
@@ -1148,12 +1450,13 @@
* 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.
-gplugin_manager_remove_path(const gchar *path) {
+gplugin_manager_remove_path(const gchar *path) GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE;
GPluginManagerClass *klass = NULL;
@@ -1171,7 +1474,8 @@
* Clears all paths that are set to search for plugins.
-gplugin_manager_remove_paths(void) {
+gplugin_manager_remove_paths(void) GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE;
GPluginManagerClass *klass = NULL;
@@ -1187,10 +1491,12 @@
* 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) {
+gplugin_manager_add_default_paths(void) path = g_build_filename(PREFIX, LIBDIR, "gplugin", NULL);
@@ -1202,19 +1508,17 @@
* gplugin_manager_add_app_paths:
* @prefix: The installation prefix for the application.
* @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,
+gplugin_manager_add_app_paths(const gchar *prefix, const gchar *appname) @@ -1232,13 +1536,14 @@
* 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) {
+gplugin_manager_get_paths(void) GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE;
GPluginManagerClass *klass = NULL;
@@ -1253,38 +1558,64 @@
* 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); + "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); + "unregister_loader method not implemented"); @@ -1293,7 +1624,8 @@
* Forces a refresh of all plugins found in the search paths.
-gplugin_manager_refresh(void) {
+gplugin_manager_refresh(void) GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE;
GPluginManagerClass *klass = NULL;
@@ -1305,18 +1637,40 @@
+ * gplugin_manager_foreach: + * @func: (scope call): The #GPluginManagerForeachFunc to call. + * @data: User data to pass to func. + * Calls @func for each plugin that is known. +gplugin_manager_foreach(GPluginManagerForeachFunc func, gpointer data) + GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE; + GPluginManagerClass *klass = NULL; + g_return_if_fail(GPLUGIN_IS_MANAGER(manager)); + g_return_if_fail(func != NULL); + klass = GPLUGIN_MANAGER_GET_CLASS(manager); + if(klass && klass->foreach) + klass->foreach(manager, func, data); * 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) {
+gplugin_manager_find_plugins(const gchar *id) GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE;
GPluginManagerClass *klass = NULL;
@@ -1330,30 +1684,106 @@
- * 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( + 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); + /* 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); + /* we need to keep info around until we're done using found_version */ + g_object_unref(G_OBJECT(info)); + keep = (g_strcmp0(op, "<") == 0 || g_strcmp0(op, "<=") == 0); + } else if(result == 0) { + (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); + g_slist_prepend(filtered, g_object_ref(G_OBJECT(plugin))); + g_slist_free_full(plugins, g_object_unref); + return g_slist_reverse(filtered); + * gplugin_manager_find_plugins_with_state: + * @state: The #GPluginPluginState to look for. + * Finds all plugins that currently have a state of @state. + * Returns: (element-type GPlugin.Plugin) (transfer full): A #GSList of + * referenced #GPluginPlugin's whose state is @state. 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_with_state(GPluginPluginState state) + GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE; + GPluginManagerClass *klass = NULL; + g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), NULL); + klass = GPLUGIN_MANAGER_GET_CLASS(manager); + if(klass && klass->find_plugins_with_state) + return klass->find_plugins_with_state(manager, state); @@ -1368,7 +1798,8 @@
* if no plugin matching @id was found.
-gplugin_manager_find_plugin(const gchar *id) {
+gplugin_manager_find_plugin(const gchar *id) GSList *plugins_list = NULL;
GPluginPlugin *plugin = NULL;
@@ -1380,24 +1811,99 @@
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); + * gplugin_manager_find_plugin_with_newest_version: + * @id: The id of the plugin to find. + * Calls gplugin_manager_find_plugins() with @id, and then returns the plugins + * with the highest version number or %NULL if no plugins with @id are found. + * Returns: (transfer full): The #GPluginPlugin with an id of @id that has the + * highest version number, or %NULL if no plugins were found with @id. +gplugin_manager_find_plugin_with_newest_version(const gchar *id) + GPluginPlugin *plugin_a = NULL; + GPluginPluginInfo *info_a = NULL; + const gchar *version_a = NULL; + g_return_val_if_fail(id != NULL, NULL); + l = gplugin_manager_find_plugins(id); + for(; l != NULL; l = g_slist_delete_link(l, l)) { + GPluginPlugin *plugin_b = NULL; + GPluginPluginInfo *info_b = NULL; + const gchar *version_b = NULL; + if(!GPLUGIN_IS_PLUGIN(l->data)) { + plugin_b = GPLUGIN_PLUGIN(l->data); + info_b = gplugin_plugin_get_info(plugin_b); + /* If this is the first plugin we've found, set the plugin_a values and + if(!GPLUGIN_IS_PLUGIN(plugin_a)) { + version_a = gplugin_plugin_info_get_version(info_a); + /* At this point, we've seen another plugin, so we need to compare + version_b = gplugin_plugin_info_get_version(info_b); + cmp = gplugin_version_compare(version_a, version_b); + /* plugin_b has a newer version, so set the plugin_a pointers to + * the plugin_b pointers as well as the version pointers. + g_set_object(&plugin_a, plugin_b); + g_set_object(&info_a, info_b); + /* Clean up the plugin_b pointers. */ + g_clear_object(&plugin_b); + g_clear_object(&info_b); + g_clear_object(&info_a); * 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) {
+gplugin_manager_get_plugin_dependencies(GPluginPlugin *plugin, GError **error) GPluginManager *manager = NULL;
GPluginManagerClass *klass = NULL;
@@ -1416,18 +1922,19 @@
* 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) {
+gplugin_manager_load_plugin(GPluginPlugin *plugin, GError **error) GPluginManager *manager = NULL;
GPluginManagerClass *klass = NULL;
@@ -1445,16 +1952,17 @@
* 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) {
+gplugin_manager_unload_plugin(GPluginPlugin *plugin, GError **error) GPluginManager *manager = NULL;
GPluginManagerClass *klass = NULL;
@@ -1476,11 +1984,12 @@
* Returns a #GList of all plugin id's. Each id should be queried directly
- * Return value: (element-type utf8) (transfer full): A #GList of each unique
+ * Return value: (element-type utf8) (transfer container): A #GList of each -gplugin_manager_list_plugins(void) {
+gplugin_manager_list_plugins(void) GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE;
GPluginManagerClass *klass = NULL;
@@ -1493,7 +2002,6 @@
* gplugin_manager_get_instance:
@@ -1503,14 +2011,14 @@
* 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) {
+gplugin_manager_get_instance(void) return G_OBJECT(instance);
--- a/gplugin/gplugin-manager.h Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin-manager.h Sat Sep 05 20:05:36 2020 -0500
@@ -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,6 +29,11 @@
+typedef void (*GPluginManagerForeachFunc)( void gplugin_manager_append_path(const gchar *path);
void gplugin_manager_prepend_path(const gchar *path);
void gplugin_manager_remove_path(const gchar *path);
@@ -39,17 +44,26 @@
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);
+void gplugin_manager_foreach(GPluginManagerForeachFunc func, gpointer data); GSList *gplugin_manager_find_plugins(const gchar *id);
-void gplugin_manager_free_plugin_list(GSList *plugins_list);
+GSList *gplugin_manager_find_plugins_with_version( +GSList *gplugin_manager_find_plugins_with_state(GPluginPluginState state); GPluginPlugin *gplugin_manager_find_plugin(const gchar *id);
+GPluginPlugin *gplugin_manager_find_plugin_with_newest_version(const gchar *id); -GSList *gplugin_manager_get_plugin_dependencies(GPluginPlugin *plugin, GError **error);
+GSList *gplugin_manager_get_plugin_dependencies( gboolean gplugin_manager_load_plugin(GPluginPlugin *plugin, GError **error);
gboolean gplugin_manager_unload_plugin(GPluginPlugin *plugin, GError **error);
@@ -61,4 +75,3 @@
#endif /* GPLUGIN_MANAGER_H */
--- a/gplugin/gplugin-native-loader.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin-native-loader.c Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -15,30 +15,20 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
+#include <glib/gi18n-lib.h> #include <gplugin/gplugin-core.h>
-#include <gplugin/gplugin-private.h>
#include <gplugin/gplugin-native-loader.h>
#include <gplugin/gplugin-native-plugin.h>
#include <gplugin/gplugin-native-private.h>
+#include <gplugin/gplugin-private.h> #define GPLUGIN_QUERY_SYMBOL "gplugin_query"
#define GPLUGIN_LOAD_SYMBOL "gplugin_load"
#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.
@@ -67,16 +57,22 @@
*****************************************************************************/
-gplugin_native_loader_lookup_symbol(GModule *module,
- const gchar *name, GError **error)
+gplugin_native_loader_lookup_symbol( g_return_val_if_fail(module != NULL, NULL);
if(!g_module_symbol(module, name, &symbol)) {
- g_set_error(error, GPLUGIN_DOMAIN, 0,
- _("symbol %s was not found"), name);
+ _("symbol %s was not found"), @@ -85,8 +81,10 @@
-gplugin_native_loader_open(const gchar *filename, GModuleFlags flags,
+gplugin_native_loader_open( @@ -97,9 +95,12 @@
const gchar *msg = g_module_error();
- *error = g_error_new(GPLUGIN_DOMAIN, 0,
- _("Failed to open plugin '%s': %s"),
- filename, (msg) ? msg : _("Unknown error"));
+ _("Failed to open plugin '%s': %s"), + (msg) ? msg : _("Unknown error")); @@ -109,12 +110,13 @@
* 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");
@@ -124,25 +126,28 @@
static GPluginPluginInfo *
-gplugin_native_loader_open_and_query(const gchar *filename,
- GPluginNativePluginQueryFunc *query,
+gplugin_native_loader_open_and_query( + GPluginNativePluginQueryFunc *query, GPluginPluginInfo *info = NULL;
*module = gplugin_native_loader_open(filename, flags, error);
- } else if (error && *error) {
+ } else if(error && *error) { - *query = gplugin_native_loader_lookup_symbol(*module, GPLUGIN_QUERY_SYMBOL,
+ *query = gplugin_native_loader_lookup_symbol( if((*query == NULL) || (error && *error)) {
@@ -161,9 +166,10 @@
-gplugin_native_loader_query(GPluginLoader *loader,
+gplugin_native_loader_query( GPluginPlugin *plugin = NULL;
GPluginPluginInfo *info = NULL;
@@ -172,13 +178,20 @@
GPluginNativePluginUnloadFunc unload = NULL;
- info = gplugin_native_loader_open_and_query(filename, &module, 0, &query,
+ info = gplugin_native_loader_open_and_query( if(!GPLUGIN_IS_PLUGIN_INFO(info)) {
- if (error && *error == NULL) {
- g_set_error_literal(error, GPLUGIN_DOMAIN, 0,
- _("the query function did not return a "
- "GPluginPluginInfo instance"));
+ if(error && *error == NULL) { + _("the query function did not return a " + "GPluginPluginInfo instance")); @@ -188,14 +201,20 @@
g_object_unref(G_OBJECT(info));
- info = gplugin_native_loader_open_and_query(filename, &module,
+ info = gplugin_native_loader_open_and_query( if(!GPLUGIN_IS_PLUGIN_INFO(info)) {
- if (error && *error == NULL) {
- g_set_error_literal(error, GPLUGIN_DOMAIN, 0,
- _("the query function did not return a "
- "GPluginPluginInfo instance"));
+ if(error && *error == NULL) { + _("the query function did not return a " + "GPluginPluginInfo instance")); @@ -203,9 +222,8 @@
/* now look for the load symbol */
- load = gplugin_native_loader_lookup_symbol(module,
+ gplugin_native_loader_lookup_symbol(module, GPLUGIN_LOAD_SYMBOL, error); g_object_unref(G_OBJECT(info));
@@ -213,34 +231,39 @@
/* now look for the unload symbol */
- unload = gplugin_native_loader_lookup_symbol(module,
+ unload = gplugin_native_loader_lookup_symbol( g_object_unref(G_OBJECT(info));
- /* claim ownership of the info object */
- g_object_ref_sink(G_OBJECT(info));
/* now create the actual plugin instance */
- plugin = g_object_new(GPLUGIN_TYPE_NATIVE_PLUGIN,
+ GPLUGIN_TYPE_NATIVE_PLUGIN, /* now that the plugin instance owns the info, remove our ref */
g_object_unref(G_OBJECT(info));
if(!GPLUGIN_IS_NATIVE_PLUGIN(plugin)) {
- g_set_error_literal(error, GPLUGIN_DOMAIN, 0,
- _("failed to create plugin instance"));
+ g_module_close(module); + _("failed to create plugin instance")); @@ -248,9 +271,10 @@
-gplugin_native_loader_load(G_GNUC_UNUSED GPluginLoader *loader,
+gplugin_native_loader_load( + G_GNUC_UNUSED GPluginLoader *loader, GPluginNativePluginLoadFunc func;
@@ -260,7 +284,7 @@
/* get and call the function */
g_object_get(G_OBJECT(plugin), "load-func", &func, NULL);
if(!func(GPLUGIN_NATIVE_PLUGIN(plugin), error)) {
- if (error && *error == NULL)
+ if(error && *error == NULL) g_set_error_literal(error, GPLUGIN_DOMAIN, 0, _("unknown failure"));
@@ -270,9 +294,10 @@
-gplugin_native_loader_unload(G_GNUC_UNUSED GPluginLoader *loader,
+gplugin_native_loader_unload( + G_GNUC_UNUSED GPluginLoader *loader, GPluginNativePluginUnloadFunc func;
@@ -284,16 +309,18 @@
/* validate the function */
- const char *filename = gplugin_plugin_get_filename(plugin);
+ gchar *filename = gplugin_plugin_get_filename(plugin); g_warning(_("unload function for %s is NULL"), filename);
/* now call the function */
if(!func(GPLUGIN_NATIVE_PLUGIN(plugin), error)) {
- if (error && *error == NULL)
+ if(error && *error == NULL) g_set_error_literal(error, GPLUGIN_DOMAIN, 0, _("unknown failure"));
@@ -303,16 +330,17 @@
-gplugin_native_loader_init(G_GNUC_UNUSED GPluginNativeLoader *loader) {
+gplugin_native_loader_init(G_GNUC_UNUSED GPluginNativeLoader *loader) -gplugin_native_loader_class_init(GPluginNativeLoaderClass *klass) {
- GPluginLoaderClass *loader_class =
- GPLUGIN_LOADER_CLASS(klass);
+gplugin_native_loader_class_init(GPluginNativeLoaderClass *klass) + GPluginLoaderClass *loader_class = 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 Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin-native-loader.h Sat Sep 05 20:05:36 2020 -0500
@@ -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,9 +32,13 @@
#define GPLUGIN_TYPE_NATIVE_LOADER (gplugin_native_loader_get_type())
-G_DECLARE_FINAL_TYPE(GPluginNativeLoader, gplugin_native_loader, GPLUGIN, NATIVE_LOADER, GPluginLoader)
#endif /* GPLUGIN_NATIVE_LOADER_H */
--- a/gplugin/gplugin-native-plugin.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin-native-plugin.c Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -15,25 +15,13 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#include <gplugin/gplugin-native-plugin.h>
-#include <gplugin/gplugin-native-private.h>
-#include <gplugin/gplugin-loader.h>
-#include <gplugin/gplugin-manager.h>
+#include <glib/gi18n-lib.h> #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 <gplugin/gplugin-loader.h> +#include <gplugin/gplugin-manager.h> +#include <gplugin/gplugin-native-plugin.h> +#include <gplugin/gplugin-native-private.h> * GPLUGIN_TYPE_NATIVE_PLUGIN:
@@ -63,6 +51,7 @@
GPluginPluginState state;
/******************************************************************************
@@ -78,15 +67,19 @@
PROP_FILENAME = N_PROPERTIES,
-static GParamSpec *properties[N_PROPERTIES] = {NULL,};
+static GParamSpec *properties[N_PROPERTIES] = { /******************************************************************************
* GPluginPlugin Implementation
*****************************************************************************/
-gplugin_native_plugin_iface_init(G_GNUC_UNUSED GPluginPluginInterface *iface) {
+gplugin_native_plugin_iface_init(G_GNUC_UNUSED GPluginPluginInterface *iface) /* we just override properites from GPluginPlugin */
@@ -94,12 +87,14 @@
* GTypeModule Implementation
*****************************************************************************/
-gplugin_native_plugin_load(G_GNUC_UNUSED GTypeModule *module) {
+gplugin_native_plugin_load(G_GNUC_UNUSED GTypeModule *module) -gplugin_native_plugin_unload(G_GNUC_UNUSED GTypeModule *module) {
+gplugin_native_plugin_unload(G_GNUC_UNUSED GTypeModule *module) /******************************************************************************
@@ -109,19 +104,24 @@
- G_IMPLEMENT_INTERFACE(GPLUGIN_TYPE_PLUGIN, gplugin_native_plugin_iface_init)
+ gplugin_native_plugin_iface_init)); -gplugin_native_plugin_get_property(GObject *obj, guint param_id, GValue *value,
+gplugin_native_plugin_get_property( GPluginNativePlugin *plugin = GPLUGIN_NATIVE_PLUGIN(obj);
- g_value_set_pointer(value,
- gplugin_native_plugin_get_module(plugin));
+ gplugin_native_plugin_get_module(plugin)); g_value_set_pointer(value, plugin->load_func);
@@ -143,6 +143,10 @@
g_value_set_enum(value, plugin->state);
+ g_value_set_boxed(value, plugin->error); G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
@@ -150,8 +154,11 @@
-gplugin_native_plugin_set_property(GObject *obj, guint param_id,
- const GValue *value, GParamSpec *pspec)
+gplugin_native_plugin_set_property( GPluginNativePlugin *plugin = GPLUGIN_NATIVE_PLUGIN(obj);
@@ -179,6 +186,9 @@
plugin->state = g_value_get_enum(value);
+ plugin->error = g_value_dup_boxed(value); G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
@@ -187,22 +197,28 @@
-gplugin_native_plugin_finalize(GObject *obj) {
+gplugin_native_plugin_finalize(GObject *obj) GPluginNativePlugin *plugin = GPLUGIN_NATIVE_PLUGIN(obj);
g_clear_pointer(&plugin->filename, g_free);
g_clear_object(&plugin->loader);
g_clear_object(&plugin->info);
+ g_clear_error(&plugin->error); + g_module_close(plugin->module); G_OBJECT_CLASS(gplugin_native_plugin_parent_class)->finalize(obj);
-gplugin_native_plugin_init(G_GNUC_UNUSED GPluginNativePlugin *plugin) {
+gplugin_native_plugin_init(G_GNUC_UNUSED GPluginNativePlugin *plugin) -gplugin_native_plugin_class_init(GPluginNativePluginClass *klass) {
+gplugin_native_plugin_class_init(GPluginNativePluginClass *klass) GObjectClass *obj_class = G_OBJECT_CLASS(klass);
GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS(klass);
@@ -219,10 +235,10 @@
* The GModule instance for this plugin.
properties[PROP_MODULE] = g_param_spec_pointer(
- "module", "module handle",
"The GModule instance of the plugin",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); * GPluginNativePlugin:load-func:
@@ -230,10 +246,10 @@
* A function pointer to the load method of the plugin.
properties[PROP_LOAD_FUNC] = g_param_spec_pointer(
- "load-func", "load function pointer",
+ "load function pointer", "address pointer to load function",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); * GPluginNativePlugin:unload-func:
@@ -241,10 +257,10 @@
* A function pointer to the unload method of the plugin.
properties[PROP_UNLOAD_FUNC] = g_param_spec_pointer(
- "unload-func", "unload function pointer",
+ "unload function pointer", "address pointer to the unload function",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
@@ -253,6 +269,7 @@
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");
+ g_object_class_override_property(obj_class, PROP_ERROR, "error"); /******************************************************************************
@@ -269,9 +286,9 @@
* Returns: The %GModule associated with this plugin.
-gplugin_native_plugin_get_module(GPluginNativePlugin *plugin) {
+gplugin_native_plugin_get_module(GPluginNativePlugin *plugin) g_return_val_if_fail(GPLUGIN_IS_NATIVE_PLUGIN(plugin), NULL);
--- a/gplugin/gplugin-native-plugin.h Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin-native-plugin.h Sat Sep 05 20:05:36 2020 -0500
@@ -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,11 +29,15 @@
#define GPLUGIN_TYPE_NATIVE_PLUGIN (gplugin_native_plugin_get_type())
-G_DECLARE_FINAL_TYPE(GPluginNativePlugin, gplugin_native_plugin, GPLUGIN, NATIVE_PLUGIN, GTypeModule)
GModule *gplugin_native_plugin_get_module(GPluginNativePlugin *plugin);
#endif /* GPLUGIN_NATIVE_PLUGIN_H */
--- a/gplugin/gplugin-native-private.h Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin-native-private.h Sat Sep 05 20:05:36 2020 -0500
@@ -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,10 +29,12 @@
typedef GPluginPluginInfo *(*GPluginNativePluginQueryFunc)(GError **error);
-typedef gboolean (*GPluginNativePluginLoadFunc)(GPluginNativePlugin *plugin, GError **error);
-typedef gboolean (*GPluginNativePluginUnloadFunc)(GPluginNativePlugin *plugin, GError **error);
+ *GPluginNativePluginLoadFunc)(GPluginNativePlugin *plugin, GError **error); +typedef gboolean (*GPluginNativePluginUnloadFunc)( + GPluginNativePlugin *plugin, #endif /* GPLUGIN_PRIVATE_H */
--- a/gplugin/gplugin-native.h.in Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin-native.h.in Sat Sep 05 20:05:36 2020 -0500
@@ -1,18 +1,18 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> - * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * 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/>. --- a/gplugin/gplugin-options.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin-options.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,13 +16,12 @@
-#include <gplugin/gplugin-options.h>
+#include <glib/gi18n-lib.h> #include <gplugin/gplugin-core.h>
#include <gplugin/gplugin-manager.h>
+#include <gplugin/gplugin-options.h> * SECTION:gplugin-options
@@ -41,16 +40,18 @@
static gchar **paths = NULL;
-gplugin_options_no_default_paths_cb(G_GNUC_UNUSED const gchar *n,
- G_GNUC_UNUSED const gchar *v,
- G_GNUC_UNUSED gpointer d,
- G_GNUC_UNUSED GError **e)
+gplugin_options_no_default_paths_cb( + G_GNUC_UNUSED const gchar *n, + G_GNUC_UNUSED const gchar *v, + G_GNUC_UNUSED gpointer d, + G_GNUC_UNUSED GError **e) add_default_paths = FALSE;
static GOptionEntry entries[] = {
"no-default-paths", 'D', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
@@ -65,12 +66,14 @@
NULL, 0, 0, 0, NULL, NULL, NULL
-gplugin_options_post_parse_cb(G_GNUC_UNUSED GOptionContext *ctx,
- G_GNUC_UNUSED GOptionGroup *group,
- G_GNUC_UNUSED gpointer data,
- G_GNUC_UNUSED GError **error)
+gplugin_options_post_parse_cb( + G_GNUC_UNUSED GOptionContext *ctx, + G_GNUC_UNUSED GOptionGroup *group, + G_GNUC_UNUSED gpointer data, + G_GNUC_UNUSED GError **error) @@ -97,23 +100,27 @@
* 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
-gplugin_get_option_group(void) {
+gplugin_get_option_group(void) GOptionGroup *group = NULL;
- group = g_option_group_new("gplugin", _("GPlugin Options"),
- _("Show GPlugin Options"), NULL, NULL);
+ group = g_option_group_new( + _("Show GPlugin Options"), - g_option_group_set_parse_hooks(group, NULL,
- gplugin_options_post_parse_cb);
+ g_option_group_set_parse_hooks(group, NULL, gplugin_options_post_parse_cb); g_option_group_add_entries(group, entries);
g_option_group_set_translation_domain(group, GETTEXT_PACKAGE);
--- a/gplugin/gplugin-options.h Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin-options.h Sat Sep 05 20:05:36 2020 -0500
@@ -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 Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin-plugin-info.c Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -15,16 +15,15 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
+#include <gplugin/gplugin-core.h> +#include <gplugin/gplugin-enums.h> #include <gplugin/gplugin-plugin-info.h>
-#include <gplugin/gplugin-core.h>
-#include <gplugin/gplugin-enums.h>
#include <gplugin/gplugin-private.h>
* 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 +56,17 @@
- GPluginVersionCompareFunc version_func;
@@ -93,168 +90,185 @@
-static GParamSpec *properties[N_PROPERTIES] = {NULL,};
+static GParamSpec *properties[N_PROPERTIES] = { -G_DEFINE_TYPE_WITH_PRIVATE(GPluginPluginInfo, gplugin_plugin_info, G_TYPE_INITIALLY_UNOWNED)
+G_DEFINE_TYPE_WITH_PRIVATE( /******************************************************************************
*****************************************************************************/
-gplugin_plugin_info_set_id(GPluginPluginInfo *info, const gchar *id) {
- GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
+gplugin_plugin_info_set_id(GPluginPluginInfo *info, const gchar *id) + GPluginPluginInfoPrivate *priv = + gplugin_plugin_info_get_instance_private(info); -gplugin_plugin_info_set_abi_version(GPluginPluginInfo *info,
+gplugin_plugin_info_set_abi_version( + GPluginPluginInfo *info, - GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
+ GPluginPluginInfoPrivate *priv = + gplugin_plugin_info_get_instance_private(info); priv->abi_version = abi_version;
-gplugin_plugin_info_set_internal(GPluginPluginInfo *info, gboolean internal) {
- GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
+gplugin_plugin_info_set_internal(GPluginPluginInfo *info, gboolean internal) + GPluginPluginInfoPrivate *priv = + gplugin_plugin_info_get_instance_private(info); priv->internal = internal;
-gplugin_plugin_info_set_load_on_query(GPluginPluginInfo *info, gboolean loq) {
- GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
+gplugin_plugin_info_set_load_on_query(GPluginPluginInfo *info, gboolean loq) + GPluginPluginInfoPrivate *priv = + gplugin_plugin_info_get_instance_private(info); priv->load_on_query = loq;
-gplugin_plugin_info_set_bind_local(GPluginPluginInfo *info,
+gplugin_plugin_info_set_bind_local(GPluginPluginInfo *info, gboolean bind_local) - GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
+ GPluginPluginInfoPrivate *priv = + gplugin_plugin_info_get_instance_private(info); priv->bind_local = bind_local;
-gplugin_plugin_info_set_name(GPluginPluginInfo *info, const gchar *name) {
- GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
+gplugin_plugin_info_set_name(GPluginPluginInfo *info, const gchar *name) + GPluginPluginInfoPrivate *priv = + gplugin_plugin_info_get_instance_private(info); priv->name = g_strdup(name);
-gplugin_plugin_info_set_version(GPluginPluginInfo *info,
+gplugin_plugin_info_set_version(GPluginPluginInfo *info, const gchar *version) - GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
+ GPluginPluginInfoPrivate *priv = + gplugin_plugin_info_get_instance_private(info); priv->version = g_strdup(version);
-gplugin_plugin_info_set_version_func(GPluginPluginInfo *info,
- GPluginVersionCompareFunc func)
+gplugin_plugin_info_set_license_id( + GPluginPluginInfo *info, + const gchar *license_id) - GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
- priv->version_func = func;
-gplugin_plugin_info_set_license_id(GPluginPluginInfo *info,
- const gchar *license_id)
- GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
+ GPluginPluginInfoPrivate *priv = + gplugin_plugin_info_get_instance_private(info); g_free(priv->license_id);
priv->license_id = g_strdup(license_id);
-gplugin_plugin_info_set_license_text(GPluginPluginInfo *info,
- const gchar *license_text)
+gplugin_plugin_info_set_license_text( + GPluginPluginInfo *info, + const gchar *license_text) - GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
+ GPluginPluginInfoPrivate *priv = + gplugin_plugin_info_get_instance_private(info); g_free(priv->license_text);
priv->license_text = g_strdup(license_text);
-gplugin_plugin_info_set_license_url(GPluginPluginInfo *info,
- const gchar *license_url)
+gplugin_plugin_info_set_license_url( + GPluginPluginInfo *info, + const gchar *license_url) - GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
+ GPluginPluginInfoPrivate *priv = + gplugin_plugin_info_get_instance_private(info); g_free(priv->license_url);
priv->license_url = g_strdup(license_url);
-gplugin_plugin_info_set_icon(GPluginPluginInfo *info, const gchar *icon) {
- GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
+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); -gplugin_plugin_info_set_summary(GPluginPluginInfo *info,
+gplugin_plugin_info_set_summary(GPluginPluginInfo *info, const gchar *summary) - GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
+ GPluginPluginInfoPrivate *priv = + gplugin_plugin_info_get_instance_private(info); priv->summary = g_strdup(summary);
-gplugin_plugin_info_set_description(GPluginPluginInfo *info,
- const gchar *description)
+gplugin_plugin_info_set_description( + GPluginPluginInfo *info, + const gchar *description) - GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
+ GPluginPluginInfoPrivate *priv = + gplugin_plugin_info_get_instance_private(info); g_free(priv->description);
priv->description = g_strdup(description);
-gplugin_plugin_info_set_category(GPluginPluginInfo *info,
+gplugin_plugin_info_set_category(GPluginPluginInfo *info, const gchar *category) - GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
+ GPluginPluginInfoPrivate *priv = + gplugin_plugin_info_get_instance_private(info); priv->category = g_strdup(category);
-gplugin_plugin_info_set_authors(GPluginPluginInfo *info,
- const gchar * const *authors) {
- GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
+gplugin_plugin_info_set_authors( + GPluginPluginInfo *info, + const gchar *const *authors) + GPluginPluginInfoPrivate *priv = + gplugin_plugin_info_get_instance_private(info); g_strfreev(priv->authors);
@@ -262,29 +276,22 @@
-gplugin_plugin_info_set_help(GPluginPluginInfo *info, const gchar *help)
+gplugin_plugin_info_set_website(GPluginPluginInfo *info, const gchar *website) - GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
- priv->help = g_strdup(help);
-gplugin_plugin_info_set_website(GPluginPluginInfo *info,
- GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
+ GPluginPluginInfoPrivate *priv = + gplugin_plugin_info_get_instance_private(info); priv->website = g_strdup(website);
-gplugin_plugin_info_set_dependencies(GPluginPluginInfo *info,
- const gchar * const *dependencies)
+gplugin_plugin_info_set_dependencies( + GPluginPluginInfo *info, + const gchar *const *dependencies) - GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
+ GPluginPluginInfoPrivate *priv = + gplugin_plugin_info_get_instance_private(info); g_strfreev(priv->dependencies);
@@ -295,8 +302,11 @@
*****************************************************************************/
-gplugin_plugin_info_get_property(GObject *obj, guint param_id, GValue *value,
+gplugin_plugin_info_get_property( GPluginPluginInfo *info = GPLUGIN_PLUGIN_INFO(obj);
@@ -311,12 +321,14 @@
g_value_set_boolean(value, gplugin_plugin_info_get_internal(info));
- g_value_set_boolean(value,
- gplugin_plugin_info_get_load_on_query(info));
+ gplugin_plugin_info_get_load_on_query(info)); - g_value_set_boolean(value,
- gplugin_plugin_info_get_bind_local(info));
+ gplugin_plugin_info_get_bind_local(info)); g_value_set_string(value, gplugin_plugin_info_get_name(info));
@@ -324,31 +336,29 @@
g_value_set_string(value, gplugin_plugin_info_get_version(info));
- case PROP_VERSION_FUNC:
- g_value_set_pointer(value,
- gplugin_plugin_info_get_version_func(info));
- g_value_set_string(value,
- gplugin_plugin_info_get_license_id(info));
+ g_value_set_string(value, gplugin_plugin_info_get_license_id(info)); - g_value_set_string(value,
- gplugin_plugin_info_get_license_text(info));
+ gplugin_plugin_info_get_license_text(info)); - g_value_set_string(value,
- gplugin_plugin_info_get_license_url(info));
+ 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));
- g_value_set_string(value,
- gplugin_plugin_info_get_description(info));
+ gplugin_plugin_info_get_description(info)); g_value_set_string(value, gplugin_plugin_info_get_category(info));
@@ -356,15 +366,13 @@
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));
- g_value_set_boxed(value,
- gplugin_plugin_info_get_dependencies(info));
+ gplugin_plugin_info_get_dependencies(info)); G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
@@ -373,8 +381,11 @@
-gplugin_plugin_info_set_property(GObject *obj, guint param_id,
- const GValue *value, GParamSpec *pspec)
+gplugin_plugin_info_set_property( GPluginPluginInfo *info = GPLUGIN_PLUGIN_INFO(obj);
@@ -389,12 +400,14 @@
gplugin_plugin_info_set_internal(info, g_value_get_boolean(value));
- gplugin_plugin_info_set_load_on_query(info,
- g_value_get_boolean(value));
+ gplugin_plugin_info_set_load_on_query( + g_value_get_boolean(value)); - gplugin_plugin_info_set_bind_local(info,
- g_value_get_boolean(value));
+ gplugin_plugin_info_set_bind_local( + g_value_get_boolean(value)); gplugin_plugin_info_set_name(info, g_value_get_string(value));
@@ -402,31 +415,29 @@
gplugin_plugin_info_set_version(info, g_value_get_string(value));
- case PROP_VERSION_FUNC:
- gplugin_plugin_info_set_version_func(info,
- g_value_get_pointer(value));
- gplugin_plugin_info_set_license_id(info,
- g_value_get_string(value));
+ gplugin_plugin_info_set_license_id(info, g_value_get_string(value)); - gplugin_plugin_info_set_license_text(info,
- g_value_get_string(value));
+ gplugin_plugin_info_set_license_text( + g_value_get_string(value)); - gplugin_plugin_info_set_license_url(info,
- g_value_get_string(value));
+ gplugin_plugin_info_set_license_url( + 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));
- gplugin_plugin_info_set_description(info,
- g_value_get_string(value));
+ gplugin_plugin_info_set_description( + g_value_get_string(value)); gplugin_plugin_info_set_category(info, g_value_get_string(value));
@@ -434,15 +445,13 @@
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));
- gplugin_plugin_info_set_dependencies(info,
- g_value_get_boxed(value));
+ gplugin_plugin_info_set_dependencies( + g_value_get_boxed(value)); G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
@@ -451,8 +460,10 @@
-gplugin_plugin_info_finalize(GObject *obj) {
- GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(GPLUGIN_PLUGIN_INFO(obj));
+gplugin_plugin_info_finalize(GObject *obj) + GPluginPluginInfoPrivate *priv = + gplugin_plugin_info_get_instance_private(GPLUGIN_PLUGIN_INFO(obj)); g_clear_pointer(&priv->id, g_free);
g_clear_pointer(&priv->name, g_free);
@@ -460,23 +471,25 @@
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);
+ g_clear_pointer(&priv->category, g_free); G_OBJECT_CLASS(gplugin_plugin_info_parent_class)->finalize(obj);
-gplugin_plugin_info_init(G_GNUC_UNUSED GPluginPluginInfo *info) {
+gplugin_plugin_info_init(G_GNUC_UNUSED GPluginPluginInfo *info) -gplugin_plugin_info_class_init(GPluginPluginInfoClass *klass) {
+gplugin_plugin_info_class_init(GPluginPluginInfoClass *klass) GObjectClass *obj_class = G_OBJECT_CLASS(klass);
obj_class->get_property = gplugin_plugin_info_get_property;
@@ -492,54 +505,57 @@
* 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(
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); * GPluginPluginInfo:abi-version:
* 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
properties[PROP_ABI_VERSION] = g_param_spec_uint(
- "abi-version", "abi_version",
"The ABI version of the plugin",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); * GPluginPluginInfo:internal:
* Whether or not the plugin is considered an "internal" plugin.
properties[PROP_INTERNAL] = g_param_spec_boolean(
- "internal", "internal",
"Whether or not the plugin is an internal plugin",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); * GPluginPluginInfo:load-on-query:
@@ -549,28 +565,28 @@
* 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",
"Whether or not the plugin should be loaded when queried",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); * 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.
properties[PROP_BIND_LOCAL] = g_param_spec_boolean(
- "bind-local", "bind-local",
"Whether symbols should be bound locally",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); * GPluginPluginInfo:name:
@@ -578,34 +594,23 @@
* The display name of the plugin. This should be a translated string.
properties[PROP_NAME] = g_param_spec_string(
"The name of the plugin",
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); * GPluginPluginInfo:version:
- * The version of the plugin.
+ * The version of the plugin. Preferably a semantic version. properties[PROP_VERSION] = g_param_spec_string(
"The version of the plugin",
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
- * GPluginPluginInfo:version-func:
- * The function to use to compare versions of this plugin.
- properties[PROP_VERSION_FUNC] = g_param_spec_pointer(
- "version-func", "version-func",
- "The function that can compare versions of this plugin",
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); * GPluginPluginInfo:license-id:
@@ -613,58 +618,58 @@
* 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
* the same time, they should be separated by an ampersand (&).
properties[PROP_LICENSE_ID] = g_param_spec_string(
- "license-id", "license-id",
"The license id of the plugin according to SPDX",
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); * 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",
"The text of the license for the plugin",
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); * 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",
"The url to the license of the plugin",
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); - * 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( + "The XDG icon name for the plugin", - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); * GPluginPluginInfo:summary:
@@ -673,11 +678,11 @@
properties[PROP_SUMMARY] = g_param_spec_string(
"The summary of the plugin",
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); * GPluginPluginInfo:description:
@@ -686,11 +691,11 @@
* information" section in a user interface.
properties[PROP_DESCRIPTION] = g_param_spec_string(
- "description", "description",
"The description of the plugin",
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); * GPluginPluginInfo:category:
@@ -703,39 +708,26 @@
* that don't match this category into an "Other" category.
properties[PROP_CATEGORY] = g_param_spec_string(
- "category", "category",
"The category of the plugin",
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); * 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(
"The authors of the plugin",
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
- * 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
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); * GPluginPluginInfo:website:
@@ -743,11 +735,11 @@
* The url of the plugin that can be represented in a user interface.
properties[PROP_WEBSITE] = g_param_spec_string(
"The website of the plugin",
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); * GPluginPluginInfo:dependencies:
@@ -755,11 +747,11 @@
* A comma separated list of plugin id's that this plugin depends on.
properties[PROP_DEPENDENCIES] = g_param_spec_boxed(
- "dependencies", "dependencies",
"The dependencies of the plugin",
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
@@ -770,25 +762,26 @@
* 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.
* Returns: The id from @info.
-gplugin_plugin_info_get_id(GPluginPluginInfo *info) {
+gplugin_plugin_info_get_id(GPluginPluginInfo *info) GPluginPluginInfoPrivate *priv = NULL;
g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
@@ -800,7 +793,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.
@@ -808,7 +801,8 @@
* Returns: The abi_version from @info.
-gplugin_plugin_info_get_abi_version(GPluginPluginInfo *info) {
+gplugin_plugin_info_get_abi_version(GPluginPluginInfo *info) GPluginPluginInfoPrivate *priv = NULL;
g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), 0);
@@ -820,16 +814,17 @@
* 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) {
+gplugin_plugin_info_get_internal(GPluginPluginInfo *info) GPluginPluginInfoPrivate *priv = NULL;
g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), FALSE);
@@ -841,17 +836,18 @@
* 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) {
+gplugin_plugin_info_get_load_on_query(GPluginPluginInfo *info) GPluginPluginInfoPrivate *priv = NULL;
g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), FALSE);
@@ -863,14 +859,15 @@
* gplugin_plugin_info_get_name:
- * @info: #GPluginPluginInfo instance
+ * @info: The #GPluginPluginInfo instance. * Returns the name of the plugin as specified in @info.
* Returns: The name from @info.
-gplugin_plugin_info_get_name(GPluginPluginInfo *info) {
+gplugin_plugin_info_get_name(GPluginPluginInfo *info) GPluginPluginInfoPrivate *priv = NULL;
g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
@@ -882,14 +879,15 @@
* gplugin_plugin_info_get_version:
- * @info: #GPluginPluginInfo instance
+ * @info: The #GPluginPluginInfo instance. * Returns the version of the plugin as specified in @info.
* Returns: The version from @info.
-gplugin_plugin_info_get_version(GPluginPluginInfo *info) {
+gplugin_plugin_info_get_version(GPluginPluginInfo *info) GPluginPluginInfoPrivate *priv = NULL;
g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
@@ -900,36 +898,16 @@
- * 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.
* Returns: The license-id from @info.
-gplugin_plugin_info_get_license_id(GPluginPluginInfo *info) {
+gplugin_plugin_info_get_license_id(GPluginPluginInfo *info) GPluginPluginInfoPrivate *priv = NULL;
g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
@@ -941,14 +919,15 @@
* gplugin_plugin_info_get_license_text:
- * @info: #GPluginPluginInfo instance
+ * @info: The #GPluginPluginInfo instance. * Returns the license text for the plugin as specified in @info.
* Returns: The text of the license from @info.
-gplugin_plugin_info_get_license_text(GPluginPluginInfo *info) {
+gplugin_plugin_info_get_license_text(GPluginPluginInfo *info) GPluginPluginInfoPrivate *priv = NULL;
g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
@@ -960,14 +939,15 @@
* 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
* Returns: The url of the license from @info.
-gplugin_plugin_info_get_license_url(GPluginPluginInfo *info) {
+gplugin_plugin_info_get_license_url(GPluginPluginInfo *info) GPluginPluginInfoPrivate *priv = NULL;
g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
@@ -978,34 +958,36 @@
- * 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.
* Returns: The summary from @info.
-gplugin_plugin_info_get_summary(GPluginPluginInfo *info) {
+gplugin_plugin_info_get_summary(GPluginPluginInfo *info) GPluginPluginInfoPrivate *priv = NULL;
g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
@@ -1017,14 +999,15 @@
* gplugin_plugin_info_get_description:
- * @info: #GPluginPluginInfo instance
+ * @info: The #GPluginPluginInfo instance. * Returns the description for the plugin as specified in @info.
* Returns: The description from @info.
-gplugin_plugin_info_get_description(GPluginPluginInfo *info) {
+gplugin_plugin_info_get_description(GPluginPluginInfo *info) GPluginPluginInfoPrivate *priv = NULL;
g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
@@ -1036,14 +1019,15 @@
* gplugin_plugin_info_get_category:
- * @info: #GPluginPluginInfo instance
+ * @info: The #GPluginPluginInfo instance. * Returns the category of the plugin as specified in @info.
* Returns: The category from @info.
-gplugin_plugin_info_get_category(GPluginPluginInfo *info) {
+gplugin_plugin_info_get_category(GPluginPluginInfo *info) GPluginPluginInfoPrivate *priv = NULL;
g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
@@ -1055,52 +1039,35 @@
* gplugin_plugin_info_get_authors:
- * @info: #GPluginPluginInfo instance
+ * @info: The #GPluginPluginInfo instance. * Returns the authors of the plugin as specified in @info.
* Returns: (array zero-terminated=1) (transfer none): The authors from @info.
-gplugin_plugin_info_get_authors(GPluginPluginInfo *info) {
+gplugin_plugin_info_get_authors(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 (const gchar * const *)priv->authors;
- * 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);
+ return (const gchar *const *)priv->authors; * gplugin_plugin_info_get_website:
- * @info: #GPluginPluginInfo instance
+ * @info: The #GPluginPluginInfo instance. * Returns the website for the plugin as specified in @info.
* Returns: The website from @info.
-gplugin_plugin_info_get_website(GPluginPluginInfo *info) {
+gplugin_plugin_info_get_website(GPluginPluginInfo *info) GPluginPluginInfoPrivate *priv = NULL;
g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
@@ -1112,35 +1079,37 @@
* gplugin_plugin_info_get_dependencies:
- * @info: #GPluginPluginInfo instance
+ * @info: The #GPluginPluginInfo instance. * Returns the dependencies of the plugins as specified in @info.
* Returns: (array zero-terminated=1) (transfer none): The list of
* dependencies from @info.
-gplugin_plugin_info_get_dependencies(GPluginPluginInfo *info) {
+gplugin_plugin_info_get_dependencies(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 (const gchar * const *)priv->dependencies;
+ return (const gchar *const *)priv->dependencies; * 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) {
+gplugin_plugin_info_get_bind_local(GPluginPluginInfo *info) GPluginPluginInfoPrivate *priv = NULL;
g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), FALSE);
@@ -1149,4 +1118,3 @@
--- a/gplugin/gplugin-plugin-info.h Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin-plugin-info.h Sat Sep 05 20:05:36 2020 -0500
@@ -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,25 +28,31 @@
#define GPLUGIN_TYPE_PLUGIN_INFO (gplugin_plugin_info_get_type())
-G_DECLARE_DERIVABLE_TYPE(GPluginPluginInfo, gplugin_plugin_info, GPLUGIN, PLUGIN_INFO, GInitiallyUnowned)
+G_DECLARE_DERIVABLE_TYPE( #include <gplugin/gplugin-loader.h>
#include <gplugin/gplugin-version.h>
struct _GPluginPluginInfoClass {
- GInitiallyUnownedClass gparent;
#define gplugin_plugin_info_new(id, abi_version, ...) \
- g_object_new(GPLUGIN_TYPE_PLUGIN_INFO, \
- "abi-version", (abi_version), \
+ GPLUGIN_PLUGIN_INFO(g_object_new( \ + GPLUGIN_TYPE_PLUGIN_INFO, \ + "abi-version", (abi_version), \ const gchar *gplugin_plugin_info_get_id(GPluginPluginInfo *info);
guint32 gplugin_plugin_info_get_abi_version(GPluginPluginInfo *info);
@@ -57,17 +63,15 @@
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 *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);
-GPluginVersionCompareFunc gplugin_plugin_info_get_version_func(GPluginPluginInfo *info);
-const gchar *gplugin_plugin_info_get_help(GPluginPluginInfo *info);
+const gchar *const *gplugin_plugin_info_get_dependencies( + GPluginPluginInfo *info); #endif /* GPLUGIN_PLUGIN_INFO_H */
--- a/gplugin/gplugin-plugin.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin-plugin.c Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -15,32 +15,32 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
+#include <gplugin/gplugin-enums.h> #include <gplugin/gplugin-plugin.h>
-#include <gplugin/gplugin-enums.h>
#include <gplugin/gplugin-private.h>
- * @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. + * @GPLUGIN_PLUGIN_STATE_UNLOAD_FAILED: The plugin failed to unload. - * 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
@@ -70,7 +71,9 @@
-static guint signals[SIG_LAST] = {0, };
+static guint signals[SIG_LAST] = { G_DEFINE_INTERFACE(GPluginPlugin, gplugin_plugin, G_TYPE_INVALID);
@@ -78,7 +81,8 @@
*****************************************************************************/
-gplugin_plugin_default_init(GPluginPluginInterface *iface) {
+gplugin_plugin_default_init(GPluginPluginInterface *iface) GParamSpec *pspec = NULL;
@@ -87,11 +91,11 @@
* The absolute path to the plugin on disk.
pspec = g_param_spec_string(
- "filename", "filename",
"The filename of the plugin",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_interface_install_property(iface, pspec);
@@ -100,11 +104,11 @@
* The #GPluginLoader that loaded this plugin.
pspec = g_param_spec_object(
"The loader for this plugin",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_interface_install_property(iface, pspec);
@@ -113,11 +117,11 @@
* The #GPluginPluginInfo from this plugin.
pspec = g_param_spec_object(
"The information for the plugin",
GPLUGIN_TYPE_PLUGIN_INFO,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_interface_install_property(iface, pspec);
@@ -126,12 +130,25 @@
* The #GPluginPluginState that this plugin is in.
pspec = g_param_spec_enum(
"The state of the plugin",
GPLUGIN_TYPE_PLUGIN_STATE,
GPLUGIN_PLUGIN_STATE_UNKNOWN,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + g_object_interface_install_property(iface, pspec); + * A #GError returned the plugin if it failed to load or unload. + pspec = g_param_spec_boxed( + "A GError returned from the load or unload function", + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_interface_install_property(iface, pspec);
@@ -142,18 +159,18 @@
* Emitted when @plugin changes state.
- signals[SIG_STATE_CHANGED] =
- g_signal_new("state-changed",
- G_STRUCT_OFFSET(GPluginPluginInterface, state_changed),
- GPLUGIN_TYPE_PLUGIN_STATE,
- GPLUGIN_TYPE_PLUGIN_STATE);
+ signals[SIG_STATE_CHANGED] = g_signal_new( + G_STRUCT_OFFSET(GPluginPluginInterface, state_changed), + GPLUGIN_TYPE_PLUGIN_STATE, + GPLUGIN_TYPE_PLUGIN_STATE); /******************************************************************************
@@ -162,14 +179,15 @@
* 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) {
+gplugin_plugin_get_filename(GPluginPlugin *plugin) g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), NULL);
@@ -181,14 +199,15 @@
* 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) {
+gplugin_plugin_get_loader(GPluginPlugin *plugin) GPluginLoader *loader = NULL;
g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), NULL);
@@ -200,14 +219,15 @@
* 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) {
+gplugin_plugin_get_info(GPluginPlugin *plugin) GPluginPluginInfo *info = NULL;
g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), NULL);
@@ -219,17 +239,20 @@
* 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) {
+gplugin_plugin_get_state(GPluginPlugin *plugin) GPluginPluginState state = GPLUGIN_PLUGIN_STATE_UNKNOWN;
- g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), GPLUGIN_PLUGIN_STATE_UNKNOWN);
+ GPLUGIN_IS_PLUGIN(plugin), + GPLUGIN_PLUGIN_STATE_UNKNOWN); g_object_get(G_OBJECT(plugin), "state", &state, NULL);
@@ -238,14 +261,15 @@
* 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
-gplugin_plugin_set_state(GPluginPlugin *plugin, GPluginPluginState state) {
+gplugin_plugin_set_state(GPluginPlugin *plugin, GPluginPluginState state) GPluginPluginState oldstate = GPLUGIN_PLUGIN_STATE_UNKNOWN;
g_return_if_fail(GPLUGIN_IS_PLUGIN(plugin));
@@ -254,6 +278,26 @@
g_object_set(G_OBJECT(plugin), "state", state, NULL);
- g_signal_emit(plugin, signals[SIG_STATE_CHANGED], 0,
+ g_signal_emit(plugin, signals[SIG_STATE_CHANGED], 0, oldstate, state); + * gplugin_plugin_get_error: + * @plugin: The #GPluginPlugin instance. + * Gets the #GError, if any, that the plugin returned during load or unload. + * Returns: (transfer full): The #GError the plugin returned during load or + * unload, or %NULL if no error occurred. +gplugin_plugin_get_error(GPluginPlugin *plugin) + g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), NULL); + g_object_get(G_OBJECT(plugin), "error", &error, NULL); --- a/gplugin/gplugin-plugin.h Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin-plugin.h Sat Sep 05 20:05:36 2020 -0500
@@ -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,6 +25,7 @@
typedef enum /*< prefix=GPLUGIN_PLUGIN_STATE,underscore_name=GPLUGIN_PLUGIN_STATE >*/ {
GPLUGIN_PLUGIN_STATE_UNKNOWN = -1,
GPLUGIN_PLUGIN_STATE_ERROR = 0,
@@ -32,10 +33,12 @@
GPLUGIN_PLUGIN_STATE_REQUERY,
GPLUGIN_PLUGIN_STATE_LOADED,
GPLUGIN_PLUGIN_STATE_LOAD_FAILED,
+ GPLUGIN_PLUGIN_STATE_UNLOAD_FAILED, GPLUGIN_PLUGIN_STATES, /*< skip >*/
@@ -43,15 +46,18 @@
G_DECLARE_INTERFACE(GPluginPlugin, gplugin_plugin, GPLUGIN, PLUGIN, GObject)
/* circular dependencies suck... */
+#include <gplugin/gplugin-loader.h> #include <gplugin/gplugin-plugin-info.h>
-#include <gplugin/gplugin-loader.h>
struct _GPluginPluginInterface {
- void (*state_changed)(GPluginPlugin *plugin, GPluginPluginState oldstate, GPluginPluginState newstate);
+ GPluginPluginState oldstate, + GPluginPluginState newstate); @@ -64,7 +70,8 @@
GPluginPluginState gplugin_plugin_get_state(GPluginPlugin *plugin);
void gplugin_plugin_set_state(GPluginPlugin *plugin, GPluginPluginState state);
+GError *gplugin_plugin_get_error(GPluginPlugin *plugin); #endif /* GPLUGIN_PLUGIN_H */
--- a/gplugin/gplugin-private.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin-private.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,10 +19,11 @@
/* A GSignalAccumulator that stops emission if a handler returns FALSE */
-gplugin_boolean_accumulator(G_GNUC_UNUSED GSignalInvocationHint *hint,
- const GValue *handler_return,
- G_GNUC_UNUSED gpointer data)
+gplugin_boolean_accumulator( + G_GNUC_UNUSED GSignalInvocationHint *hint, + const GValue *handler_return, + G_GNUC_UNUSED gpointer data) gboolean continue_emission;
gboolean handler_returned;
@@ -33,4 +34,3 @@
return continue_emission;
--- a/gplugin/gplugin-private.h Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin-private.h Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -14,30 +14,33 @@
* 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/>.
-#if !defined(GPLUGIN_GLOBAL_HEADER_INSIDE) && !defined(GPLUGIN_COMPILATION)
-#error "only <gplugin.h> may be included directly"
#ifndef GPLUGIN_PRIVATE_H
#define GPLUGIN_PRIVATE_H
+/* this gets included by some tests so we need to trick the headers to accept +#define GPLUGIN_GLOBAL_HEADER_INSIDE +#include <gplugin/gplugin-plugin-info.h> #include <gplugin/gplugin-plugin.h>
-#include <gplugin/gplugin-plugin-info.h>
+#undef GPLUGIN_GLOBAL_HEADER_INSIDE void gplugin_manager_private_init(void);
void gplugin_manager_private_uninit(void);
-gboolean gplugin_boolean_accumulator(GSignalInvocationHint *hint, GValue *return_accu, const GValue *handler_return, gpointer data);
+gboolean gplugin_boolean_accumulator( + GSignalInvocationHint *hint, + const GValue *handler_return, gboolean gplugin_plugin_info_get_bind_local(GPluginPluginInfo *info);
#endif /* GPLUGIN_PRIVATE_H */
--- a/gplugin/gplugin-query.c Thu Nov 07 23:09:55 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,350 +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/>.
-/******************************************************************************
- *****************************************************************************/
-static gint verbosity = 0;
-static gboolean show_internal = FALSE;
-static gboolean output_paths = FALSE;
-static gboolean exit_early = FALSE;
-/******************************************************************************
- *****************************************************************************/
-verbosity_cb(G_GNUC_UNUSED const gchar *n,
- G_GNUC_UNUSED const gchar *v,
- G_GNUC_UNUSED gpointer d,
- G_GNUC_UNUSED GError **e)
-full_verbosity_cb(G_GNUC_UNUSED const gchar *n,
- G_GNUC_UNUSED const gchar *v,
- G_GNUC_UNUSED gpointer d,
- G_GNUC_UNUSED GError **e)
-internal_cb(G_GNUC_UNUSED const gchar *n,
- G_GNUC_UNUSED const gchar *v,
- G_GNUC_UNUSED gpointer d,
- G_GNUC_UNUSED GError **e)
-version_cb(G_GNUC_UNUSED const gchar *n,
- G_GNUC_UNUSED const gchar *v,
- G_GNUC_UNUSED gpointer d,
- G_GNUC_UNUSED GError **e)
- printf("gplugin-query %s\n", GPLUGIN_VERSION);
-list_cb(G_GNUC_UNUSED const gchar *n,
- G_GNUC_UNUSED const gchar *v,
- G_GNUC_UNUSED gpointer d,
- G_GNUC_UNUSED GError **e)
-output_plugin(const gchar *id) {
- GSList *plugins = NULL, *l = NULL;
- gboolean first = TRUE, header_output = FALSE;
- #define MAIN_FORMAT_NEL " " FORMAT ": "
- #define MAIN_FORMAT MAIN_FORMAT_NEL "%s\n"
- #define STR_OR_EMPTY(str) ((str) ? (str) : "")
- plugins = gplugin_manager_find_plugins(id);
- printf("%s not found\n", id);
- for(l = plugins; l; l = l->next) {
- GPluginPlugin *plugin = GPLUGIN_PLUGIN(l->data);
- GPluginPluginInfo *info = gplugin_plugin_get_info(plugin);
- gboolean internal, loq;
- gchar *license_id, *license_text, *license_url;
- gchar *icon, *summary, *description, *category, *website;
- gchar **authors, **dependencies;
- internal = gplugin_plugin_info_get_internal(info);
- if(!show_internal && internal)
- g_object_get(G_OBJECT(info),
- "abi-version", &abi_version,
- "license-id", &license_id,
- "license-text", &license_text,
- "license-url", &license_url,
- "description", &description,
- "dependencies", &dependencies,
- printf(MAIN_FORMAT, "name", STR_OR_EMPTY(name));
- printf(MAIN_FORMAT, "category", STR_OR_EMPTY(category));
- printf(MAIN_FORMAT, "version", STR_OR_EMPTY(version));
- printf(MAIN_FORMAT, "license", STR_OR_EMPTY(license_id));
- printf(MAIN_FORMAT, "license url", STR_OR_EMPTY(license_url));
- printf(MAIN_FORMAT, "summary", STR_OR_EMPTY(summary));
- printf(MAIN_FORMAT_NEL, "authors");
- for(i = 0; authors[i]; i++) {
- printf("%s\n", STR_OR_EMPTY(authors[i]));
- printf(MAIN_FORMAT, "website", STR_OR_EMPTY(website));
- printf(MAIN_FORMAT, "filename",
- STR_OR_EMPTY(gplugin_plugin_get_filename(plugin)));
- GPluginLoader *loader = gplugin_plugin_get_loader(plugin);
- printf(MAIN_FORMAT_NEL "%08x\n", "abi version", abi_version);
- printf(MAIN_FORMAT, "internal", (internal) ? "yes" : "no");
- printf(MAIN_FORMAT, "load on query", (loq) ? "yes" : "no");
- printf(MAIN_FORMAT, "loader", G_OBJECT_TYPE_NAME(loader));
- g_object_unref(G_OBJECT(loader));
- printf(MAIN_FORMAT, "description", STR_OR_EMPTY(description));
- printf(MAIN_FORMAT_NEL, "dependencies");
- for(i = 0; dependencies[i]; i++) {
- printf("%s\n", STR_OR_EMPTY(dependencies[i]));
- g_strfreev(dependencies);
- g_object_unref(G_OBJECT(info));
- gplugin_manager_free_plugin_list(plugins);
-output_plugins(GList *plugins) {
- gboolean ret = TRUE, first = TRUE;
- for(l = plugins; l; l = l->next) {
- if(!output_plugin(l->data))
-/******************************************************************************
- *****************************************************************************/
-static GOptionEntry entries[] = {
- "internal", 'i', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
- internal_cb, N_("Show internal plugins"),
- "verbose", 'v', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
- verbosity_cb, N_("Increase verbosity"),
- "full-verbose", 'V', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
- full_verbosity_cb, N_("Increase verbosity to eleven"),
- "version", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
- version_cb, N_("Display the version and exit"),
- "list", 'L', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
- list_cb, N_("Display all search paths and exit"),
- NULL, 0, 0, 0, NULL, NULL, NULL,
-main(gint argc, gchar **argv) {
- GOptionContext *ctx = NULL;
- GOptionGroup *group = NULL;
- ctx = g_option_context_new("PLUGIN-ID...");
- g_option_context_set_summary(ctx, _("Query installed plugins"));
- g_option_context_set_translation_domain(ctx, GETTEXT_PACKAGE);
- g_option_context_add_main_entries(ctx, entries, NULL);
- group = gplugin_get_option_group();
- g_option_context_add_group(ctx, group);
- g_option_context_parse(ctx, &argc, &argv, &error);
- g_option_context_free(ctx);
- fprintf(stderr, "%s\n", error->message);
- for(path = gplugin_manager_get_paths(); path; path = path->next) {
- printf("%s\n", (gchar *)path->data);
- gplugin_manager_refresh();
- /* check if the user gave us atleast one plugin, and output them */
- GQueue *plugins = g_queue_new();
- for(i = 1; i < argc; i++) {
- if(strlen(argv[i]) == 0)
- g_queue_push_tail(plugins, argv[i]);
- if(!output_plugins(plugins->head))
- GList *plugins = gplugin_manager_list_plugins();
- if(!output_plugins(plugins))
--- a/gplugin/gplugin-version.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin-version.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,47 +18,47 @@
* 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 <glib/gi18n-lib.h> #include <gplugin/gplugin-core.h>
#include <gplugin/gplugin-version.h>
/******************************************************************************
*****************************************************************************/
-static const gchar *version_pattern = "^(?P<major>\\d+)(\\." \
- "(\\.(?P<micro>\\d+)(?P<extra>.*))?)?$";
+static const gchar *version_pattern = "^(?P<major>\\d+)(\\." + "(\\.(?P<micro>\\d+)(?P<extra>.*))?)?$"; /******************************************************************************
*****************************************************************************/
-gplugin_version_lazy_init(void) {
+gplugin_version_lazy_init(void) static volatile gsize init_volatile = 0;
if(g_once_init_enter(&init_volatile)) {
- regex = g_regex_new(version_pattern, G_REGEX_NO_AUTO_CAPTURE,
+ g_regex_new(version_pattern, G_REGEX_NO_AUTO_CAPTURE, 0, &error); - g_warning(_("Failed to initialize the version regex: %s"),
- (error->message) ? error->message :
+ _("Failed to initialize the version regex: %s"), + (error->message) ? error->message : _("unknown")); @@ -66,20 +66,57 @@
-gplugin_version_parser(const gchar *v, gint *major, gint *minor, gint *micro,
- gchar **extra, GError **error)
+ * gplugin_version_parser: + * @version: The string version to parse. + * @major: (out) (nullable): A return gint pointer for the major version. + * @minor: (out) (nullable): A return gint pointer for the minor version. + * @micro: (out) (nullable): A return gint pointer for the micro version. + * @extra: (out) (nullable): A return gchar * pointer for any extra version + * Attempts to parse a version string into its @major, @minor, @micro, and + * @extra parts. If @version doesn't match a semantic version string, @major + * will be set to %-1, @minor will be set to %0, and @micro will be set to %0. gboolean matches = FALSE;
- matches = g_regex_match(regex, v, 0, &info);
+ /* initialize everything to our failed state */ + /* if a version was not provided, return our failed values */ + matches = g_regex_match(regex, version, 0, &info); - g_set_error(error, GPLUGIN_DOMAIN, 0,
- _("%s does not match the version regex"), v);
+ /* If we failed to match the regex, free info and return our failed + g_match_info_unref(info);
/* grab the major version */
@@ -104,12 +141,11 @@
/* grab the extra version */
*extra = g_match_info_fetch_named(info, "extra");
g_match_info_unref(info);
/******************************************************************************
@@ -148,72 +184,97 @@
- * @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. - * 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) {
+gplugin_version_compare(const gchar *v1, const gchar *v2) gint v1_maj = 0, v1_min = 0, v1_mic = 0;
gint v2_maj = 0, v2_min = 0, v2_mic = 0;
- g_return_val_if_fail(v1 != NULL, 1);
- g_return_val_if_fail(v2 != NULL, 2);
gplugin_version_lazy_init();
- /* make sure v1 matches the regex */
- if(!gplugin_version_parser(v1, &v1_maj, &v1_min, &v1_mic, NULL, error))
+ gplugin_version_parser(v1, &v1_maj, &v1_min, &v1_mic, NULL); - /* make sure v2 matches the regex */
- if(!gplugin_version_parser(v2, &v2_maj, &v2_min, &v2_mic, NULL, error))
+ gplugin_version_parser(v2, &v2_maj, &v2_min, &v2_mic, NULL); /* now figure out if they match */
- return v2_mic - v1_mic;
+ return v1_mic - v2_mic;
--- a/gplugin/gplugin-version.h.in Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin-version.h.in Sat Sep 05 20:05:36 2020 -0500
@@ -1,18 +1,18 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> - * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * 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/>. #if !defined(GPLUGIN_GLOBAL_HEADER_INSIDE) && !defined(GPLUGIN_COMPILATION)
@@ -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);
+gint gplugin_version_compare(const gchar *v1, const gchar *v2); #endif /* GPLUGIN_VERSION_H */
--- a/gplugin/gplugin.h.in Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/gplugin.h.in Sat Sep 05 20:05:36 2020 -0500
@@ -1,18 +1,18 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> - * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * 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/>. @@ -26,5 +26,3 @@
#undef GPLUGIN_GLOBAL_HEADER_INSIDE
--- a/gplugin/meson.build Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/meson.build Sat Sep 05 20:05:36 2020 -0500
@@ -69,7 +69,7 @@
- install_dir : join_paths(get_option('includedir'), 'gplugin-1.0', 'gplugin'))
+ install_dir : get_option('includedir') / 'gplugin-1.0' / 'gplugin') @@ -95,7 +95,7 @@
output : 'gplugin-version.h',
configuration : version_conf,
- install_dir : join_paths(get_option('includedir'), 'gplugin-1.0', 'gplugin')
+ install_dir : get_option('includedir') / 'gplugin-1.0' / 'gplugin' GPLUGIN_PUBLIC_BUILT_HEADERS += [
@@ -126,7 +126,7 @@
- install_dir : join_paths(get_option('includedir'), 'gplugin-1.0'))
+ install_dir : get_option('includedir') / 'gplugin-1.0') GPLUGIN_NATIVE_H_INCLUDES = ''
@@ -143,7 +143,7 @@
output : 'gplugin-native.h',
- install_dir : join_paths(get_option('includedir'), 'gplugin-1.0'))
+ install_dir : get_option('includedir') / 'gplugin-1.0') ###############################################################################
@@ -175,39 +175,18 @@
description : 'A fully featured GModule based plugin library',
- version : meson.project_version(),
- requires : ['glib-2.0', 'gobject-2.0', 'gmodule-2.0'],
+ requires : [GLIB, GOBJECT, GMODULE], ###############################################################################
-# gplugin-query executable
-###############################################################################
-gplugin_query = executable('gplugin-query',
- dependencies : [gplugin_dep, GLIB, GOBJECT],
-if get_option('help2man')
- custom_target('gplugin-query.1',
- '--name=Query installed plugins', '--section=1',
- '--help-option=--help-all', '--no-info',
- '--output', '@OUTPUT@',
- output : 'gplugin-query.1',
- install_dir : join_paths(get_option('mandir'), 'man1'))
-###############################################################################
# loader-tests static library
###############################################################################
gplugin_loader_tests = static_library('gplugin-loader-tests',
@@ -220,7 +199,7 @@
###############################################################################
###############################################################################
-if get_option('gobject-introspection')
+if get_option('introspection') gplugin_gir = gnome.generate_gir(gplugin,
sources : GPLUGIN_SOURCES + GPLUGIN_HEADERS +
GPLUGIN_PUBLIC_BUILT_SOURCES +
@@ -229,7 +208,7 @@
symbol_prefix : 'gplugin',
- nsversion : '@0@.0'.format(GPLUGIN_MAJOR_VERSION),
export_packages : ['gplugin'],
extra_args : ['--quiet', '-DGPLUGIN_COMPILATION'])
@@ -248,6 +227,7 @@
###############################################################################
###############################################################################
--- a/gplugin/reference/embedding.xml Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/reference/embedding.xml Sat Sep 05 20:05:36 2020 -0500
@@ -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 Sat Sep 05 20:05:36 2020 -0500
@@ -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 Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/reference/gplugin-docs.xml Sat Sep 05 20:05:36 2020 -0500
@@ -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="perl5.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 Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/reference/lua.xml Sat Sep 05 20:05:36 2020 -0500
@@ -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 Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/reference/meson.build Sat Sep 05 20:05:36 2020 -0500
@@ -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 Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/reference/native-plugins.xml Sat Sep 05 20:05:36 2020 -0500
@@ -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>", @@ -51,8 +51,7 @@
"description", "description",
/* gplugin_plugin_load is called by the loader when the plugin should
@@ -77,4 +76,4 @@
</programlisting></informalexample>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin/reference/perl5.xml Sat Sep 05 20:05:36 2020 -0500
@@ -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-perl5"> + <title>Perl5 Plugins</title> + You <emphasis role="strong">MUST</emphasis> have the Perl5 loader + plugin installed and working as well as the gobject-introspection + package for GPlugin installed to use Perl5 plugins. + <title>Example Perl5 Plugin</title> + Like all plugins in GPlugin, Perl5 plugins must also implement + the <code>gplugin_query</code>, <code>gplugin_load</code>, and + <code>gplugin_unload</code> functions. + The following is a basic Perl5 plugin. + <informalexample><programlisting> + use Glib::Object::Introspection; + Glib::Object::Introspection->setup(basename => "GPlugin", version => "1.0", package=> "GPlugin"); + return GPlugin::PluginInfo->new( + id => "gplugin/perl5-basic-plugin", + abi_version => 0x01020304, + name => "basic plugin", + authors => ("author1"), + license_id => "license", + description => "description", + </programlisting></informalexample> --- a/gplugin/reference/python.xml Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/reference/python.xml Sat Sep 05 20:05:36 2020 -0500
@@ -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 Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/reference/vala.xml Sat Sep 05 20:05:36 2020 -0500
@@ -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> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin/share/meson.build Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,2 @@
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin/share/valgrind/gplugin.supp Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,40 @@
+# GPlugin Valgrind suppressions file +# This file provides a list of suppressions for all of GPlugin (including +# GPluginGTK), for all Valgrind tools (memcheck, drd, helgrind, etc.) for the +# false positives and deliberate one-time leaks which GPlugin causes to be +# reported when running under Valgrind. Some of these are actually from Glib, +# but we handle them here because it takes time for them to filter into +# distribution versions of glib. +# When running an application which links to GPlugin under Valgrind, you can +# pass this suppression file to Valgrind using +# --suppressions=/path/to/gplugin.supp. +# http://valgrind.org/docs/manual/manual-core.html#manual-core.suppress +# Note that there is currently no way for Valgrind to load this automatically +# (https://bugs.kde.org/show_bug.cgi?id=160905), so the best GPlugin can +# currently do is to install this file as part of its development package. +# This file should be updated if GPlugin introduces a new deliberate one-time +# leak, or another false positive in Valgrind: please file bugs at: +# https://issues.imfreedom.org/issues/GPLUGIN + match-leak-kinds: reachable + gplugin-register-plugin-state + match-leak-kinds: possible + fun:gplugin_plugin_state_get_type --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin/share/valgrind/meson.build Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,2 @@
+install_data('gplugin.supp', + install_dir : join_paths(get_option('datadir'), 'gplugin', 'valgrind')) --- a/gplugin/tests/bad-plugins/query-error.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/bad-plugins/query-error.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,23 +19,25 @@
#include <gplugin-native.h>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
+gplugin_query(G_GNUC_UNUSED GError **error) g_set_error(error, GPLUGIN_DOMAIN, 0, "expected error");
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/gplugin/tests/bind-local/bind-local.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/bind-local/bind-local.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,26 +19,29 @@
#include <gplugin-native.h>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
+gplugin_query(G_GNUC_UNUSED GError **error) return gplugin_plugin_info_new(
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/gplugin/tests/dynamic-type/dynamic-test.h Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/dynamic-type/dynamic-test.h Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -18,15 +19,20 @@
-#define DYNAMIC_TYPE_TEST (dynamic_test_get_type())
-#define DYNAMIC_TEST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), DYNAMIC_TYPE_TEST, DynamicTest))
-#define DYNAMIC_TEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), DYNAMIC_TYPE_TEST, DynamicTestClass))
-#define DYNAMIC_IS_TEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), DYNAMIC_TYPE_TEST))
-#define DYNAMIC_IS_TEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), DYNAMIC_TYPE_TEST))
-#define DYNAMIC_TEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), DYNAMIC_TYPE_TEST, DynamicTestClass))
+#define DYNAMIC_TYPE_TEST (dynamic_test_get_type()) +#define DYNAMIC_TEST(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), DYNAMIC_TYPE_TEST, DynamicTest)) +#define DYNAMIC_TEST_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), DYNAMIC_TYPE_TEST, DynamicTestClass)) +#define DYNAMIC_IS_TEST(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), DYNAMIC_TYPE_TEST)) +#define DYNAMIC_IS_TEST_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), DYNAMIC_TYPE_TEST)) +#define DYNAMIC_TEST_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), DYNAMIC_TYPE_TEST, DynamicTestClass)) -typedef struct _DynamicTest DynamicTest;
-typedef struct _DynamicTestClass DynamicTestClass;
+typedef struct _DynamicTest DynamicTest; +typedef struct _DynamicTestClass DynamicTestClass; --- a/gplugin/tests/dynamic-type/dynamic-type-provider.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/dynamic-type/dynamic-type-provider.c Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -23,39 +24,41 @@
G_DEFINE_DYNAMIC_TYPE(DynamicTest, dynamic_test, G_TYPE_OBJECT);
-dynamic_test_init(G_GNUC_UNUSED DynamicTest *inst) {
- g_message("instance created");
+dynamic_test_init(G_GNUC_UNUSED DynamicTest *inst) -dynamic_test_class_finalize(G_GNUC_UNUSED DynamicTestClass *klass) {
+dynamic_test_class_finalize(G_GNUC_UNUSED DynamicTestClass *klass) -dynamic_test_class_init(G_GNUC_UNUSED DynamicTestClass *klass) {
- g_message("class created");
+dynamic_test_class_init(G_GNUC_UNUSED DynamicTestClass *klass) G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
+gplugin_query(G_GNUC_UNUSED GError **error) return gplugin_plugin_info_new(
"gplugin/dynamic-type-provider",
GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
-gplugin_load(GPluginNativePlugin *plugin, G_GNUC_UNUSED GError **error) {
+gplugin_load(GPluginNativePlugin *plugin, G_GNUC_UNUSED GError **error) dynamic_test_register_type(G_TYPE_MODULE(plugin));
-gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/gplugin/tests/dynamic-type/dynamic-type-user.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/dynamic-type/dynamic-type-user.c Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -23,27 +24,30 @@
static DynamicTest *test_object = NULL;
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
- const gchar * const dependencies[] = {
- "gplugin/dynamic-type-provider",
+gplugin_query(G_GNUC_UNUSED GError **error) + const gchar *const dependencies[] = {"gplugin/dynamic-type-provider", NULL}; return gplugin_plugin_info_new(
"gplugin/dynamic-type-user",
GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
"dependencies", dependencies,
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin, GError **error) {
+gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin, GError **error) test_object = g_object_new(DYNAMIC_TYPE_TEST, NULL);
- if (test_object == NULL) {
- g_set_error(error, GPLUGIN_DOMAIN, 0,
- "could not create an instance of DynamicTest");
+ if(test_object == NULL) { + "could not create an instance of DynamicTest"); @@ -58,12 +62,10 @@
g_object_unref(test_object);
- if (DYNAMIC_IS_TEST(weak_test_object)) {
- g_set_error(error, GPLUGIN_DOMAIN, 0,
- "test_object is still valid");
+ if(DYNAMIC_IS_TEST(weak_test_object)) { + g_set_error(error, GPLUGIN_DOMAIN, 0, "test_object is still valid");
--- a/gplugin/tests/id-collision/id-collision1.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/id-collision/id-collision1.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,26 +19,29 @@
#include <gplugin-native.h>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
+gplugin_query(G_GNUC_UNUSED GError **error) return gplugin_plugin_info_new(
GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/gplugin/tests/id-collision/id-collision2.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/id-collision/id-collision2.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,26 +19,29 @@
#include <gplugin-native.h>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
+gplugin_query(G_GNUC_UNUSED GError **error) return gplugin_plugin_info_new(
GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/gplugin/tests/load-on-query-fail/load-on-query-fail.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/load-on-query-fail/load-on-query-fail.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,17 +19,20 @@
#include <gplugin-native.h>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
+gplugin_query(G_GNUC_UNUSED GError **error) return gplugin_plugin_info_new(
"gplugin/load-on-query-fail",
GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin, GError **error) {
+gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin, GError **error) g_set_error(error, GPLUGIN_DOMAIN, 0, "called %d times", count++);
@@ -38,9 +41,9 @@
-gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/gplugin/tests/load-on-query-pass/load-on-query-pass.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/load-on-query-pass/load-on-query-pass.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,26 +19,29 @@
#include <gplugin-native.h>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
+gplugin_query(G_GNUC_UNUSED GError **error) return gplugin_plugin_info_new(
GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/gplugin/tests/meson.build Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/meson.build Sat Sep 05 20:05:36 2020 -0500
@@ -1,15 +1,16 @@
###############################################################################
###############################################################################
+subdir('load-on-query-fail') subdir('load-on-query-pass')
-subdir('load-on-query-fail')
+subdir('newest-version') +subdir('unresolved-symbol') subdir('versioned-dependencies')
-subdir('unresolved-symbol')
###############################################################################
@@ -28,6 +29,20 @@
dependencies : [gplugin_dep, GLIB, GOBJECT])
+e = executable('test-find-plugins', 'test-find-plugins.c', + c_args : ['-DTEST_DIR="@0@/plugins/"'.format(meson.current_build_dir())], + 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-newest-version', 'test-newest-version.c', + c_args : ['-DTEST_DIR="@0@/newest-version/"'.format(meson.current_build_dir())], + dependencies : [gplugin_dep, GLIB, GOBJECT]) +test('Find Plugins Newest Version', e) e = executable('test-option-group', 'test-option-group.c',
dependencies : [gplugin_dep, GLIB, GOBJECT])
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin/tests/newest-version/meson.build Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,35 @@
+shared_module('multiple-semantic-1.0.0', 'multiple-semantic-1.0.0.c', + dependencies : [gplugin_dep, GLIB]) +shared_module('multiple-semantic-1.1.0', 'multiple-semantic-1.1.0.c', + dependencies : [gplugin_dep, GLIB]) +shared_module('no-version-and-semantic-no-version', + 'no-version-and-semantic-no-version.c', + dependencies : [gplugin_dep, GLIB]) +shared_module('no-version-and-semantic-semantic', + 'no-version-and-semantic-semantic.c', + dependencies : [gplugin_dep, GLIB]) +shared_module('non-semantic-and-semantic-non-semantic', + 'non-semantic-and-semantic-non-semantic.c', + dependencies : [gplugin_dep, GLIB]) +shared_module('non-semantic-and-semantic-semantic', + 'non-semantic-and-semantic-semantic.c', + dependencies : [gplugin_dep, GLIB]) +shared_module('solo-no-version', 'solo-no-version.c', + dependencies : [gplugin_dep, GLIB]) +shared_module('solo-non-semantic', 'solo-non-semantic.c', + dependencies : [gplugin_dep, GLIB]) --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin/tests/newest-version/multiple-semantic-1.0.0.c Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,47 @@
+ * 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> +G_MODULE_EXPORT GPluginPluginInfo * +gplugin_query(G_GNUC_UNUSED GError **error) + return gplugin_plugin_info_new( + "gplugin/test-newest-version/multiple-semantic", +G_MODULE_EXPORT gboolean + G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) +G_MODULE_EXPORT gboolean + G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin/tests/newest-version/multiple-semantic-1.1.0.c Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,47 @@
+ * 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> +G_MODULE_EXPORT GPluginPluginInfo * +gplugin_query(G_GNUC_UNUSED GError **error) + return gplugin_plugin_info_new( + "gplugin/test-newest-version/multiple-semantic", +G_MODULE_EXPORT gboolean + G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) +G_MODULE_EXPORT gboolean + G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin/tests/newest-version/no-version-and-semantic-no-version.c Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,46 @@
+ * 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> +G_MODULE_EXPORT GPluginPluginInfo * +gplugin_query(G_GNUC_UNUSED GError **error) + return gplugin_plugin_info_new( + "gplugin/test-newest-version/no-version-and-semantic", +G_MODULE_EXPORT gboolean + G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) +G_MODULE_EXPORT gboolean + G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin/tests/newest-version/no-version-and-semantic-semantic.c Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,47 @@
+ * 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> +G_MODULE_EXPORT GPluginPluginInfo * +gplugin_query(G_GNUC_UNUSED GError **error) + return gplugin_plugin_info_new( + "gplugin/test-newest-version/no-version-and-semantic", +G_MODULE_EXPORT gboolean + G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) +G_MODULE_EXPORT gboolean + G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin/tests/newest-version/non-semantic-and-semantic-non-semantic.c Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,47 @@
+ * 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> +G_MODULE_EXPORT GPluginPluginInfo * +gplugin_query(G_GNUC_UNUSED GError **error) + return gplugin_plugin_info_new( + "gplugin/test-newest-version/non-semantic-and-semantic", +G_MODULE_EXPORT gboolean + G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) +G_MODULE_EXPORT gboolean + G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin/tests/newest-version/non-semantic-and-semantic-semantic.c Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,47 @@
+ * 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> +G_MODULE_EXPORT GPluginPluginInfo * +gplugin_query(G_GNUC_UNUSED GError **error) + return gplugin_plugin_info_new( + "gplugin/test-newest-version/non-semantic-and-semantic", +G_MODULE_EXPORT gboolean + G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) +G_MODULE_EXPORT gboolean + G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin/tests/newest-version/solo-no-version.c Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,46 @@
+ * 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> +G_MODULE_EXPORT GPluginPluginInfo * +gplugin_query(G_GNUC_UNUSED GError **error) + return gplugin_plugin_info_new( + "gplugin/test-newest-version/solo-no-version", +G_MODULE_EXPORT gboolean + G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) +G_MODULE_EXPORT gboolean + G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin/tests/newest-version/solo-non-semantic.c Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,47 @@
+ * 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> +G_MODULE_EXPORT GPluginPluginInfo * +gplugin_query(G_GNUC_UNUSED GError **error) + return gplugin_plugin_info_new( + "gplugin/test-newest-version/solo-non-semantic", +G_MODULE_EXPORT gboolean + G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) +G_MODULE_EXPORT gboolean + G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) --- a/gplugin/tests/plugins/basic-plugin.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/plugins/basic-plugin.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,12 +19,11 @@
#include <gplugin-native.h>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
- const gchar * const authors[] = {
+gplugin_query(G_GNUC_UNUSED GError **error) + const gchar *const authors[] = {"author1", NULL}; return gplugin_plugin_info_new(
"gplugin/native-basic-plugin",
@@ -36,21 +35,22 @@
"description", "description",
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/gplugin/tests/plugins/broken-dependent-plugin.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/plugins/broken-dependent-plugin.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,31 +19,31 @@
#include <gplugin-native.h>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
- const gchar * const dependencies[] = {
- "gplugin/does-not-exist",
+gplugin_query(G_GNUC_UNUSED GError **error) + const gchar *const dependencies[] = {"gplugin/does-not-exist", NULL}; return gplugin_plugin_info_new(
"gplugin/broken-dependent-native-plugin",
GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
"dependencies", dependencies,
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/gplugin/tests/plugins/dependent-plugin.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/plugins/dependent-plugin.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,32 +19,31 @@
#include <gplugin-native.h>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
- const gchar * const dependencies[] = {
+gplugin_query(G_GNUC_UNUSED GError **error) + const gchar *const dependencies[] = {"dependency1", "dependency2", NULL}; return gplugin_plugin_info_new(
"gplugin/native-dependent-plugin",
GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
"dependencies", dependencies,
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/gplugin/tests/plugins/load-exception.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/plugins/load-exception.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,25 +19,26 @@
#include <gplugin-native.h>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
+gplugin_query(G_GNUC_UNUSED GError **error) return gplugin_plugin_info_new(
"gplugin/native-load-exception",
GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/gplugin/tests/plugins/load-failed.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/plugins/load-failed.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,25 +19,26 @@
#include <gplugin-native.h>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
+gplugin_query(G_GNUC_UNUSED GError **error) return gplugin_plugin_info_new(
"gplugin/native-load-failed",
GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin, GError **error) {
+gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin, GError **error) g_set_error(error, GPLUGIN_DOMAIN, 0, "expected error");
-gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/gplugin/tests/plugins/unload-failed.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/plugins/unload-failed.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,25 +19,26 @@
#include <gplugin-native.h>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
+gplugin_query(G_GNUC_UNUSED GError **error) return gplugin_plugin_info_new(
"gplugin/native-unload-failed",
GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin, GError **error) {
+gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin, GError **error) g_set_error(error, GPLUGIN_DOMAIN, 0, "expected error");
--- a/gplugin/tests/test-bind-local.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/test-bind-local.c Sat Sep 05 20:05:36 2020 -0500
@@ -17,21 +17,22 @@
#include <gplugin-native.h>
/******************************************************************************
*****************************************************************************/
/* 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.
GPluginPlugin *plugin = NULL;
gplugin_manager_remove_paths();
@@ -48,16 +49,15 @@
*****************************************************************************/
-main(gint argc, gchar **argv) {
+main(gint argc, gchar **argv) g_test_init(&argc, &argv, NULL);
/* test the load on query flag */
- g_test_add_func("/loaders/native/bind-local",
+ g_test_add_func("/loaders/native/bind-local", test_bind_local);
--- a/gplugin/tests/test-core.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/test-core.c Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -15,35 +15,72 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
+/****************************************************************************** + *****************************************************************************/ +test_gplugin_count_ids_and_plugins(gint *n_ids, gint *n_plugins) + GList *l_ids = NULL, *l_id = NULL; + gint ids = 0, plugins = 0; + l_ids = gplugin_manager_list_plugins(); + for(l_id = l_ids; l_id; l_id = l_id->next) { + GSList *l_plugins = NULL, *l_plugin = NULL; + const gchar *id = (const gchar *)l_id->data; + l_plugins = gplugin_manager_find_plugins(id); + for(l_plugin = l_plugins; l_plugin; l_plugin = l_plugin->next) { + g_slist_free_full(l_plugins, g_object_unref); /******************************************************************************
*****************************************************************************/
-test_gplugin_init_uninit(void) {
+test_gplugin_init_uninit(void) -test_gplugin_init_init_uninit(void) {
+test_gplugin_init_init_uninit(void) -test_gplugin_init_uninit_with_refresh(void) {
+test_gplugin_init_uninit_with_refresh(void) gplugin_manager_refresh();
-test_gplugin_init_uninit_with_refresh_plugins(void) {
+test_gplugin_init_uninit_with_refresh_plugins(void) gplugin_manager_append_path(TEST_DIR);
gplugin_manager_refresh();
@@ -51,9 +88,8 @@
-test_gplugin_init_uninit_with_double_refresh_plugins(void) {
+test_gplugin_init_uninit_with_double_refresh_plugins(void) gint f_ids = 0, s_ids = 0, f_plugins = 0, s_plugins = 0;
@@ -62,25 +98,11 @@
/* run the first refresh and count everything */
gplugin_manager_refresh();
- for(l = gplugin_manager_list_plugins(); l; l = l->next) {
- const gchar *id = (const gchar *)l->data;
- for(sl = gplugin_manager_find_plugins(id); sl; sl = sl->next)
+ test_gplugin_count_ids_and_plugins(&f_ids, &f_plugins); /* now run the second refresh and make sure the counts match */
gplugin_manager_refresh();
- for(l = gplugin_manager_list_plugins(); l; l = l->next) {
- const gchar *id = (const gchar *)l->data;
- for(sl = gplugin_manager_find_plugins(id); sl; sl = sl->next)
+ test_gplugin_count_ids_and_plugins(&s_ids, &s_plugins); g_assert_cmpint(f_ids, >, 0);
g_assert_cmpint(f_plugins, >, 0);
@@ -95,23 +117,21 @@
*****************************************************************************/
-main(gint argc, gchar **argv) {
+main(gint argc, gchar **argv) g_test_init(&argc, &argv, NULL);
- g_test_add_func("/core/init_uninit",
- test_gplugin_init_uninit);
- g_test_add_func("/core/init_init_uninit",
- test_gplugin_init_init_uninit);
- g_test_add_func("/core/init_uninit_with_refresh",
- test_gplugin_init_uninit_with_refresh);
- g_test_add_func("/core/init_uninit_with_refresh_plugins",
- test_gplugin_init_uninit_with_refresh_plugins);
- g_test_add_func("/core/init_uninit_with_double_refresh_plugins",
- test_gplugin_init_uninit_with_double_refresh_plugins);
+ g_test_add_func("/core/init_uninit", test_gplugin_init_uninit); + g_test_add_func("/core/init_init_uninit", test_gplugin_init_init_uninit); + "/core/init_uninit_with_refresh", + test_gplugin_init_uninit_with_refresh); + "/core/init_uninit_with_refresh_plugins", + test_gplugin_init_uninit_with_refresh_plugins); + "/core/init_uninit_with_double_refresh_plugins", + test_gplugin_init_uninit_with_double_refresh_plugins);
--- a/gplugin/tests/test-dynamic-type.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/test-dynamic-type.c Sat Sep 05 20:05:36 2020 -0500
@@ -17,18 +17,18 @@
#include <gplugin-native.h>
#include <gplugin/gplugin-loader-tests.h>
/******************************************************************************
*****************************************************************************/
-test_dynamic_type(void) {
GPluginPlugin *provider = NULL, *user = NULL;
GPluginPluginState state;
@@ -72,16 +72,15 @@
*****************************************************************************/
-main(gint argc, gchar **argv) {
+main(gint argc, gchar **argv) g_test_init(&argc, &argv, NULL);
- g_test_add_func("/loaders/native/dynamic-type",
+ g_test_add_func("/loaders/native/dynamic-type", test_dynamic_type);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin/tests/test-find-plugins.c Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,142 @@
+ * 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/>. +/****************************************************************************** + *****************************************************************************/ +test_gplugin_manager_foreach_load_plugins( + G_GNUC_UNUSED const gchar *id, + for(l = plugins; l != NULL; l = l->next) { + gplugin_manager_load_plugin(GPLUGIN_PLUGIN(l->data), NULL); +test_gplugin_manager_foreach_unload_plugins( + G_GNUC_UNUSED const gchar *id, + for(l = plugins; l != NULL; l = l->next) { + gplugin_manager_unload_plugin(GPLUGIN_PLUGIN(l->data), NULL); +/****************************************************************************** + *****************************************************************************/ + * test_gplugin_manager_find_plugins_with_state: + * Runs through the normal plugins in the plugins directory, trying to progress + * their state each iteration while checking that + * gplugin_manager_find_plugins_with_state() returns the correct values. + * If any changes are made to the plugins directory, this test will need to be +test_gplugin_manager_find_plugins_with_state(void) + GSList *plugins = NULL; + /* this is the list of the current plugins and the furthest state they can + * make it in the plugin lifecycle: + * basic-plugin.c: unloaded + * broken-dependent-plugin.c: queried + * dependent-plugin.c: queried + * load-exception: load failed + * load-failed: load failed + * unload-failed: unload failed + gint UNLOADED = 3; /* unloaded plugins go back to the queried state */ + gint UNLOAD_FAILED = 1; + gplugin_manager_append_path(TEST_DIR); + gplugin_manager_refresh(); + /* make sure that all the plugins are queried */ + gplugin_manager_find_plugins_with_state(GPLUGIN_PLUGIN_STATE_QUERIED); + g_assert_cmpint(g_slist_length(plugins), ==, QUERIED); + g_slist_free_full(plugins, g_object_unref); + /* now load all of the plugins */ + gplugin_manager_foreach(test_gplugin_manager_foreach_load_plugins, NULL); + /* make sure we have the proper number loaded */ + gplugin_manager_find_plugins_with_state(GPLUGIN_PLUGIN_STATE_LOADED); + g_assert_cmpint(g_slist_length(plugins), ==, LOADED); + g_slist_free_full(plugins, g_object_unref); + /* make sure we have the proper number of load failed */ + plugins = gplugin_manager_find_plugins_with_state( + GPLUGIN_PLUGIN_STATE_LOAD_FAILED); + g_assert_cmpint(g_slist_length(plugins), ==, LOAD_FAILED); + g_slist_free_full(plugins, g_object_unref); + /* unload all of the plugins */ + gplugin_manager_foreach(test_gplugin_manager_foreach_unload_plugins, NULL); + /* make sure we have the proper number unloaded */ + gplugin_manager_find_plugins_with_state(GPLUGIN_PLUGIN_STATE_QUERIED); + g_assert_cmpint(g_slist_length(plugins), ==, UNLOADED); + g_slist_free_full(plugins, g_object_unref); + /* make sure we have the proper number of unload failed */ + plugins = gplugin_manager_find_plugins_with_state( + GPLUGIN_PLUGIN_STATE_UNLOAD_FAILED); + g_assert_cmpint(g_slist_length(plugins), ==, UNLOAD_FAILED); + g_slist_free_full(plugins, g_object_unref); +/****************************************************************************** + *****************************************************************************/ +main(gint argc, gchar **argv) + g_test_init(&argc, &argv, NULL); + "/manager/find_plugins/with_state", + test_gplugin_manager_find_plugins_with_state); --- a/gplugin/tests/test-id-collision.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/test-id-collision.c Sat Sep 05 20:05:36 2020 -0500
@@ -17,18 +17,18 @@
#include <gplugin-native.h>
#include <gplugin/gplugin-loader-tests.h>
/******************************************************************************
*****************************************************************************/
-test_id_collision(void) {
gplugin_manager_append_path(TEST_ID_DIR);
@@ -39,22 +39,21 @@
g_assert_cmpuint(g_slist_length(plugins), ==, 2);
- gplugin_manager_free_plugin_list(plugins);
+ g_slist_free_full(plugins, g_object_unref); /******************************************************************************
*****************************************************************************/
-main(gint argc, gchar **argv) {
+main(gint argc, gchar **argv) g_test_init(&argc, &argv, NULL);
- g_test_add_func("/loaders/native/id-collision",
+ g_test_add_func("/loaders/native/id-collision", test_id_collision);
--- a/gplugin/tests/test-load-on-query.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/test-load-on-query.c Sat Sep 05 20:05:36 2020 -0500
@@ -17,17 +17,18 @@
#include <gplugin-native.h>
/******************************************************************************
*****************************************************************************/
-test_load_on_query(void) {
+test_load_on_query(void) GPluginPlugin *plugin = NULL;
gplugin_manager_remove_paths();
@@ -38,12 +39,15 @@
g_assert_nonnull(plugin);
g_assert_true(GPLUGIN_IS_PLUGIN(plugin));
- g_assert_cmpint(gplugin_plugin_get_state(plugin), ==,
- GPLUGIN_PLUGIN_STATE_LOADED);
+ gplugin_plugin_get_state(plugin), + GPLUGIN_PLUGIN_STATE_LOADED); -test_load_on_query_fail_subprocess(void) {
+test_load_on_query_fail_subprocess(void) /* this test is very simple since we can't get the exact error condition
@@ -60,8 +64,12 @@
-test_load_on_query_fail(void) {
- g_test_trap_subprocess("/loaders/native/load-on-query/fail/subprocess", 0, 0);
+test_load_on_query_fail(void) + g_test_trap_subprocess( + "/loaders/native/load-on-query/fail/subprocess", g_test_trap_assert_stderr("*failed to load*during query*");
@@ -70,20 +78,21 @@
*****************************************************************************/
-main(gint argc, gchar **argv) {
+main(gint argc, gchar **argv) g_test_init(&argc, &argv, NULL);
/* test the load on query flag */
- g_test_add_func("/loaders/native/load-on-query/pass",
- g_test_add_func("/loaders/native/load-on-query/fail",
- test_load_on_query_fail);
- g_test_add_func("/loaders/native/load-on-query/fail/subprocess",
- test_load_on_query_fail_subprocess);
+ g_test_add_func("/loaders/native/load-on-query/pass", test_load_on_query); + "/loaders/native/load-on-query/fail", + test_load_on_query_fail); + "/loaders/native/load-on-query/fail/subprocess", + test_load_on_query_fail_subprocess);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin/tests/test-loader-registration.c Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,188 @@
+ * 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-private.h" +/****************************************************************************** + * GObject Implementation + *****************************************************************************/ +#define TEST_GPLUGIN_TYPE_LOADER (test_gplugin_loader_get_type()) +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_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_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); + 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); + "/manager/loader/register_unregister", + test_gplugin_manager_loader_register_unregister); + "/manager/loader/register-twice", + test_gplugin_manager_loader_register_twice); + "/manager/loader/unregister-twice", + test_gplugin_manager_loader_unregister_twice); --- a/gplugin/tests/test-native-loader.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/test-native-loader.c Sat Sep 05 20:05:36 2020 -0500
@@ -17,18 +17,18 @@
#include <gplugin-native.h>
#include <gplugin/gplugin-loader-tests.h>
/******************************************************************************
*****************************************************************************/
-test_broken_depend_plugin_load(void) {
+test_broken_depend_plugin_load(void) GPluginPlugin *plugin = NULL;
GPluginPluginState state;
@@ -49,13 +49,16 @@
/* now attempt to load the dependent plugin, it's supposed to fail */
g_assert_false(gplugin_manager_load_plugin(plugin, &error));
+ g_assert_error(error, GPLUGIN_DOMAIN, 0); /******************************************************************************
*****************************************************************************/
-test_query_error_subprocess(void) {
+test_query_error_subprocess(void) GPluginPlugin *plugin = NULL;
/* add the test directory to the plugin manager's search paths */
@@ -70,7 +73,8 @@
-test_query_error(void) {
g_test_trap_subprocess("/loaders/native/error/query/subprocess", 0, 0);
g_test_trap_assert_failed();
@@ -80,7 +84,8 @@
*****************************************************************************/
-main(gint argc, gchar **argv) {
+main(gint argc, gchar **argv) g_test_init(&argc, &argv, NULL);
@@ -88,15 +93,15 @@
gplugin_loader_tests_main(NULL, TEST_DIR, "native");
- g_test_add_func("/loaders/native/load/broken_dependent",
- test_broken_depend_plugin_load);
+ "/loaders/native/load/broken_dependent", + test_broken_depend_plugin_load); - g_test_add_func("/loaders/native/error/query",
- g_test_add_func("/loaders/native/error/query/subprocess",
- test_query_error_subprocess);
+ g_test_add_func("/loaders/native/error/query", test_query_error); + "/loaders/native/error/query/subprocess", + test_query_error_subprocess);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin/tests/test-newest-version.c Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,117 @@
+ * 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/>. +/****************************************************************************** + *****************************************************************************/ +test_newest_version(const gchar *id, const gchar *version) + GPluginPlugin *plugin = NULL; + GPluginPluginInfo *info = NULL; + gplugin_manager_append_path(TEST_DIR); + gplugin_manager_refresh(); + plugin = gplugin_manager_find_plugin_with_newest_version(id); + g_assert_nonnull(plugin); + g_assert_true(GPLUGIN_IS_PLUGIN(plugin)); + info = gplugin_plugin_get_info(plugin); + g_assert_nonnull(info); + g_assert_true(GPLUGIN_IS_PLUGIN_INFO(info)); + g_assert_cmpstr(gplugin_plugin_info_get_version(info), ==, version); + g_clear_object(&plugin); +/****************************************************************************** + *****************************************************************************/ +test_newest_version_multiple_semantic(void) + "gplugin/test-newest-version/multiple-semantic", +test_newest_version_solo_non_semantic(void) + "gplugin/test-newest-version/solo-non-semantic", +test_newest_version_non_semantic_and_semantic(void) + "gplugin/test-newest-version/non-semantic-and-semantic", +test_newest_version_solo_no_version(void) + test_newest_version("gplugin/test-newest-version/solo-no-version", NULL); +test_newest_version_no_version_and_semantic(void) + "gplugin/test-newest-version/no-version-and-semantic", +/****************************************************************************** + *****************************************************************************/ +main(gint argc, gchar **argv) + g_test_init(&argc, &argv, NULL); + "/manager/find_plugin_newest_version/multiple-semantic", + test_newest_version_multiple_semantic); + "/manager/find_plugin_newest_version/no-version-and-semantic", + test_newest_version_no_version_and_semantic); + "/manager/find_plugin_newest_version/non-semantic-and-semantic", + test_newest_version_non_semantic_and_semantic); + "/manager/find_plugin_newest_version/solo-no-version", + test_newest_version_solo_no_version); + "/manager/find_plugin_newest_version/solo-non-semantic", + test_newest_version_solo_non_semantic); --- a/gplugin/tests/test-option-group.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/test-option-group.c Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -15,15 +15,16 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
/******************************************************************************
*****************************************************************************/
-test_gplugin_option_group_paths(const gchar *args, GList *expected) {
+test_gplugin_option_group_paths(const gchar *args, GList *expected) GOptionContext *ctx = NULL;
GOptionGroup *group = NULL;
@@ -63,21 +64,27 @@
-test_gplugin_manager_default_paths(void) {
+test_gplugin_manager_default_paths(void) - path = g_build_filename(PREFIX, LIBDIR, "gplugin", NULL);
+ path = g_build_filename(PREFIX, LIBDIR, "gplugin", G_DIR_SEPARATOR_S, NULL); paths = g_list_prepend(paths, path);
- path = g_build_filename(g_get_user_config_dir(), "gplugin", NULL);
+ path = g_build_filename( + g_get_user_config_dir(), paths = g_list_prepend(paths, path);
-test_gplugin_option_group_default_paths(void) {
+test_gplugin_option_group_default_paths(void) gchar *args = "test-option-group";
@@ -87,76 +94,84 @@
-test_gplugin_option_group_default_paths_with_single(void) {
+test_gplugin_option_group_default_paths_with_single(void) gchar *args = "test-option-group,-p,foo";
expected = test_gplugin_manager_default_paths();
- expected = g_list_prepend(expected, g_strdup("foo"));
+ expected = g_list_prepend(expected, g_strdup("foo/")); test_gplugin_option_group_paths(args, expected);
-test_gplugin_option_group_default_paths_with_multiple(void) {
+test_gplugin_option_group_default_paths_with_multiple(void) gchar *args = "test-option-group,-p,foo,-p,bar,-p,baz";
expected = test_gplugin_manager_default_paths();
- expected = g_list_prepend(expected, g_strdup("foo"));
- expected = g_list_prepend(expected, g_strdup("bar"));
- expected = g_list_prepend(expected, g_strdup("baz"));
+ expected = g_list_prepend(expected, g_strdup("foo/")); + expected = g_list_prepend(expected, g_strdup("bar/")); + expected = g_list_prepend(expected, g_strdup("baz/")); test_gplugin_option_group_paths(args, expected);
-test_gplugin_option_group_no_default_paths_short(void) {
+test_gplugin_option_group_no_default_paths_short(void) gchar *args = "test-option-group,-D";
test_gplugin_option_group_paths(args, NULL);
-test_gplugin_option_group_no_default_paths_long(void) {
+test_gplugin_option_group_no_default_paths_long(void) gchar *args = "test-option-group,--no-default-paths";
test_gplugin_option_group_paths(args, NULL);
-test_gplugin_option_group_no_default_paths_with_single(void) {
+test_gplugin_option_group_no_default_paths_with_single(void) gchar *args = "test-option-group,-D,-p,foo";
- expected = g_list_prepend(expected, g_strdup("foo"));
+ expected = g_list_prepend(expected, g_strdup("foo/")); test_gplugin_option_group_paths(args, expected);
-test_gplugin_option_group_no_default_paths_with_multiple(void) {
+test_gplugin_option_group_no_default_paths_with_multiple(void) gchar *args = "test-option-group,-D,-p,foo,-p,bar,-p,baz";
- expected = g_list_prepend(expected, g_strdup("foo"));
- expected = g_list_prepend(expected, g_strdup("bar"));
- expected = g_list_prepend(expected, g_strdup("baz"));
+ expected = g_list_prepend(expected, g_strdup("foo/")); + expected = g_list_prepend(expected, g_strdup("bar/")); + expected = g_list_prepend(expected, g_strdup("baz/")); test_gplugin_option_group_paths(args, expected);
-test_gplugin_option_group_add_path_short(void) {
- GList *expected = g_list_prepend(NULL, g_strdup("foo"));
+test_gplugin_option_group_add_path_short(void) + GList *expected = g_list_prepend(NULL, g_strdup("foo/")); gchar *args = "test-option-group,-D,-p,foo";
test_gplugin_option_group_paths(args, expected);
-test_gplugin_option_group_add_path_long(void) {
- GList *expected = g_list_prepend(NULL, g_strdup("foo"));
+test_gplugin_option_group_add_path_long(void) + GList *expected = g_list_prepend(NULL, g_strdup("foo/")); gchar *args = "test-option-group,-D,--path,foo";
test_gplugin_option_group_paths(args, expected);
@@ -166,30 +181,39 @@
*****************************************************************************/
-main(gint argc, gchar **argv) {
+main(gint argc, gchar **argv) g_test_init(&argc, &argv, NULL);
- g_test_add_func("/option-group/default-paths",
- test_gplugin_option_group_default_paths);
- g_test_add_func("/option-group/default-paths/single",
- test_gplugin_option_group_default_paths_with_single);
- g_test_add_func("/option-group/default-paths/multiple",
- test_gplugin_option_group_default_paths_with_multiple);
+ "/option-group/default-paths", + test_gplugin_option_group_default_paths); + "/option-group/default-paths/single", + test_gplugin_option_group_default_paths_with_single); + "/option-group/default-paths/multiple", + test_gplugin_option_group_default_paths_with_multiple); - g_test_add_func("/option-group/no-default-paths/short",
- test_gplugin_option_group_no_default_paths_short);
- g_test_add_func("/option-group/no-default-paths/long",
- test_gplugin_option_group_no_default_paths_long);
- g_test_add_func("/option-group/no-default-paths/single",
- test_gplugin_option_group_no_default_paths_with_single);
- g_test_add_func("/option-group/no-default-paths/multiple",
- test_gplugin_option_group_no_default_paths_with_multiple);
+ "/option-group/no-default-paths/short", + test_gplugin_option_group_no_default_paths_short); + "/option-group/no-default-paths/long", + test_gplugin_option_group_no_default_paths_long); + "/option-group/no-default-paths/single", + test_gplugin_option_group_no_default_paths_with_single); + "/option-group/no-default-paths/multiple", + test_gplugin_option_group_no_default_paths_with_multiple); - g_test_add_func("/option-group/add-path/short",
- test_gplugin_option_group_add_path_short);
- g_test_add_func("/option-group/add-path/long",
- test_gplugin_option_group_add_path_long);
+ "/option-group/add-path/short", + test_gplugin_option_group_add_path_short); + "/option-group/add-path/long", + test_gplugin_option_group_add_path_long);
--- a/gplugin/tests/test-plugin-info.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/test-plugin-info.c Sat Sep 05 20:05:36 2020 -0500
@@ -15,37 +15,52 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
#include <gplugin-native.h>
-#define test_string(var, value) G_STMT_START { \
- g_assert_cmpstr((var), ==, (value)); \
- g_assert_cmpstr((var), ==, gplugin_plugin_info_get_##var(info)); \
+#define test_string(var, value) \ + g_assert_cmpstr((var), ==, (value)); \ + g_assert_cmpstr((var), ==, gplugin_plugin_info_get_##var(info)); \ -#define test_uint(var, value) G_STMT_START { \
- g_assert_cmpuint((var), ==, (value)); \
- g_assert_cmpuint((var), ==, gplugin_plugin_info_get_##var(info)); \
+#define test_uint(var, value) \ + g_assert_cmpuint((var), ==, (value)); \ + g_assert_cmpuint((var), ==, gplugin_plugin_info_get_##var(info)); \ -#define test_true(var) G_STMT_START { \
- g_assert_true((var)); \
- g_assert_true(gplugin_plugin_info_get_##var(info)); \
+#define test_true(var) \ + g_assert_true((var)); \ + g_assert_true(gplugin_plugin_info_get_##var(info)); \ -#define test_false(var) G_STMT_START { \
- g_assert_false((var)); \
- g_assert_false(gplugin_plugin_info_get_##var(info)); \
+#define test_false(var) \ + g_assert_false((var)); \ + g_assert_false(gplugin_plugin_info_get_##var(info)); \ typedef gchar **(*TestStringVFunc)(GPluginPluginInfo *info);
-test_stringv(gchar **got, const gchar * const * const expected,
- TestStringVFunc func, GPluginPluginInfo *info)
+ const gchar *const *const expected, + GPluginPluginInfo *info) @@ -67,26 +82,28 @@
g_assert_cmpstr(tmp[i], ==, expected[i]);
/******************************************************************************
*****************************************************************************/
-test_gplugin_plugin_info_construction(void) {
+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;
- const gchar * const r_authors[] = { "author", NULL };
- const gchar * const r_dependencies[] = { "dependency", NULL };
+ const gchar *const r_authors[] = {"author", NULL}; + const gchar *const r_dependencies[] = {"dependency", NULL}; - info = g_object_new(GPLUGIN_TYPE_PLUGIN_INFO,
+ GPLUGIN_TYPE_PLUGIN_INFO, "id", "gplugin-test/plugin-info-test",
"abi_version", GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
@@ -96,20 +113,21 @@
"license-id", "license-id",
"license-text", "license-text",
"license-url", "license-url",
+ "icon-name", "icon-name", "description", "description",
"dependencies", r_dependencies,
g_assert_true(GPLUGIN_IS_PLUGIN_INFO(info));
- g_object_get(G_OBJECT(info),
"abi_version", &abi_version,
@@ -119,115 +137,15 @@
"license-id", &license_id,
"license-text", &license_text,
"license-url", &license_url,
+ "icon-name", &icon_name, "description", &description,
"dependencies", &dependencies,
- test_string(id, "gplugin-test/plugin-info-test");
- test_uint(abi_version, GPLUGIN_NATIVE_PLUGIN_ABI_VERSION);
- test_true(load_on_query);
- test_string(name, "name");
- test_string(version, "version");
- test_string(license_id, "license-id");
- test_string(license_text, "license-text");
- test_string(license_url, "license-url");
- test_string(icon, "icon");
- 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);
-test_gplugin_plugin_info_new_empty(void) {
- GPluginPluginInfo *info = NULL;
- guint32 abi_version = 0;
- info = gplugin_plugin_info_new("empty", 1, NULL);
- g_assert_true(GPLUGIN_IS_PLUGIN_INFO(info));
- g_object_get(G_OBJECT(info),
- "abi-version", &abi_version,
- test_string(id, "empty");
- test_uint(abi_version, 1);
- g_object_unref(G_OBJECT(info));
-test_gplugin_plugin_info_new_full(void) {
- GPluginPluginInfo *info = NULL;
- gchar *id = NULL, *name = NULL, *version = 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 **authors = NULL, **dependencies = NULL;
- gboolean internal = FALSE, load_on_query = FALSE;
- const gchar * const r_authors[] = { "author", NULL };
- const gchar * const r_dependencies[] = { "dependency", NULL };
- info = gplugin_plugin_info_new(
- "gplugin-test/plugin-info-test",
- GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
- "license-id", "license-id",
- "license-text", "license-text",
- "license-url", "license-url",
- "description", "description",
- "category", "category",
- "dependencies", r_dependencies,
- g_assert_true(GPLUGIN_IS_PLUGIN_INFO(info));
- g_object_get(G_OBJECT(info),
- "abi_version", &abi_version,
- "load-on-query", &load_on_query,
- "license-id", &license_id,
- "license-text", &license_text,
- "license-url", &license_url,
- "description", &description,
- "dependencies", &dependencies,
test_string(id, "gplugin-test/plugin-info-test");
test_uint(abi_version, GPLUGIN_NATIVE_PLUGIN_ABI_VERSION);
@@ -238,30 +156,152 @@
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");
+ (TestStringVFunc)gplugin_plugin_info_get_authors, test_string(website, "website");
- test_stringv(dependencies, r_dependencies,
- (TestStringVFunc)gplugin_plugin_info_get_dependencies, info);
+ (TestStringVFunc)gplugin_plugin_info_get_dependencies, + g_object_unref(G_OBJECT(info)); +test_gplugin_plugin_info_new_empty(void) + GPluginPluginInfo *info = NULL; + guint32 abi_version = 0; + info = gplugin_plugin_info_new("empty", 1, NULL); + g_assert_true(GPLUGIN_IS_PLUGIN_INFO(info)); + "abi-version", &abi_version, + test_string(id, "empty"); + test_uint(abi_version, 1); + g_object_unref(G_OBJECT(info)); -test_gplugin_plugin_info_authors_single(void) {
+test_gplugin_plugin_info_new_full(void) GPluginPluginInfo *info = NULL;
- const gchar * const authors[] = { "author", NULL };
- const gchar * const *g_authors = NULL;
+ gchar *id = NULL, *name = NULL, *version = NULL, *icon_name = NULL; + gchar *license_id = NULL, *license_text = NULL, *license_url = NULL; + gchar *summary = NULL, *description = NULL, *category = NULL; + gchar **authors = NULL, **dependencies = NULL; + gboolean internal = FALSE, load_on_query = FALSE; + const gchar *const r_authors[] = {"author", NULL}; + const gchar *const r_dependencies[] = {"dependency", NULL}; + info = gplugin_plugin_info_new( + "gplugin-test/plugin-info-test", + GPLUGIN_NATIVE_PLUGIN_ABI_VERSION, + "license-id", "license-id", + "license-text", "license-text", + "license-url", "license-url", + "icon-name", "icon-name", + "description", "description", + "category", "category", + "dependencies", r_dependencies, + g_assert_true(GPLUGIN_IS_PLUGIN_INFO(info)); + "abi_version", &abi_version, + "load-on-query", &load_on_query, + "license-id", &license_id, + "license-text", &license_text, + "license-url", &license_url, + "icon-name", &icon_name, + "description", &description, + "dependencies", &dependencies, + test_string(id, "gplugin-test/plugin-info-test"); + test_uint(abi_version, GPLUGIN_NATIVE_PLUGIN_ABI_VERSION); + test_true(load_on_query); + test_string(name, "name"); + test_string(version, "version"); + test_string(license_id, "license-id"); + test_string(license_text, "license-text"); + test_string(license_url, "license-url"); + test_string(icon_name, "icon-name"); + test_string(summary, "summary"); + test_string(description, "description"); + test_string(category, "category"); + (TestStringVFunc)gplugin_plugin_info_get_authors, + test_string(website, "website"); + (TestStringVFunc)gplugin_plugin_info_get_dependencies, + g_object_unref(G_OBJECT(info)); +test_gplugin_plugin_info_authors_single(void) + GPluginPluginInfo *info = NULL; + const gchar *const authors[] = {"author", NULL}; + const gchar *const *g_authors = NULL; info = gplugin_plugin_info_new(
GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
g_authors = gplugin_plugin_info_get_authors(info);
@@ -272,17 +312,20 @@
-test_gplugin_plugin_info_authors_multiple(void) {
+test_gplugin_plugin_info_authors_multiple(void) GPluginPluginInfo *info = NULL;
- const gchar * const authors[] = { "author1", "author2", NULL };
- const gchar * const *g_authors = NULL;
+ const gchar *const authors[] = {"author1", "author2", NULL}; + const gchar *const *g_authors = NULL; info = gplugin_plugin_info_new(
GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
g_authors = gplugin_plugin_info_get_authors(info);
@@ -292,19 +335,21 @@
g_object_unref(G_OBJECT(info));
-test_gplugin_plugin_info_dependencies_single(void) {
+test_gplugin_plugin_info_dependencies_single(void) GPluginPluginInfo *info = NULL;
- gchar *dependencies[] = { "dependency1", NULL };
- const gchar * const *g_dependencies = NULL;
+ gchar *dependencies[] = {"dependency1", NULL}; + const gchar *const *g_dependencies = NULL; info = gplugin_plugin_info_new(
"test/single-dependency",
GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
"dependencies", dependencies,
g_dependencies = gplugin_plugin_info_get_dependencies(info);
@@ -315,18 +360,20 @@
-test_gplugin_plugin_info_dependencies_multiple(void) {
+test_gplugin_plugin_info_dependencies_multiple(void) GPluginPluginInfo *info = NULL;
- gchar *dependencies[] = { "dependencie1", "dependencie2", NULL };
- const gchar * const *g_dependencies = NULL;
+ gchar *dependencies[] = {"dependencie1", "dependencie2", NULL}; + const gchar *const *g_dependencies = NULL;
info = gplugin_plugin_info_new(
"test/single-dependencie",
GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
"dependencies", dependencies,
g_dependencies = gplugin_plugin_info_get_dependencies(info);
@@ -337,84 +384,37 @@
/******************************************************************************
- *****************************************************************************/
-test_gplugin_plugin_info_version_func(GPluginVersionCompareFunc func) {
- GPluginPluginInfo *info = NULL;
- GPluginVersionCompareFunc got = NULL;
- info = gplugin_plugin_info_new(
- GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
- got = gplugin_plugin_info_get_version_func(info);
- g_assert_true(func == got);
-test_gplugin_version_compare(G_GNUC_UNUSED const gchar *v1,
- G_GNUC_UNUSED const gchar *v2,
- G_GNUC_UNUSED GError *error)
-test_gplugin_plugin_info_version_func_null(void) {
- test_gplugin_plugin_info_version_func(NULL);
-test_gplugin_plugin_info_version_func_default(void) {
- test_gplugin_plugin_info_version_func(
- (GPluginVersionCompareFunc)gplugin_version_compare
-test_gplugin_plugin_info_version_func_custom(void) {
- test_gplugin_plugin_info_version_func(
- (GPluginVersionCompareFunc)test_gplugin_version_compare
-/******************************************************************************
*****************************************************************************/
-main(gint argc, gchar **argv) {
+main(gint argc, gchar **argv) g_test_init(&argc, &argv, NULL);
- g_test_add_func("/plugin-info/construction",
- test_gplugin_plugin_info_construction);
+ "/plugin-info/construction", + test_gplugin_plugin_info_construction); - g_test_add_func("/plugin-info/new/empty",
- test_gplugin_plugin_info_new_empty);
- g_test_add_func("/plugin-info/new/full",
- test_gplugin_plugin_info_new_full);
+ "/plugin-info/new/empty", + test_gplugin_plugin_info_new_empty); + g_test_add_func("/plugin-info/new/full", test_gplugin_plugin_info_new_full); - g_test_add_func("/plugin-info/authors/single",
- test_gplugin_plugin_info_authors_single);
- g_test_add_func("/plugin-info/authors/multiple",
- test_gplugin_plugin_info_authors_multiple);
+ "/plugin-info/authors/single", + test_gplugin_plugin_info_authors_single); + "/plugin-info/authors/multiple", + test_gplugin_plugin_info_authors_multiple); - g_test_add_func("/plugin-info/dependencies/single",
- test_gplugin_plugin_info_dependencies_single);
- g_test_add_func("/plugin-info/dependencies/multiple",
- test_gplugin_plugin_info_dependencies_multiple);
- g_test_add_func("/plugin-info/version-func/null",
- test_gplugin_plugin_info_version_func_null);
- g_test_add_func("/plugin-info/version-func/default",
- test_gplugin_plugin_info_version_func_default);
- g_test_add_func("/plugin-info/version-func/custom",
- test_gplugin_plugin_info_version_func_custom);
+ "/plugin-info/dependencies/single", + test_gplugin_plugin_info_dependencies_single); + "/plugin-info/dependencies/multiple", + test_gplugin_plugin_info_dependencies_multiple);
--- a/gplugin/tests/test-plugin-manager-paths.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/test-plugin-manager-paths.c Sat Sep 05 20:05:36 2020 -0500
@@ -15,20 +15,24 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#define test_path_count(e) G_STMT_START { \
- GList *paths = gplugin_manager_get_paths(); \
- g_assert_cmpint(g_list_length(paths), ==, (e)); \
+#define test_path_count(e) \ + GList *paths = gplugin_manager_get_paths(); \ + g_assert_cmpint(g_list_length(paths), ==, (e)); \ /******************************************************************************
*****************************************************************************/
-test_gplugin_manager_paths_single(void) {
+test_gplugin_manager_paths_single(void) gplugin_manager_append_path("foo");
@@ -37,7 +41,8 @@
-test_gplugin_manager_paths_duplicate(void) {
+test_gplugin_manager_paths_duplicate(void) gplugin_manager_append_path("foo");
gplugin_manager_append_path("foo");
@@ -48,7 +53,8 @@
-test_gplugin_manager_paths_multiple_fifo(void) {
+test_gplugin_manager_paths_multiple_fifo(void) gplugin_manager_append_path("foo");
@@ -65,7 +71,8 @@
-test_gplugin_manager_paths_multiple_filo(void) {
+test_gplugin_manager_paths_multiple_filo(void) gplugin_manager_append_path("foo");
@@ -82,7 +89,44 @@
-test_gplugin_manager_add_default_paths(void) {
+test_gplugin_manager_paths_unicode(void) + gplugin_manager_append_path("/home/🐦/.plugins"); + gplugin_manager_append_path("/home/user/.plugins"); + gplugin_manager_remove_path("/home/🐦/.plugins"); + gplugin_manager_remove_path("/home/user/.plugins"); +test_gplugin_manager_add_multiple_mixed_trailing_slashes(void) + gplugin_manager_append_path("/home/user1/.plugins"); + gplugin_manager_append_path("/home/user2/.plugins/"); + gplugin_manager_remove_path("/home/user1/.plugins/"); + gplugin_manager_remove_path("/home/user2/.plugins"); +test_gplugin_manager_add_default_paths(void) GList *paths = NULL, *l = NULL;
@@ -92,10 +136,14 @@
req = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
/* create and add the paths we are expecting to the table */
- path = g_build_filename(PREFIX, LIBDIR, "gplugin", NULL);
+ path = g_build_filename(PREFIX, LIBDIR, "gplugin", G_DIR_SEPARATOR_S, NULL); g_hash_table_insert(req, path, GINT_TO_POINTER(FALSE));
- path = g_build_filename(g_get_user_config_dir(), "gplugin", NULL);
+ path = g_build_filename( + g_get_user_config_dir(), g_hash_table_insert(req, path, GINT_TO_POINTER(FALSE));
/* now tell the plugin manager to add the default paths */
@@ -115,7 +163,8 @@
-test_gplugin_manager_add_app_paths(void) {
+test_gplugin_manager_add_app_paths(void) GList *paths = NULL, *l = NULL;
const gchar *prefix = "/usr/local/";
@@ -126,10 +175,15 @@
/* build our table of required paths */
req = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
- path = g_build_filename(prefix, LIBDIR, appname, NULL);
+ path = g_build_filename(prefix, LIBDIR, appname, G_DIR_SEPARATOR_S, NULL); g_hash_table_insert(req, path, GINT_TO_POINTER(FALSE));
- path = g_build_filename(g_get_user_config_dir(), appname, "plugins", NULL);
+ path = g_build_filename( + g_get_user_config_dir(), g_hash_table_insert(req, path, GINT_TO_POINTER(FALSE));
/* now add the app paths */
@@ -153,29 +207,43 @@
-main(gint argc, gchar **argv) {
+main(gint argc, gchar **argv) g_test_init(&argc, &argv, NULL);
- g_test_add_func("/plugins/paths/add_remove_single",
- test_gplugin_manager_paths_single);
+ "/plugins/paths/add_remove_single", + test_gplugin_manager_paths_single); - g_test_add_func("/plugins/paths/add_remove_duplicate",
- test_gplugin_manager_paths_duplicate);
+ "/plugins/paths/add_remove_duplicate", + test_gplugin_manager_paths_duplicate); + "/plugins/paths/add_remove_multiple_fifo", + test_gplugin_manager_paths_multiple_fifo); - g_test_add_func("/plugins/paths/add_remove_multiple_fifo",
- test_gplugin_manager_paths_multiple_fifo);
+ "/plugins/paths/add_remove_multiple_filo", + test_gplugin_manager_paths_multiple_filo); + "/plugins/paths/add_multiple_unicode", + test_gplugin_manager_paths_unicode); - g_test_add_func("/plugins/paths/add_remove_multiple_filo",
- test_gplugin_manager_paths_multiple_filo);
+ "/plugins/paths/add_multiple_mixed_trailing_slashes", + test_gplugin_manager_add_multiple_mixed_trailing_slashes); - g_test_add_func("/plugins/paths/add_default_paths",
- test_gplugin_manager_add_default_paths);
- g_test_add_func("/plugins/paths/add_app_paths",
- test_gplugin_manager_add_app_paths);
+ "/plugins/paths/add_default_paths", + test_gplugin_manager_add_default_paths); + "/plugins/paths/add_app_paths", + test_gplugin_manager_add_app_paths);
--- a/gplugin/tests/test-signals.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/test-signals.c Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -15,9 +15,9 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
@@ -25,16 +25,18 @@
+ gboolean unload_failed; } TestGPluginManagerSignalsData;
/******************************************************************************
*****************************************************************************/
-test_gplugin_manager_signals_normal_loading(G_GNUC_UNUSED GObject *manager,
- G_GNUC_UNUSED GPluginPlugin *plugin,
- G_GNUC_UNUSED GError **error,
+test_gplugin_manager_signals_normal_loading( + G_GNUC_UNUSED GObject *manager, + G_GNUC_UNUSED GPluginPlugin *plugin, + G_GNUC_UNUSED GError **error, TestGPluginManagerSignalsData *data = (TestGPluginManagerSignalsData *)d;
@@ -44,9 +46,10 @@
-test_gplugin_manager_signals_normal_loaded(G_GNUC_UNUSED GObject *manager,
- G_GNUC_UNUSED GPluginPlugin *plugin,
+test_gplugin_manager_signals_normal_loaded( + G_GNUC_UNUSED GObject *manager, + G_GNUC_UNUSED GPluginPlugin *plugin, TestGPluginManagerSignalsData *data = (TestGPluginManagerSignalsData *)d;
@@ -54,10 +57,11 @@
-test_gplugin_manager_signals_normal_unloading(G_GNUC_UNUSED GObject *manager,
- G_GNUC_UNUSED GPluginPlugin *plugin,
- G_GNUC_UNUSED GError **error,
+test_gplugin_manager_signals_normal_unloading( + G_GNUC_UNUSED GObject *manager, + G_GNUC_UNUSED GPluginPlugin *plugin, + G_GNUC_UNUSED GError **error, TestGPluginManagerSignalsData *data = (TestGPluginManagerSignalsData *)d;
@@ -67,9 +71,10 @@
-test_gplugin_manager_signals_normal_unloaded(G_GNUC_UNUSED GObject *manager,
- G_GNUC_UNUSED GPluginPlugin *plugin,
+test_gplugin_manager_signals_normal_unloaded( + G_GNUC_UNUSED GObject *manager, + G_GNUC_UNUSED GPluginPlugin *plugin, TestGPluginManagerSignalsData *data = (TestGPluginManagerSignalsData *)d;
@@ -77,10 +82,11 @@
-test_gplugin_manager_signals_stop_loading(G_GNUC_UNUSED GObject *manager,
- G_GNUC_UNUSED GPluginPlugin *plugin,
+test_gplugin_manager_signals_stop_loading( + G_GNUC_UNUSED GObject *manager, + G_GNUC_UNUSED GPluginPlugin *plugin, TestGPluginManagerSignalsData *data = (TestGPluginManagerSignalsData *)d;
@@ -92,10 +98,11 @@
-test_gplugin_manager_signals_stop_unloading(G_GNUC_UNUSED GObject *manager,
- G_GNUC_UNUSED GPluginPlugin *plugin,
+test_gplugin_manager_signals_stop_unloading( + G_GNUC_UNUSED GObject *manager, + G_GNUC_UNUSED GPluginPlugin *plugin, TestGPluginManagerSignalsData *data = (TestGPluginManagerSignalsData *)d;
@@ -107,42 +114,64 @@
-test_gplugin_manager_signals_load_failed(G_GNUC_UNUSED GObject *manager,
- G_GNUC_UNUSED GPluginPlugin *plugin,
+test_gplugin_manager_signals_load_failed( + G_GNUC_UNUSED GObject *manager, + G_GNUC_UNUSED GPluginPlugin *plugin, TestGPluginManagerSignalsData *data = (TestGPluginManagerSignalsData *)d;
data->load_failed = TRUE;
+test_gplugin_manager_signals_unload_failed( + G_GNUC_UNUSED GObject *manager, + G_GNUC_UNUSED GPluginPlugin *plugin, + TestGPluginManagerSignalsData *data = (TestGPluginManagerSignalsData *)d; + data->unload_failed = TRUE; /******************************************************************************
*****************************************************************************/
-test_gplugin_manager_signals_normal(void) {
+test_gplugin_manager_signals_normal(void) GPluginPlugin *plugin = NULL;
GObject *manager = gplugin_manager_get_instance();
- TestGPluginManagerSignalsData data = { FALSE, FALSE, FALSE, FALSE, FALSE };
- gulong signals[] = { 0, 0, 0, 0};
+ TestGPluginManagerSignalsData data = { + gulong signals[] = {0, 0, 0, 0};
- g_signal_connect(manager, "loading-plugin",
- G_CALLBACK(test_gplugin_manager_signals_normal_loading),
- g_signal_connect(manager, "loaded-plugin",
- G_CALLBACK(test_gplugin_manager_signals_normal_loaded),
- g_signal_connect(manager, "unloading-plugin",
- G_CALLBACK(test_gplugin_manager_signals_normal_unloading),
- g_signal_connect(manager, "unloaded-plugin",
- G_CALLBACK(test_gplugin_manager_signals_normal_unloaded),
+ signals[0] = g_signal_connect( + G_CALLBACK(test_gplugin_manager_signals_normal_loading), + signals[1] = g_signal_connect( + G_CALLBACK(test_gplugin_manager_signals_normal_loaded), + signals[2] = g_signal_connect( + G_CALLBACK(test_gplugin_manager_signals_normal_unloading), + signals[3] = g_signal_connect( + G_CALLBACK(test_gplugin_manager_signals_normal_unloaded), gplugin_manager_append_path(TEST_DIR);
gplugin_manager_refresh();
@@ -165,29 +194,39 @@
-test_gplugin_manager_signals_loading_stopped(void) {
+test_gplugin_manager_signals_loading_stopped(void) GPluginPlugin *plugin = NULL;
GObject *manager = gplugin_manager_get_instance();
- TestGPluginManagerSignalsData data = { FALSE, FALSE, FALSE, FALSE, FALSE };
- gulong signals[] = { 0, 0, 0, 0};
+ TestGPluginManagerSignalsData data = { + gulong signals[] = {0, 0, 0, 0};
- g_signal_connect(manager, "loading-plugin",
- G_CALLBACK(test_gplugin_manager_signals_stop_loading),
- g_signal_connect(manager, "loaded-plugin",
- G_CALLBACK(test_gplugin_manager_signals_normal_loaded),
- g_signal_connect(manager, "unloading-plugin",
- G_CALLBACK(test_gplugin_manager_signals_normal_unloading),
- g_signal_connect(manager, "unloaded-plugin",
- G_CALLBACK(test_gplugin_manager_signals_normal_unloaded),
+ signals[0] = g_signal_connect( + G_CALLBACK(test_gplugin_manager_signals_stop_loading), + signals[1] = g_signal_connect( + G_CALLBACK(test_gplugin_manager_signals_normal_loaded), + signals[2] = g_signal_connect( + G_CALLBACK(test_gplugin_manager_signals_normal_unloading), + signals[3] = g_signal_connect( + G_CALLBACK(test_gplugin_manager_signals_normal_unloaded), gplugin_manager_append_path(TEST_DIR);
gplugin_manager_refresh();
@@ -207,29 +246,39 @@
-test_gplugin_manager_signals_unloading_stopped(void) {
+test_gplugin_manager_signals_unloading_stopped(void) GPluginPlugin *plugin = NULL;
GObject *manager = gplugin_manager_get_instance();
- TestGPluginManagerSignalsData data = { FALSE, FALSE, FALSE, FALSE, FALSE };
- gulong signals[] = { 0, 0, 0, 0};
+ TestGPluginManagerSignalsData data = { + gulong signals[] = {0, 0, 0, 0};
- g_signal_connect(manager, "loading-plugin",
- G_CALLBACK(test_gplugin_manager_signals_normal_loading),
- g_signal_connect(manager, "loaded-plugin",
- G_CALLBACK(test_gplugin_manager_signals_normal_loaded),
- g_signal_connect(manager, "unloading-plugin",
- G_CALLBACK(test_gplugin_manager_signals_stop_unloading),
- g_signal_connect(manager, "unloaded-plugin",
- G_CALLBACK(test_gplugin_manager_signals_normal_unloaded),
+ signals[0] = g_signal_connect( + G_CALLBACK(test_gplugin_manager_signals_normal_loading), + signals[1] = g_signal_connect( + G_CALLBACK(test_gplugin_manager_signals_normal_loaded), + signals[2] = g_signal_connect( + G_CALLBACK(test_gplugin_manager_signals_stop_unloading), + signals[3] = g_signal_connect( + G_CALLBACK(test_gplugin_manager_signals_normal_unloaded), gplugin_manager_append_path(TEST_DIR);
gplugin_manager_refresh();
@@ -252,21 +301,27 @@
-test_gplugin_manager_signals_load_failure(void) {
+test_gplugin_manager_signals_load_failure(void) GPluginPlugin *plugin = NULL;
GObject *manager = gplugin_manager_get_instance();
- TestGPluginManagerSignalsData data = { FALSE, FALSE, FALSE, FALSE, FALSE };
- gulong signals[] = { 0, 0, 0, 0, 0};
+ TestGPluginManagerSignalsData data = { + gulong signals[] = {0, 0, 0, 0};
- g_signal_connect(manager, "loading-plugin",
- G_CALLBACK(test_gplugin_manager_signals_normal_loading),
- g_signal_connect(manager, "load-failed",
- G_CALLBACK(test_gplugin_manager_signals_load_failed),
+ signals[0] = g_signal_connect( + G_CALLBACK(test_gplugin_manager_signals_normal_loading), + signals[1] = g_signal_connect( + G_CALLBACK(test_gplugin_manager_signals_load_failed), gplugin_manager_append_path(TEST_DIR);
gplugin_manager_refresh();
@@ -281,25 +336,84 @@
g_signal_handler_disconnect(manager, signals[1]);
+test_gplugin_manager_signals_unload_failure(void) + GPluginPlugin *plugin = NULL; + GObject *manager = gplugin_manager_get_instance(); + TestGPluginManagerSignalsData data = { + .unload_failed = FALSE, + gulong signals[] = {0, 0, 0, 0}; + signals[0] = g_signal_connect( + G_CALLBACK(test_gplugin_manager_signals_normal_loading), + signals[1] = g_signal_connect( + G_CALLBACK(test_gplugin_manager_signals_normal_loaded), + signals[2] = g_signal_connect( + G_CALLBACK(test_gplugin_manager_signals_normal_unloading), + signals[3] = g_signal_connect( + "unload-plugin-failed", + G_CALLBACK(test_gplugin_manager_signals_unload_failed), + gplugin_manager_append_path(TEST_DIR); + gplugin_manager_refresh(); + plugin = gplugin_manager_find_plugin("gplugin/native-unload-failed"); + gplugin_manager_load_plugin(plugin, &error); + g_assert_no_error(error); + g_assert_true(data.loading); + g_assert_true(data.loaded); + gplugin_manager_unload_plugin(plugin, &error); + g_assert_error(error, GPLUGIN_DOMAIN, 0); + g_assert_true(data.unloading); + g_assert_true(data.unload_failed); + g_signal_handler_disconnect(manager, signals[0]); + g_signal_handler_disconnect(manager, signals[1]); /******************************************************************************
*****************************************************************************/
-main(gint argc, gchar **argv) {
+main(gint argc, gchar **argv) g_test_init(&argc, &argv, NULL);
- g_test_add_func("/manager/signals/normal",
- test_gplugin_manager_signals_normal);
- g_test_add_func("/manager/signals/loading-stopped",
- test_gplugin_manager_signals_loading_stopped);
- g_test_add_func("/manager/signals/unloading-stopped",
- test_gplugin_manager_signals_unloading_stopped);
- g_test_add_func("/manager/signals/load-failed",
- test_gplugin_manager_signals_load_failure);
+ "/manager/signals/normal", + test_gplugin_manager_signals_normal); + "/manager/signals/loading-stopped", + test_gplugin_manager_signals_loading_stopped); + "/manager/signals/unloading-stopped", + test_gplugin_manager_signals_unloading_stopped); + "/manager/signals/load-failed", + test_gplugin_manager_signals_load_failure); + "/manager/signals/unload-failed", + test_gplugin_manager_signals_unload_failure);
--- a/gplugin/tests/test-unresolved-symbol.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/test-unresolved-symbol.c Sat Sep 05 20:05:36 2020 -0500
@@ -17,22 +17,22 @@
#include <gplugin-native.h>
/******************************************************************************
*****************************************************************************/
-test_unresolved_symbol(void) {
+test_unresolved_symbol(void) - "*some_unresolved_symbol*"
+ "*some_unresolved_symbol*"); gplugin_manager_remove_paths();
gplugin_manager_append_path(PLUGIN_DIR);
@@ -45,16 +45,17 @@
*****************************************************************************/
-main(gint argc, gchar **argv) {
+main(gint argc, gchar **argv) g_test_init(&argc, &argv, NULL);
/* test the load on query flag */
- g_test_add_func("/loaders/native/unresolved-symbol",
- test_unresolved_symbol);
+ "/loaders/native/unresolved-symbol", + test_unresolved_symbol);
--- a/gplugin/tests/test-version-compare.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/test-version-compare.c Sat Sep 05 20:05:36 2020 -0500
@@ -22,227 +22,199 @@
*****************************************************************************/
-test_gplugin_version_null__null_subprocess(void) {
- gplugin_version_compare(NULL, NULL, NULL);
-test_gplugin_version_null__null(void) {
- g_test_trap_subprocess("/version-check/null__null/subprocess", 0, 0);
- g_test_trap_assert_failed();
- g_test_trap_assert_stderr("*gplugin_version_compare*assertion*");
+test_gplugin_version_null__null(void) + g_assert_cmpint(gplugin_version_compare(NULL, NULL), ==, 0); -test_gplugin_version_null__1_2_3_subprocess(void) {
- gplugin_version_compare(NULL, "1.2.3", NULL);
-test_gplugin_version_null__1_2_3(void) {
- g_test_trap_subprocess("/version-check/null__1_2_3/subprocess", 0, 0);
- g_test_trap_assert_failed();
- g_test_trap_assert_stderr("*gplugin_version_compare*assertion*");
-test_gplugin_version_1_2_3__null_subprocess(void) {
- gplugin_version_compare("1.2.3", NULL, NULL);
+test_gplugin_version_null__1_2_3(void) + g_assert_cmpint(gplugin_version_compare(NULL, "1.2.3"), <, 0); -test_gplugin_version_1_2_3__null(void) {
- g_test_trap_subprocess("/version-check/1_2_3__null/subprocess", 0, 0);
- g_test_trap_assert_failed();
- g_test_trap_assert_stderr("*gplugin_version_compare*assertion*");
-test_gplugin_version_abc__1_2_3_subprocess(void) {
- t = gplugin_version_compare("abc", "1.2.3", &error);
- g_assert_cmpint(t, ==, 1);
- g_assert_no_error(error);
+test_gplugin_version_1_2_3__null(void) + g_assert_cmpint(gplugin_version_compare("1.2.3", NULL), >, 0); -test_gplugin_version_abc__1_2_3(void) {
- g_test_trap_subprocess("/version-check/abc__1_2_3/subprocess", 0, 0);
- g_test_trap_assert_failed();
- g_test_trap_assert_stderr("*assertion*");
+test_gplugin_version_abc__1_2_3(void) + g_assert_cmpint(gplugin_version_compare("abc", "1.2.3"), <, 0); -test_gplugin_version_1_2_3__abc_subprocess(void) {
- t = gplugin_version_compare("1.2.3", "abc", &error);
- g_assert_cmpint(t, ==, -1);
- g_assert_no_error(error);
-test_gplugin_version_1_2_3__abc(void) {
- g_test_trap_subprocess("/version-check/1_2_3__abc/subprocess", 0, 0);
- g_test_trap_assert_failed();
- g_test_trap_assert_stderr("*assertion*");
+test_gplugin_version_1_2_3__abc(void) + g_assert_cmpint(gplugin_version_compare("1.2.3", "abc"), >, 0); /* 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);
+test_gplugin_version_1_0_0__0_0_0(void) + g_assert_cmpint(gplugin_version_compare("1.0.0", "0.0.0"), >, 0); -test_gplugin_version_1_0_0__1_0_0(void) {
- g_assert_cmpint(gplugin_version_compare("1.0.0", "1.0.0", NULL), ==, 0);
+test_gplugin_version_1_0_0__1_0_0(void) + g_assert_cmpint(gplugin_version_compare("1.0.0", "1.0.0"), ==, 0); -test_gplugin_version_0_0_0__1_0_0(void) {
- g_assert_cmpint(gplugin_version_compare("0.0.0", "1.0.0", NULL), ==, 1);
+test_gplugin_version_0_0_0__1_0_0(void) + g_assert_cmpint(gplugin_version_compare("0.0.0", "1.0.0"), <, 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);
+test_gplugin_version_0_1_0__0_0_0(void) + g_assert_cmpint(gplugin_version_compare("0.1.0", "0.0.0"), >, 0); -test_gplugin_version_0_1_0__0_1_0(void) {
- g_assert_cmpint(gplugin_version_compare("0.1.0", "0.1.0", NULL), ==, 0);
+test_gplugin_version_0_1_0__0_1_0(void) + g_assert_cmpint(gplugin_version_compare("0.1.0", "0.1.0"), ==, 0); -test_gplugin_version_0_0_0__0_1_0(void) {
- g_assert_cmpint(gplugin_version_compare("0.0.0", "0.1.0", NULL), ==, 1);
+test_gplugin_version_0_0_0__0_1_0(void) + g_assert_cmpint(gplugin_version_compare("0.0.0", "0.1.0"), <, 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);
+test_gplugin_version_0_0_1__0_0_0(void) + g_assert_cmpint(gplugin_version_compare("0.0.1", "0.0.0"), >, 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);
+test_gplugin_version_0_0_1__0_0_1(void) + g_assert_cmpint(gplugin_version_compare("0.0.1", "0.0.1"), ==, 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);
+test_gplugin_version_0_0_0__0_0_1(void) + g_assert_cmpint(gplugin_version_compare("0.0.0", "0.0.1"), <, 0); -static void test_gplugin_version_1_0__0_1(void) {
- g_assert_cmpint(gplugin_version_compare("1.0", "0.1", NULL), ==, -1);
+test_gplugin_version_1_0__0_1(void) + g_assert_cmpint(gplugin_version_compare("1.0", "0.1"), >, 0); -static void test_gplugin_version_1_0__1_0(void) {
- g_assert_cmpint(gplugin_version_compare("1.0", "1.0", NULL), ==, 0);
+test_gplugin_version_1_0__1_0(void) + g_assert_cmpint(gplugin_version_compare("1.0", "1.0"), ==, 0); -static void test_gplugin_version_0_1__1_0(void) {
- g_assert_cmpint(gplugin_version_compare("0.1", "1.0", NULL), ==, 1);
+test_gplugin_version_0_1__1_0(void) + g_assert_cmpint(gplugin_version_compare("0.1", "1.0"), <, 0); -static void test_gplugin_version_1__0(void) {
- g_assert_cmpint(gplugin_version_compare("1", "0", NULL), ==, -1);
+test_gplugin_version_1__0(void) + g_assert_cmpint(gplugin_version_compare("1", "0"), >, 0); -static void test_gplugin_version_1__1(void) {
- g_assert_cmpint(gplugin_version_compare("1", "1", NULL), ==, 0);
+test_gplugin_version_1__1(void) + g_assert_cmpint(gplugin_version_compare("1", "1"), ==, 0); -static void test_gplugin_version_0__1(void) {
- g_assert_cmpint(gplugin_version_compare("0", "1", NULL), ==, 1);
+test_gplugin_version_0__1(void) + g_assert_cmpint(gplugin_version_compare("0", "1"), <, 0); /******************************************************************************
*****************************************************************************/
-main(gint argc, gchar **argv) {
+main(gint argc, gchar **argv) g_test_init(&argc, &argv, NULL);
- g_test_add_func("/version-check/null__null",
- test_gplugin_version_null__null);
- g_test_add_func("/version-check/null__1_2_3",
- test_gplugin_version_null__1_2_3);
- g_test_add_func("/version-check/1_2_3__null",
- test_gplugin_version_1_2_3__null);
- g_test_add_func("/version-check/abc__1_2_3",
- test_gplugin_version_abc__1_2_3);
- g_test_add_func("/version-check/1_2_3__abc",
- test_gplugin_version_1_2_3__abc);
- g_test_add_func("/version-check/null__null/subprocess",
- test_gplugin_version_null__null_subprocess);
- g_test_add_func("/version-check/null__1_2_3/subprocess",
- test_gplugin_version_null__1_2_3_subprocess);
- g_test_add_func("/version-check/1_2_3__null/subprocess",
- test_gplugin_version_1_2_3__null_subprocess);
- g_test_add_func("/version-check/abc__1_2_3/subprocess",
- test_gplugin_version_abc__1_2_3_subprocess);
- g_test_add_func("/version-check/1_2_3__abc/subprocess",
- test_gplugin_version_1_2_3__abc_subprocess);
+ "/version-compare/null__null", + test_gplugin_version_null__null); + "/version-compare/null__1_2_3", + test_gplugin_version_null__1_2_3); + "/version-compare/1_2_3__null", + test_gplugin_version_1_2_3__null); + "/version-compare/abc__1_2_3", + test_gplugin_version_abc__1_2_3); + "/version-compare/1_2_3__abc", + test_gplugin_version_1_2_3__abc); - g_test_add_func("/version-check/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",
- test_gplugin_version_1_0_0__1_0_0);
- g_test_add_func("/version-check/0_0_0__1_0_0",
- test_gplugin_version_0_0_0__1_0_0);
+ "/version-compare/1_0_0__0_0_0", + test_gplugin_version_1_0_0__0_0_0); + "/version-compare/1_0_0__1_0_0", + test_gplugin_version_1_0_0__1_0_0); + "/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",
- test_gplugin_version_0_1_0__0_0_0);
- g_test_add_func("/version-check/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",
- test_gplugin_version_0_0_0__0_1_0);
+ "/version-compare/0_1_0__0_0_0", + test_gplugin_version_0_1_0__0_0_0); + "/version-compare/0_1_0__0_1_0", + test_gplugin_version_0_1_0__0_1_0); + "/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",
- test_gplugin_version_0_0_1__0_0_0);
- g_test_add_func("/version-check/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",
- test_gplugin_version_0_0_0__0_0_1);
+ "/version-compare/0_0_1__0_0_0", + test_gplugin_version_0_0_1__0_0_0); + "/version-compare/0_0_1__0_0_1", + test_gplugin_version_0_0_1__0_0_1); + "/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",
- test_gplugin_version_1_0__0_1);
- g_test_add_func("/version-check/1_0__1_0",
- test_gplugin_version_1_0__1_0);
- g_test_add_func("/version-check/0_1__1_0",
- test_gplugin_version_0_1__1_0);
+ g_test_add_func("/version-compare/1_0__0_1", test_gplugin_version_1_0__0_1); + g_test_add_func("/version-compare/1_0__1_0", test_gplugin_version_1_0__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",
- test_gplugin_version_1__0);
- g_test_add_func("/version-check/1__1",
- test_gplugin_version_1__1);
- g_test_add_func("/version-check/0__1",
- test_gplugin_version_0__1);
+ g_test_add_func("/version-compare/1__0", test_gplugin_version_1__0); + g_test_add_func("/version-compare/1__1", test_gplugin_version_1__1); + g_test_add_func("/version-compare/0__1", test_gplugin_version_0__1);
--- a/gplugin/tests/test-versioned-dependencies.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/test-versioned-dependencies.c Sat Sep 05 20:05:36 2020 -0500
@@ -15,40 +15,23 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#include <gplugin-native.h>
/******************************************************************************
*****************************************************************************/
-_test_plugin_load_and_has_dependent(GPluginPlugin *dependent,
- G_GNUC_UNUSED const gchar *id)
+_test_plugin_loaded(GPluginPlugin *dependent, const gchar *id) GPluginPlugin *plugin = NULL;
- GSList *deps = NULL, *l = NULL;
- gboolean found = FALSE;
- plugin = gplugin_manager_find_plugin("gplugin/test-no-version");
- g_assert_cmpint(gplugin_plugin_get_state(plugin), ==,
- GPLUGIN_PLUGIN_STATE_LOADED);
- deps = gplugin_manager_get_plugin_dependencies(plugin, NULL);
- for(l = deps; l; l = l->next) {
- if(l->data == dependent) {
- g_slist_free_full(deps, g_object_unref);
+ plugin = gplugin_manager_find_plugin(id); + gplugin_plugin_get_state(plugin), + GPLUGIN_PLUGIN_STATE_LOADED); g_object_unref(G_OBJECT(plugin));
@@ -57,11 +40,14 @@
*****************************************************************************/
-test_load_with_dependencies(void) {
+test_load_with_dependencies(void) GPluginPlugin *plugin = NULL;
- gplugin_manager_remove_paths();
gplugin_manager_append_path(TEST_VERSIONED_DEPENDENCY_DIR);
gplugin_manager_refresh();
@@ -69,40 +55,45 @@
g_assert_nonnull(plugin);
g_assert_true(GPLUGIN_IS_PLUGIN(plugin));
- gplugin_manager_load_plugin(plugin, &error);
+ ret = gplugin_manager_load_plugin(plugin, &error); g_assert_no_error(error);
- g_assert_cmpint(gplugin_plugin_get_state(plugin), ==,
- GPLUGIN_PLUGIN_STATE_LOADED);
- g_object_unref(G_OBJECT(plugin));
+ gplugin_plugin_get_state(plugin), + GPLUGIN_PLUGIN_STATE_LOADED); /* now make sure each dependent plugin that's available was loaded */
- _test_plugin_load_and_has_dependent(plugin, "gplugin/test-no-version");
- _test_plugin_load_and_has_dependent(plugin, "gplugin/test-exact1");
- _test_plugin_load_and_has_dependent(plugin, "gplugin/test-exact2");
- _test_plugin_load_and_has_dependent(plugin, "gplugin/test-greater");
- _test_plugin_load_and_has_dependent(plugin, "gplugin/test-greater-equal");
- _test_plugin_load_and_has_dependent(plugin, "gplugin/test-less");
- _test_plugin_load_and_has_dependent(plugin, "gplugin/test-less-equal");
- _test_plugin_load_and_has_dependent(plugin, "gplugin/bar");
- _test_plugin_load_and_has_dependent(plugin, "gplugin/baz");
- _test_plugin_load_and_has_dependent(plugin, "gplugin/fez");
+ _test_plugin_loaded(plugin, "gplugin/test-no-version"); + _test_plugin_loaded(plugin, "gplugin/test-exact1"); + _test_plugin_loaded(plugin, "gplugin/test-exact2"); + _test_plugin_loaded(plugin, "gplugin/test-greater"); + _test_plugin_loaded(plugin, "gplugin/test-greater-equal"); + _test_plugin_loaded(plugin, "gplugin/test-less"); + _test_plugin_loaded(plugin, "gplugin/test-less-equal"); + _test_plugin_loaded(plugin, "gplugin/bar"); + _test_plugin_loaded(plugin, "gplugin/baz"); + _test_plugin_loaded(plugin, "gplugin/fez"); + g_object_unref(G_OBJECT(plugin)); /******************************************************************************
*****************************************************************************/
-main(gint argc, gchar **argv) {
+main(gint argc, gchar **argv) g_test_init(&argc, &argv, NULL);
/* test the load on query flag */
- g_test_add_func("/dependent-versions/super-dependent",
- test_load_with_dependencies);
+ "/dependent-versions/super-dependent", + test_load_with_dependencies);
--- a/gplugin/tests/unresolved-symbol/unresolved-symbol.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/unresolved-symbol/unresolved-symbol.c Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -21,23 +21,25 @@
void some_unresolved_symbol(void);
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
+gplugin_query(G_GNUC_UNUSED GError **error) some_unresolved_symbol();
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/gplugin/tests/versioned-dependencies/bar.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/versioned-dependencies/bar.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,26 +19,29 @@
#include <gplugin-native.h>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
+gplugin_query(G_GNUC_UNUSED GError **error) return gplugin_plugin_info_new(
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/gplugin/tests/versioned-dependencies/baz.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/versioned-dependencies/baz.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,26 +19,29 @@
#include <gplugin-native.h>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
+gplugin_query(G_GNUC_UNUSED GError **error) return gplugin_plugin_info_new(
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/gplugin/tests/versioned-dependencies/exact1.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/versioned-dependencies/exact1.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,26 +19,29 @@
#include <gplugin-native.h>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
+gplugin_query(G_GNUC_UNUSED GError **error) return gplugin_plugin_info_new(
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/gplugin/tests/versioned-dependencies/exact2.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/versioned-dependencies/exact2.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,26 +19,29 @@
#include <gplugin-native.h>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
+gplugin_query(G_GNUC_UNUSED GError **error) return gplugin_plugin_info_new(
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/gplugin/tests/versioned-dependencies/fez.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/versioned-dependencies/fez.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,26 +19,29 @@
#include <gplugin-native.h>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
+gplugin_query(G_GNUC_UNUSED GError **error) return gplugin_plugin_info_new(
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/gplugin/tests/versioned-dependencies/greater-equal.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/versioned-dependencies/greater-equal.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,26 +19,29 @@
#include <gplugin-native.h>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
+gplugin_query(G_GNUC_UNUSED GError **error) return gplugin_plugin_info_new(
"gplugin/test-greater-equal",
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/gplugin/tests/versioned-dependencies/greater.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/versioned-dependencies/greater.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,26 +19,29 @@
#include <gplugin-native.h>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
+gplugin_query(G_GNUC_UNUSED GError **error) return gplugin_plugin_info_new(
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/gplugin/tests/versioned-dependencies/less-equal.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/versioned-dependencies/less-equal.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,26 +19,29 @@
#include <gplugin-native.h>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
+gplugin_query(G_GNUC_UNUSED GError **error) return gplugin_plugin_info_new(
"gplugin/test-less-equal",
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/gplugin/tests/versioned-dependencies/less.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/versioned-dependencies/less.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,26 +19,29 @@
#include <gplugin-native.h>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
+gplugin_query(G_GNUC_UNUSED GError **error) return gplugin_plugin_info_new(
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/gplugin/tests/versioned-dependencies/no-version.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/versioned-dependencies/no-version.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,25 +19,23 @@
#include <gplugin-native.h>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
- return gplugin_plugin_info_new(
- "gplugin/test-no-version",
+gplugin_query(G_GNUC_UNUSED GError **error) + return gplugin_plugin_info_new("gplugin/test-no-version", 0x04030201, NULL); -gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/gplugin/tests/versioned-dependencies/super-dependent.c Thu Nov 07 23:09:55 2019 -0600
+++ b/gplugin/tests/versioned-dependencies/super-dependent.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,8 +19,11 @@
#include <gplugin-native.h>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
- const gchar * const dependencies[] = {
+gplugin_query(G_GNUC_UNUSED GError **error) + /* clang-format-11 formats this correctly, so this can be removed then. */ + const gchar *const dependencies[] = { "gplugin/test-no-version",
"gplugin/test-exact1==1.0",
"gplugin/test-exact2=1.0",
@@ -31,29 +34,31 @@
"gplugin/foo|gplugin/bar",
"gplugin/foo|gplugin/baz>=2.0",
"gplugin/foo|gplugin/fez<1.9",
return gplugin_plugin_info_new(
"gplugin/super-dependent",
"name", "super dependent",
"dependencies", dependencies,
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/lua/gplugin-lua-core.c Thu Nov 07 23:09:55 2019 -0600
+++ b/lua/gplugin-lua-core.c Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -15,22 +15,25 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
+#include <glib/gi18n-lib.h> #include <gplugin-native.h>
#include "gplugin-lua-loader.h"
#include "gplugin-lua-plugin.h"
-#include <glib/gi18n-lib.h>
+G_MODULE_EXPORT GPluginPluginInfo * +gplugin_query(G_GNUC_UNUSED GError **error) + /* clang-format-11 formats this correctly, so this can be removed then. */ + const gchar *const authors[] = { + "Gary Kramlich <grim@reaperworld.com>", -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_NATIVE_PLUGIN_ABI_VERSION,
@@ -38,40 +41,34 @@
"name", "Lua Plugin Loader",
"version", GPLUGIN_VERSION,
+ "license-id", "LGPL-2.0-or-later", "summary", "A plugin that can load Lua plugins",
"description", "This plugin allows the loading of plugins written in "
"the Lua programming language.",
"website", GPLUGIN_WEBSITE,
-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); -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
+gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin, GError **error) - _("The Lua loader can not be unloaded")
+ _("The Lua loader can not be unloaded"));
--- a/lua/gplugin-lua-loader.c Thu Nov 07 23:09:55 2019 -0600
+++ b/lua/gplugin-lua-loader.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,25 +17,29 @@
#include "gplugin-lua-loader.h"
-#include "gplugin-lua-plugin.h"
+#include <glib/gi18n-lib.h>
+#include "gplugin-lua-plugin.h" struct _GPluginLuaLoader {
-G_DEFINE_DYNAMIC_TYPE(GPluginLuaLoader, gplugin_lua_loader, GPLUGIN_TYPE_LOADER);
/******************************************************************************
*****************************************************************************/
-_gplugin_lua_error_to_gerror(lua_State *L, GError **error) {
+_gplugin_lua_error_to_gerror(lua_State *L, GError **error) @@ -47,10 +51,11 @@
-_gplugin_lua_loader_load_unload_plugin(G_GNUC_UNUSED GPluginLoader *loader,
+_gplugin_lua_loader_load_unload_plugin( + G_GNUC_UNUSED GPluginLoader *loader, lua_State *L = gplugin_lua_plugin_get_state(GPLUGIN_LUA_PLUGIN(plugin));
@@ -81,59 +86,28 @@
* GPluginLoaderInterface API
*****************************************************************************/
-gplugin_lua_loader_class_supported_extensions(G_GNUC_UNUSED GPluginLoaderClass *klass) {
- exts = g_slist_append(exts, "lua");
- exts = g_slist_append(exts, "moon");
+gplugin_lua_loader_supported_extensions(G_GNUC_UNUSED GPluginLoader *l) + return g_slist_append(NULL, "lua"); -gplugin_lua_loader_query(GPluginLoader *loader, const gchar *filename,
+gplugin_lua_loader_query( GPluginPlugin *plugin = NULL;
GPluginPluginInfo *info = NULL;
- /* check the extension to see if we need to load moonscript */
- ext = g_utf8_strrchr(filename, -1, g_utf8_get_char("."));
- if(ext && g_utf8_collate(ext, ".moon") == 0) {
- lua_getglobal(L, "require");
- lua_pushstring(L, "moonscript");
- if(lua_pcall(L, 1, 1, 0) != 0) {
- _gplugin_lua_error_to_gerror(L, error);
- if(!lua_istable(L, -1)) {
- g_set_error(error, GPLUGIN_DOMAIN, 0, "moonscript returned an unexpected value");
+ if(luaL_loadfile(L, filename) != 0) { + _gplugin_lua_error_to_gerror(L, error);
- lua_getfield(L, -1, "loadfile");
- lua_pushstring(L, filename);
- if(lua_pcall(L, 1, 1, 0) != 0) {
- _gplugin_lua_error_to_gerror(L, error);
- if(luaL_loadfile(L, filename) != 0) {
- _gplugin_lua_error_to_gerror(L, error);
@@ -145,7 +119,11 @@
lua_getglobal(L, "gplugin_query");
- g_set_error(error, GPLUGIN_DOMAIN, 0, "no gplugin_query function found");
+ "no gplugin_query function found"); @@ -165,50 +143,65 @@
info = lua_touserdata(L, -1);
- plugin = g_object_new(GPLUGIN_LUA_TYPE_PLUGIN,
+ GPLUGIN_LUA_TYPE_PLUGIN, -gplugin_lua_loader_load(GPluginLoader *loader, GPluginPlugin *plugin,
+gplugin_lua_loader_load( - return _gplugin_lua_loader_load_unload_plugin(loader, plugin,
- "gplugin_load", error);
+ return _gplugin_lua_loader_load_unload_plugin( -gplugin_lua_loader_unload(GPluginLoader *loader, GPluginPlugin *plugin,
+gplugin_lua_loader_unload( - return _gplugin_lua_loader_load_unload_plugin(loader, plugin,
+ return _gplugin_lua_loader_load_unload_plugin( /******************************************************************************
*****************************************************************************/
-gplugin_lua_loader_init(G_GNUC_UNUSED GPluginLuaLoader *loader) {
+gplugin_lua_loader_init(G_GNUC_UNUSED GPluginLuaLoader *loader) -gplugin_lua_loader_class_finalize(G_GNUC_UNUSED GPluginLuaLoaderClass *klass) {
+gplugin_lua_loader_class_finalize(G_GNUC_UNUSED GPluginLuaLoaderClass *klass) -gplugin_lua_loader_class_init(GPluginLuaLoaderClass *klass) {
+gplugin_lua_loader_class_init(GPluginLuaLoaderClass *klass) 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;
@@ -218,6 +211,7 @@
*****************************************************************************/
-gplugin_lua_loader_register(GPluginNativePlugin *plugin) {
+gplugin_lua_loader_register(GPluginNativePlugin *plugin) gplugin_lua_loader_register_type(G_TYPE_MODULE(plugin));
--- a/lua/gplugin-lua-loader.h Thu Nov 07 23:09:55 2019 -0600
+++ b/lua/gplugin-lua-loader.h Sat Sep 05 20:05:36 2020 -0500
@@ -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,11 +24,15 @@
#define GPLUGIN_LUA_TYPE_LOADER (gplugin_lua_loader_get_type())
-G_DECLARE_FINAL_TYPE(GPluginLuaLoader, gplugin_lua_loader, GPLUGIN_LUA, LOADER, GPluginLoader)
void gplugin_lua_loader_register(GPluginNativePlugin *plugin);
#endif /* GPLUGIN_LUA_LOADER_H */
--- a/lua/gplugin-lua-plugin.c Thu Nov 07 23:09:55 2019 -0600
+++ b/lua/gplugin-lua-plugin.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,6 +31,7 @@
GPluginPluginState state;
/******************************************************************************
@@ -44,9 +45,12 @@
PROP_FILENAME = N_PROPERTIES,
-static GParamSpec *properties[N_PROPERTIES] = {NULL,};
+static GParamSpec *properties[N_PROPERTIES] = { /* I hate forward declarations... */
static void gplugin_lua_plugin_iface_init(GPluginPluginInterface *iface);
@@ -56,22 +60,25 @@
- G_IMPLEMENT_INTERFACE(GPLUGIN_TYPE_PLUGIN, gplugin_lua_plugin_iface_init)
+ G_IMPLEMENT_INTERFACE(GPLUGIN_TYPE_PLUGIN, gplugin_lua_plugin_iface_init)); /******************************************************************************
* GPluginPlugin Implementation
*****************************************************************************/
-gplugin_lua_plugin_iface_init(G_GNUC_UNUSED GPluginPluginInterface *iface) {
+gplugin_lua_plugin_iface_init(G_GNUC_UNUSED GPluginPluginInterface *iface) /******************************************************************************
*****************************************************************************/
-gplugin_lua_plugin_get_property(GObject *obj, guint param_id, GValue *value,
+gplugin_lua_plugin_get_property( GPluginLuaPlugin *plugin = GPLUGIN_LUA_PLUGIN(obj);
@@ -93,6 +100,9 @@
g_value_set_enum(value, plugin->state);
+ g_value_set_boxed(value, plugin->error); G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
@@ -101,8 +111,11 @@
-gplugin_lua_plugin_set_property(GObject *obj, guint param_id,
- const GValue *value, GParamSpec *pspec)
+gplugin_lua_plugin_set_property( GPluginLuaPlugin *plugin = GPLUGIN_LUA_PLUGIN(obj);
@@ -124,6 +137,9 @@
plugin->state = g_value_get_enum(value);
+ plugin->error = g_value_dup_boxed(value); G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
@@ -132,27 +148,32 @@
-gplugin_lua_plugin_finalize(GObject *obj) {
+gplugin_lua_plugin_finalize(GObject *obj) GPluginLuaPlugin *plugin = GPLUGIN_LUA_PLUGIN(obj);
g_clear_pointer(&plugin->L, lua_close);
g_clear_pointer(&plugin->filename, g_free);
g_clear_object(&plugin->loader);
g_clear_object(&plugin->info);
+ g_clear_error(&plugin->error); G_OBJECT_CLASS(gplugin_lua_plugin_parent_class)->finalize(obj);
-gplugin_lua_plugin_init(G_GNUC_UNUSED GPluginLuaPlugin *plugin) {
+gplugin_lua_plugin_init(G_GNUC_UNUSED GPluginLuaPlugin *plugin) -gplugin_lua_plugin_class_finalize(G_GNUC_UNUSED GPluginLuaPluginClass *klass) {
+gplugin_lua_plugin_class_finalize(G_GNUC_UNUSED GPluginLuaPluginClass *klass) -gplugin_lua_plugin_class_init(GPluginLuaPluginClass *klass) {
+gplugin_lua_plugin_class_init(GPluginLuaPluginClass *klass) GObjectClass *obj_class = G_OBJECT_CLASS(klass);
obj_class->get_property = gplugin_lua_plugin_get_property;
@@ -160,10 +181,10 @@
obj_class->finalize = gplugin_lua_plugin_finalize;
properties[PROP_LUA_STATE] = g_param_spec_pointer(
- "lua-state", "lua-state",
"The lua state for the plugin",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
@@ -172,18 +193,21 @@
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");
+ g_object_class_override_property(obj_class, PROP_ERROR, "error"); /******************************************************************************
*****************************************************************************/
-gplugin_lua_plugin_register(GPluginNativePlugin *native) {
+gplugin_lua_plugin_register(GPluginNativePlugin *native) gplugin_lua_plugin_register_type(G_TYPE_MODULE(native));
-gplugin_lua_plugin_get_state(GPluginLuaPlugin *plugin) {
+gplugin_lua_plugin_get_state(GPluginLuaPlugin *plugin) g_return_val_if_fail(GPLUGIN_LUA_IS_PLUGIN(plugin), NULL);
--- a/lua/gplugin-lua-plugin.h Thu Nov 07 23:09:55 2019 -0600
+++ b/lua/gplugin-lua-plugin.h Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -26,7 +26,12 @@
#define GPLUGIN_LUA_TYPE_PLUGIN (gplugin_lua_plugin_get_type())
-G_DECLARE_FINAL_TYPE(GPluginLuaPlugin, gplugin_lua_plugin, GPLUGIN_LUA, PLUGIN, GObject)
void gplugin_lua_plugin_register(GPluginNativePlugin *native);
@@ -35,4 +40,3 @@
#endif /* GPLUGIN_LUA_PLUGIN_H */
--- a/lua/gplugin-lua-test-lgi.c Thu Nov 07 23:09:55 2019 -0600
+++ b/lua/gplugin-lua-test-lgi.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,30 +18,36 @@
-_add_require_path(lua_State *L, const char *path) {
+_add_require_path(lua_State *L, const char *path) const char *pkg_path = NULL;
lua_getglobal(L, "package");
- lua_getfield(L, -1, "path"); // get field "path" from table at top of stack (-1)
+ "path"); // get field "path" from table at top of stack (-1) pkg_path = lua_tostring(L, -1); // grab path string from top of stack
memset(buff, 0, sizeof(buff));
snprintf(buff, sizeof(buff), "%s;%s", pkg_path, path);
- lua_pop(L, 1); // pop off the path field
- lua_pushstring(L, buff); // push the new one
- lua_setfield(L, -2, "path"); // set the field "path" in table at -2 with value at top of stack
- lua_pop( L, 1 ); // get rid of package table from top of stack
+ lua_pop(L, 1); // pop off the path field + lua_pushstring(L, buff); // push the new one + lua_setfield(L, -2, "path"); // set the field "path" in table at -2 with + // value at top of stack + lua_pop(L, 1); // get rid of package table from top of stack -main(int argc, char *argv[]) {
+main(int argc, char *argv[]) @@ -63,4 +69,3 @@
--- a/lua/meson.build Thu Nov 07 23:09:55 2019 -0600
+++ b/lua/meson.build Sat Sep 05 20:05:36 2020 -0500
@@ -1,5 +1,5 @@
- if not get_option('gobject-introspection')
+ if not get_option('introspection') error('Lua plugin requires GObject Introspection.')
@@ -14,16 +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 @@ -31,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',
@@ -46,7 +52,7 @@
dependencies : [LUA, gplugin_dep],
- install_dir : join_paths(get_option('libdir'), 'gplugin')
+ install_dir : get_option('libdir') / 'gplugin' --- a/lua/tests/lua-plugins/basic.lua Thu Nov 07 23:09:55 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +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/>.
---]]
-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",
- description = "description",
- authors = { "author1" },
-function gplugin_load(plugin)
-function gplugin_unload(plugin)
--- a/lua/tests/lua-plugins/dependent.lua Thu Nov 07 23:09:55 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +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/>.
---]]
-local lgi = require 'lgi'
-local GPlugin = lgi.GPlugin
-function gplugin_query()
- return GPlugin.PluginInfo {
- id="gplugin/lua-dependent-plugin",
- dependencies={"dependency1", "dependency2"},
-function gplugin_load(plugin)
-function gplugin_unload(plugin)
--- a/lua/tests/lua-plugins/load-exception.lua Thu Nov 07 23:09:55 2019 -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/>.
---]]
-local lgi = require 'lgi'
-local GPlugin = lgi.GPlugin
-function gplugin_query()
- return GPlugin.PluginInfo {
- id="gplugin/lua-load-exception",
-function gplugin_load(plugin)
-function gplugin_unload(plugin)
--- a/lua/tests/lua-plugins/load-failed.lua Thu Nov 07 23:09:55 2019 -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/>.
---]]
-local lgi = require 'lgi'
-local GPlugin = lgi.GPlugin
-function gplugin_query()
- return GPlugin.PluginInfo {
- id="gplugin/lua-load-failed",
-function gplugin_load(plugin)
-function gplugin_unload(plugin)
--- a/lua/tests/lua-plugins/unload-failed.lua Thu Nov 07 23:09:55 2019 -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/>.
---]]
-local lgi = require 'lgi'
-local GPlugin = lgi.GPlugin
-function gplugin_query()
- return GPlugin.PluginInfo {
- id="gplugin/lua-unload-failed",
-function gplugin_load(plugin)
-function gplugin_unload(plugin)
--- a/lua/tests/meson.build Thu Nov 07 23:09:55 2019 -0600
+++ b/lua/tests/meson.build Sat Sep 05 20:05:36 2020 -0500
@@ -2,28 +2,12 @@
e = executable('test-lua-loader', 'test-lua-loader.c',
- '-DLUA_LOADER_DIR="@0@"'.format(join_paths(meson.current_build_dir(), '..')),
- '-DLUA_PLUGIN_DIR="@0@/lua-plugins"'.format(
- meson.current_source_dir()),
- '-DMOONSCRIPT_PLUGIN_DIR="@0@/moonscript-plugins"'.format(
+ '-DLUA_LOADER_DIR="@0@/.."'.format(meson.current_build_dir()), + '-DLUA_PLUGIN_DIR="@0@/plugins"'.format( meson.current_source_dir()),
link_with : gplugin_loader_tests,
dependencies : [GLIB, GOBJECT, LUA, gplugin_dep])
-if get_option('moonscript-tests')
- e = executable('test-lua-moon-loader', 'test-lua-moon-loader.c',
- '-DLUA_LOADER_DIR="@0@"'.format(join_paths(meson.current_build_dir(), '..')),
- '-DLUA_PLUGIN_DIR="@0@/lua-plugins"'.format(
- meson.current_source_dir()),
- '-DMOONSCRIPT_PLUGIN_DIR="@0@/moonscript-plugins"'.format(
- meson.current_source_dir()),
- link_with : gplugin_loader_tests,
- dependencies : [GLIB, GOBJECT, LUA, gplugin_dep])
- test('Lua Moon Loader', e)
--- a/lua/tests/moonscript-plugins/basic.moon Thu Nov 07 23:09:55 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +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/>.
-
-export gplugin_query = ->
- return GPlugin.PluginInfo {
- id: "gplugin/moon-basic-plugin",
- abi_version: 0x01020304,
- description: "description",
- authors: { "author1" },
-export gplugin_load = ->
-export gplugin_unload = ->
--- a/lua/tests/moonscript-plugins/dependent.moon Thu Nov 07 23:09:55 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +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/>.
-
-export gplugin_query = ->
- return GPlugin.PluginInfo {
- id: "gplugin/moon-dependent-plugin",
- dependencies: {"dependency1", "dependency2"}
-export gplugin_load = ->
-export gplugin_unload = ->
--- a/lua/tests/moonscript-plugins/load-exception.moon Thu Nov 07 23:09:55 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +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/>.
-
-export gplugin_query = ->
- return GPlugin.PluginInfo {
- id: "gplugin/moon-load-exception"
-export gplugin_load = ->
-export gplugin_unload = ->
--- a/lua/tests/moonscript-plugins/load-failed.moon Thu Nov 07 23:09:55 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +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/>.
-
-export gplugin_query = ->
- return GPlugin.PluginInfo {
- id: "gplugin/moon-load-failed"
-export gplugin_load = ->
-export gplugin_unload = ->
--- a/lua/tests/moonscript-plugins/unload-failed.moon Thu Nov 07 23:09:55 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +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/>.
-
-export gplugin_query = ->
- return GPlugin.PluginInfo {
- id: "gplugin/moon-unload-failed"
-export gplugin_load = ->
-export gplugin_unload = ->
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lua/tests/plugins/basic.lua Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,42 @@
+ 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/>. +local lgi = require 'lgi' +local GPlugin = lgi.require('GPlugin', '1.0') +function gplugin_query() + return GPlugin.PluginInfo { + id = "gplugin/lua-basic-plugin", + abi_version = 0x01020304, + license_id = "license", + description = "description", + authors = { "author1" }, +function gplugin_load(plugin) +function gplugin_unload(plugin) --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lua/tests/plugins/dependent.lua Sat Sep 05 20:05:36 2020 -0500
@@ -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/>. +local lgi = require 'lgi' +local GPlugin = lgi.require('GPlugin', '1.0') +function gplugin_query() + return GPlugin.PluginInfo { + id="gplugin/lua-dependent-plugin", + dependencies={"dependency1", "dependency2"}, +function gplugin_load(plugin) +function gplugin_unload(plugin) --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lua/tests/plugins/load-exception.lua Sat Sep 05 20:05:36 2020 -0500
@@ -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/>. +local lgi = require 'lgi' +local GPlugin = lgi.require('GPlugin', '1.0') +function gplugin_query() + return GPlugin.PluginInfo { + id="gplugin/lua-load-exception", +function gplugin_load(plugin) +function gplugin_unload(plugin) --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lua/tests/plugins/load-failed.lua Sat Sep 05 20:05:36 2020 -0500
@@ -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/>. +local lgi = require 'lgi' +local GPlugin = lgi.require('GPlugin', '1.0') +function gplugin_query() + return GPlugin.PluginInfo { + id="gplugin/lua-load-failed", +function gplugin_load(plugin) +function gplugin_unload(plugin) --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lua/tests/plugins/unload-failed.lua Sat Sep 05 20:05:36 2020 -0500
@@ -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/>. +local lgi = require 'lgi' +local GPlugin = lgi.require('GPlugin', '1.0') +function gplugin_query() + return GPlugin.PluginInfo { + id="gplugin/lua-unload-failed", +function gplugin_load(plugin) +function gplugin_unload(plugin) --- a/lua/tests/test-lua-loader.c Thu Nov 07 23:09:55 2019 -0600
+++ b/lua/tests/test-lua-loader.c Sat Sep 05 20:05:36 2020 -0500
@@ -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,16 @@
#include <gplugin/gplugin-loader-tests.h>
-main(gint argc, gchar **argv) {
+main(gint argc, gchar **argv) g_test_init(&argc, &argv, NULL);
gplugin_loader_tests_main(LUA_LOADER_DIR, LUA_PLUGIN_DIR, "lua");
--- a/lua/tests/test-lua-moon-loader.c Thu Nov 07 23:09:55 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +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(LUA_LOADER_DIR, MOONSCRIPT_PLUGIN_DIR, "moon");
--- a/meson.build Thu Nov 07 23:09:55 2019 -0600
+++ b/meson.build Sat Sep 05 20:05:36 2020 -0500
@@ -1,8 +1,8 @@
###############################################################################
###############################################################################
-project('gplugin', 'c', version : '0.29.0',
- meson_version : '>=0.42.0',
+project('gplugin', 'c', version : '0.30.0-dev', + meson_version : '>=0.50.0', default_options : ['c_std=c99'])
parts = meson.project_version().split('-')
@@ -22,7 +22,7 @@
version_conf.set('GPLUGIN_EXTRA_VERSION', extra)
version_conf.set('GPLUGIN_VERSION', meson.project_version())
-LOCALE_DIR = join_paths(get_option('prefix'), get_option('localedir'))
+LOCALE_DIR = get_option('prefix') / get_option('localedir') add_project_arguments('-DLOCALEDIR="@0@"'.format(LOCALE_DIR), language : 'c')
###############################################################################
@@ -61,7 +61,7 @@
'-DPREFIX="@0@"'.format(get_option('prefix')),
'-DLIBDIR="@0@"'.format(get_option('libdir')),
- '-DGPLUGIN_WEBSITE="https://bitbucket.org/gplugin/gplugin"',
+ '-DGPLUGIN_WEBSITE="https://keep.imfreedom.org/gplugin/gplugin"', @@ -72,23 +72,12 @@
- input : 'gplugin-version.sh.in',
- output : 'gplugin-version.sh',
- configuration : version_conf)
toplevel_inc = include_directories('.')
###############################################################################
###############################################################################
ENABLE_DOC = get_option('doc')
- if meson.version().version_compare('<0.41.2')
- error('Meson 0.41.2 or newer is required to build documentation.')
###############################################################################
@@ -96,12 +85,12 @@
subdir('gplugin-gtk-viewer')
@@ -110,6 +99,5 @@
###############################################################################
-install_data('ChangeLog', 'INSTALL.md', 'README.md', 'HACKING',
- install_dir : join_paths(get_option('datadir'), 'doc', 'gplugin'))
+install_data('ChangeLog', 'INSTALL.md', 'README.md', 'HACKING.md', + install_dir : get_option('datadir') / 'doc' / 'gplugin') --- a/meson_options.txt Thu Nov 07 23:09:55 2019 -0600
+++ b/meson_options.txt Sat Sep 05 20:05:36 2020 -0500
@@ -1,16 +1,19 @@
-###############################################################################
-###############################################################################
- 'gobject-introspection',
- type : 'boolean', value : true,
+ type : 'boolean', value : true, yield : true, + description : 'build documentation with gtk-doc' + type : 'boolean', value : true, yield : true, description : 'Whether or not to build a GObject Introspection type library'
type : 'boolean', value : true,
- description : 'Install translation files'
+ description : 'Whether or not to build the gtk3 library' @@ -20,37 +23,25 @@
- type : 'boolean', value : true,
- description : 'build documentation with gtk-doc'
- type : 'boolean', value : true,
- description : 'Whether or not to build the gtk3 library'
type : 'boolean', value : true,
description : 'Whether or not to build the Lua plugin loader'
- type : 'boolean', value : false,
- description : 'Whether or not to run the moonscript tests'
+ type : 'boolean', value : true, + description : 'Install translation files'
- 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/compat Thu Nov 07 23:09:55 2019 -0600
+++ b/packaging/debian/compat Sat Sep 05 20:05:36 2020 -0500
@@ -1,1 +1,1 @@
--- a/packaging/debian/control Thu Nov 07 23:09:55 2019 -0600
+++ b/packaging/debian/control Sat Sep 05 20:05:36 2020 -0500
@@ -6,7 +6,7 @@
meson (>=0.37.0), libglib2.0-dev, libgtk-3-dev,
gobject-introspection, libgirepository1.0-dev,
- liblua5.1-0-dev, lua-lgi,
+ liblua5.3-dev, lua-lgi, python3-dev, python-gi-dev, python3-gi,
Homepage: https://bitbucket.org/gplugin/gplugin
@@ -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
@@ -91,7 +92,7 @@
This package contains the gplugin-gtk-viewer application for viewing plugins.
-Package: gir1.2-gplugin-0.0
+Package: gir1.2-gplugin-1.0 Depends: ${gir:Depends}, ${misc:Depends}, libgplugin0
@@ -103,6 +104,18 @@
This package can be used by other packages using the GIRepository format to
generate dynamic bindings for libgplugin.
+Package: gir1.2-gplugin-gtk-1.0 +Depends: ${gir:Depends}, ${misc:Depends}, libgplugin0 +Description: typelibe for libgplugin + 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 can be used by other packages using the GIRepository format to + generate dynamic bindings for libgplugin-gtk. Depends: ${misc:Depends}, ${shlibs:Depends}, liblua5.1-0,
@@ -115,7 +128,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 +137,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-perl5 +Depends: ${misc:Depends}, ${shlibs:Depends}, perl, libglib-perl, + libglib-object-introspection-perl, libgplugin0, gir1.2-gplugin-0.0 +Description: GPlugin Perl5 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 Perl5 programming --- a/packaging/debian/gir1.2-gplugin-0.0.install Thu Nov 07 23:09:55 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-debian/tmp/usr/lib/*/girepository-1.0/
-debian/tmp/usr/share/gir-1.0/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/packaging/debian/gir1.2-gplugin-1.0.install Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,1 @@
+debian/tmp/usr/lib/*/girepository-1.0/GPlugin-1.0.typelib --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/packaging/debian/gir1.2-gplugin-gtk-1.0.install Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,1 @@
+debian/tmp/usr/lib/*/girepository-1.0/GPluginGtk-1.0.typelib --- a/packaging/debian/libgplugin-dev.install Thu Nov 07 23:09:55 2019 -0600
+++ b/packaging/debian/libgplugin-dev.install Sat Sep 05 20:05:36 2020 -0500
@@ -3,6 +3,7 @@
debian/tmp/usr/include/gplugin-1.0/gplugin-native.h
debian/tmp/usr/lib/*/libgplugin.so
debian/tmp/usr/lib/*/pkgconfig/gplugin.pc
+debian/tmp/usr/share/gir-1.0/GPlugin-1.0.gir +debian/tmp/usr/share/gplugin/valgrind/gplugin.supp debian/tmp/usr/share/vala/vapi/gplugin.deps
debian/tmp/usr/share/vala/vapi/gplugin.vapi
--- a/packaging/debian/libgplugin-gtk-dev.install Thu Nov 07 23:09:55 2019 -0600
+++ b/packaging/debian/libgplugin-gtk-dev.install Sat Sep 05 20:05:36 2020 -0500
@@ -2,5 +2,6 @@
usr/include/gplugin-1.0/gplugin-gtk.h
debian/tmp/usr/lib/*/libgplugin-gtk.so
debian/tmp/usr/lib/*/pkgconfig/gplugin-gtk.pc
+debian/tmp/usr/share/gir-1.0/GPluginGtk-1.0.gir debian/tmp/usr/share/vala/vapi/gplugin-gtk.deps
-debian/tmp/usr/share/vala/vapi/gplugin-gtk.vapi
+debian/tmp/usr/share/vala/vapi/gplugin-gtk.vapi \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/packaging/debian/libgplugin-perl5.install Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,1 @@
+debian/tmp/usr/lib/*/gplugin/gplugin-perl5.so --- a/packaging/debian/libgplugin-python.install Thu Nov 07 23:09:55 2019 -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 Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,1 @@
+debian/tmp/usr/lib/*/gplugin/gplugin-python3.so --- a/packaging/gplugin.spec.in Thu Nov 07 23:09:55 2019 -0600
+++ b/packaging/gplugin.spec.in Sat Sep 05 20:05:36 2020 -0500
@@ -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,21 +167,26 @@
%{_mandir}/man1/gplugin-query.1*
%{_libdir}/libgplugin.so.0.1.0
-%{_datadir}/gir-1.0/GPlugin-0.0.gir
+%doc HACKING.md README.md +%{_datadir}/gir-1.0/GPlugin-1.0.gir %{_datadir}/gtk-doc/html/gplugin/
%{_includedir}/gplugin-1.0/
-%{_libdir}/girepository-1.0/GPlugin-0.0.typelib
+%{_libdir}/girepository-1.0/GPlugin-1.0.typelib %{_libdir}/libgplugin.so.0
%{_libdir}/pkgconfig/gplugin-gtk.pc
@@ -219,6 +195,7 @@
%{_bindir}/gplugin-gtk-viewer
%{_libdir}/libgplugin-gtk.so.0.1.0
%{_mandir}/man1/gplugin-gtk-viewer.1*
@@ -227,23 +204,38 @@
%dir %{_datadir}/glade/catalogs/
-%{_datadir}/gir-1.0/GPluginGtk-0.0.gir
+%{_datadir}/gir-1.0/GPluginGtk-1.0.gir %{_datadir}/glade/catalogs/gplugin-gtk.xml
%{_datadir}/gtk-doc/html/gplugin-gtk/
-%{_libdir}/girepository-1.0/GPluginGtk-0.0.typelib
+%{_libdir}/girepository-1.0/GPluginGtk-1.0.typelib %{_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-perl5.so -%{_libdir}/gplugin/gplugin-python.so
+%{_libdir}/gplugin/gplugin-python3.so @@ -252,14 +244,14 @@
%{_datadir}/vala/vapi/gplugin.vapi
%{_datadir}/vala/vapi/gplugin.deps
-%{_datadir}/vala/vapi/gplugin-gtk.vapi
-%{_datadir}/vala/vapi/gplugin-gtk.deps
+* Tue Aug 25 2020 Gary Kramlich <grim@reaperworld.com> +- Updated the perl packages for its new name.
+* 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/packaging/mingw-cross/PKGBUILD Thu Nov 07 23:09:55 2019 -0600
+++ b/packaging/mingw-cross/PKGBUILD Sat Sep 05 20:05:36 2020 -0500
@@ -26,8 +26,9 @@
--cross-file=${MINGW_PACKAGE_PREFIX}.txt \
- -Dgobject-introspection=false \
+ -Dintrospection=false \ --- a/perl/gplugin-perl-core.c Thu Nov 07 23:09:55 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +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 "gplugin-perl-loader.h"
-#include "gplugin-perl-plugin.h"
-G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(GError **error) {
- const gchar * const authors[] = {
- "Gary Kramlich <grim@reaperworld.com>",
- return gplugin_plugin_info_new(
- GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
- "name", "Perl plugin loader",
- "version", GPLUGIN_VERSION,
- "summary", "A plugin that can load perl plugins",
- "description", "This plugin allows the loading of plugins written in "
- "the perl programming language.",
- "website", GPLUGIN_WEBSITE,
-G_MODULE_EXPORT gboolean
-gplugin_load(GPluginNativePlugin *plugin, GError **error) {
- gplugin_perl_plugin_register(plugin);
- gplugin_perl_loader_register(plugin);
- gplugin_manager_register_loader(GPLUGIN_PERL_TYPE_LOADER);
-G_MODULE_EXPORT gboolean
-gplugin_unload(GPluginNativePlugin *plugin, GError **error) {
--- a/perl/gplugin-perl-loader.c Thu Nov 07 23:09:55 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,138 +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-perl-loader.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.
-struct _GPluginPerlLoader {
-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,
-/******************************************************************************
- *****************************************************************************/
-gplugin_perl_loader_init_perl(void) {
- gchar *args[] = { "", };
- gchar **argv = (gchar **)args;
- PERL_SYS_INIT(&argc, &argv);
- my_perl = perl_alloc();
- PERL_SET_CONTEXT(my_perl);
- PL_perl_destruct_level = 1;
- perl_construct(my_perl);
-gplugin_perl_loader_uninit_perl(void) {
- perl_destruct(my_perl);
-/******************************************************************************
- *****************************************************************************/
-gplugin_perl_loader_init(G_GNUC_UNUSED GPluginPerlLoader *loader) {
-gplugin_perl_loader_class_init(GPluginPerlLoaderClass *klass) {
- GPluginLoaderClass *loader_class = GPLUGIN_LOADER_CLASS(klass);
- loader_class->supported_extensions =
- gplugin_perl_loader_class_supported_extensions;
- loader_class->query = gplugin_perl_loader_query;
- loader_class->load = gplugin_perl_loader_load;
- loader_class->unload = gplugin_perl_loader_unload;
- /* perl initialization */
- gplugin_perl_loader_init_perl();
-gplugin_perl_loader_class_finalize(G_GNUC_UNUSED GPluginPerlLoaderClass *klass)
- /* perl uninitialization */
- gplugin_perl_loader_uninit_perl();
-/******************************************************************************
- *****************************************************************************/
-gplugin_perl_loader_register(GPluginNativePlugin *plugin) {
- gplugin_perl_loader_register_type(G_TYPE_MODULE(plugin));
--- a/perl/gplugin-perl-loader.h Thu Nov 07 23:09:55 2019 -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_PERL_LOADER_H
-#define GPLUGIN_PERL_LOADER_H
-#include <gplugin-native.h>
-#define GPLUGIN_PERL_TYPE_LOADER (gplugin_perl_loader_get_type())
-G_DECLARE_FINAL_TYPE(GPluginPerlLoader, gplugin_perl_loader, GPLUGIN_PERL, LOADER, GPluginLoader)
-void gplugin_perl_loader_register(GPluginNativePlugin *plugin);
-#endif /* GPLUGIN_PERL_PLUGIN_LOADER_H */
--- a/perl/gplugin-perl-plugin.c Thu Nov 07 23:09:55 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,205 +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-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.
-/******************************************************************************
- *****************************************************************************/
-struct _GPluginPerlPlugin {
- PerlInterpreter *interpreter;
- GPluginPluginInfo *info;
- GPluginPluginState state;
-/******************************************************************************
- *****************************************************************************/
- PROP_FILENAME = N_PROPERTIES,
-static GParamSpec *properties[N_PROPERTIES] = {NULL,};
-/* I hate forward declarations... */
-static void gplugin_perl_plugin_iface_init(GPluginPluginInterface *iface);
-G_DEFINE_DYNAMIC_TYPE_EXTENDED(
- G_IMPLEMENT_INTERFACE(GPLUGIN_TYPE_PLUGIN, gplugin_perl_plugin_iface_init)
-/******************************************************************************
- * GPluginPlugin Implementation
- *****************************************************************************/
-gplugin_perl_plugin_iface_init(G_GNUC_UNUSED GPluginPluginInterface *iface)
-/******************************************************************************
- *****************************************************************************/
-gplugin_perl_plugin_get_property(GObject *obj, guint param_id, GValue *value,
- GPluginPerlPlugin *plugin = GPLUGIN_PERL_PLUGIN(obj);
- g_value_set_pointer(value,
- gplugin_perl_plugin_get_interpreter(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_perl_plugin_set_property(GObject *obj, guint param_id,
- const GValue *value, GParamSpec *pspec)
- GPluginPerlPlugin *plugin = GPLUGIN_PERL_PLUGIN(obj);
- plugin->interpreter = 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_perl_plugin_finalize(GObject *obj) {
- GPluginPerlPlugin *plugin = GPLUGIN_PERL_PLUGIN(obj);
- perl_destruct(plugin->interpreter);
- perl_free(plugin->interpreter);
- plugin->interpreter = NULL;
- g_clear_pointer(&plugin->filename, g_free);
- g_clear_object(&plugin->loader);
- g_clear_object(&plugin->info);
- G_OBJECT_CLASS(gplugin_perl_plugin_parent_class)->finalize(obj);
-gplugin_perl_plugin_init(G_GNUC_UNUSED GPluginPerlPlugin *plugin)
-gplugin_perl_plugin_class_finalize(G_GNUC_UNUSED GPluginPerlPluginClass *klass)
-gplugin_perl_plugin_class_init(GPluginPerlPluginClass *klass) {
- GObjectClass *obj_class = G_OBJECT_CLASS(klass);
- obj_class->get_property = gplugin_perl_plugin_get_property;
- obj_class->set_property = gplugin_perl_plugin_set_property;
- obj_class->finalize = gplugin_perl_plugin_finalize;
- properties[PROP_INTERPRETER] = g_param_spec_pointer(
- "interpreter", "interpreter",
- "The PERL interpreter for this plugin",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS
- 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_perl_plugin_register(GPluginNativePlugin *native)
- gplugin_perl_plugin_register_type(G_TYPE_MODULE(native));
-gplugin_perl_plugin_get_interpreter(GPluginPerlPlugin *plugin) {
- g_return_val_if_fail(GPLUGIN_PERL_IS_PLUGIN(plugin), NULL);
- return plugin->interpreter;
--- a/perl/gplugin-perl-plugin.h Thu Nov 07 23:09:55 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +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_PERL_PLUGIN_H
-#define GPLUGIN_PERL_PLUGIN_H
-#include <gplugin-native.h>
-#define GPLUGIN_PERL_TYPE_PLUGIN (gplugin_perl_plugin_get_type())
-G_DECLARE_FINAL_TYPE(GPluginPerlPlugin, gplugin_perl_plugin, GPLUGIN_PERL, PLUGIN, GObject)
-void gplugin_perl_plugin_register(GPluginNativePlugin *native);
-PerlInterpreter *gplugin_perl_plugin_get_interpreter(GPluginPerlPlugin *plugin);
-#endif /* GPLUGIN_PERL_PLUGIN_H */
--- a/perl/meson.build Thu Nov 07 23:09:55 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
- if not get_option('gobject-introspection')
- error('Perl plugin requires GObject Introspection.')
- GPLUGIN_PERL_SOURCES = [
- 'gplugin-perl-loader.c',
- 'gplugin-perl-plugin.c',
- GPLUGIN_PERL_HEADERS = [
- 'gplugin-perl-loader.h',
- 'gplugin-perl-plugin.h',
- 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)
- PERL_CFLAGS = PERL_CFLAGS.split()
- PERL_LDFLAGS = PERL_LDFLAGS.split()
- shared_library('gplugin-perl',
- link_args : PERL_LDFLAGS,
- dependencies : [gplugin_dep],
- install_dir : join_paths(get_option('libdir'), 'gplugin')
--- a/perl/tests/plugins/basic.pl Thu Nov 07 23:09:55 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +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/>.
-use Glib::Object::Introspection;
-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,
- name => "basic plugin",
- authors => ("Gary Kramlich <grim\@reaperworld.com>"),
- license_id => "license id",
- description => "description",
-sub gplugin_plugin_load() {
-sub gplugin_plugin_unload() {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/perl5/gplugin-perl5-core.c Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,73 @@
+ * 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 "gplugin-perl5-loader.h" +#include "gplugin-perl5-plugin.h" +#include <glib/gi18n-lib.h> +G_MODULE_EXPORT GPluginPluginInfo * +gplugin_query(GError **error) + const gchar *const authors[] = { + "Gary Kramlich <grim@reaperworld.com>", + return gplugin_plugin_info_new( + GPLUGIN_NATIVE_PLUGIN_ABI_VERSION, + "name", "Perl plugin loader", + "version", GPLUGIN_VERSION, + "license-id", "LGPL-2.0-or-later", + "summary", "A plugin that can load perl plugins", + "description", "This plugin allows the loading of plugins written in " + "the perl programming language.", + "website", GPLUGIN_WEBSITE, +G_MODULE_EXPORT gboolean +gplugin_load(GPluginNativePlugin *plugin, GError **error) + gplugin_perl_plugin_register(plugin); + gplugin_perl_loader_register(plugin); + return gplugin_manager_register_loader(GPLUGIN_PERL_TYPE_LOADER, error); +G_MODULE_EXPORT gboolean +gplugin_unload(GPluginNativePlugin *plugin, GError **error) + _("The Perl loader can not be unloaded")); --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/perl5/gplugin-perl5-loader.c Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,332 @@
+ * 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-perl5-loader.h" +#include "gplugin-perl5-plugin.h" +struct _GPluginPerlLoader { +static PerlInterpreter *my_perl = NULL; +/****************************************************************************** + *****************************************************************************/ +extern void boot_DynaLoader(pTHX_ CV *cv); +static void gplugin_perl_loader_xs_init(pTHX) + newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, __FILE__); +gplugin_perl_loader_init_perl(void) + gchar **argv = (gchar **)args; + PERL_SYS_INIT(&argc, &argv); + my_perl = perl_alloc(); + PERL_SET_CONTEXT(my_perl); + PL_exit_flags |= PERL_EXIT_DESTRUCT_END; + perl_construct(my_perl); +gplugin_perl_loader_uninit_perl(void) + PERL_SET_CONTEXT(my_perl); + perl_destruct(my_perl); +static GPluginPluginInfo * +gplugin_perl_loader_call_gplugin_query( + PerlInterpreter *interpreter, + GPluginPluginInfo *info = NULL; + PerlInterpreter *old = NULL; + PERL_SET_CONTEXT(interpreter); + ret = call_pv("gplugin_query", G_EVAL | G_NOARGS); + "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, + PerlInterpreter *old = NULL; + PERL_SET_CONTEXT(interpreter); + count = call_pv(func, G_EVAL | G_SCALAR); + "%s did not return a value", + const gchar *errmsg = SvPVutf8_nolen(ERRSV); + 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( + 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); + 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", error); +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( +/****************************************************************************** + *****************************************************************************/ +gplugin_perl_loader_init(G_GNUC_UNUSED GPluginPerlLoader *loader) +gplugin_perl_loader_class_init(GPluginPerlLoaderClass *klass) + GPluginLoaderClass *loader_class = GPLUGIN_LOADER_CLASS(klass); + 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; + /* perl initialization */ + gplugin_perl_loader_init_perl(); +gplugin_perl_loader_class_finalize(G_GNUC_UNUSED GPluginPerlLoaderClass *klass) + /* perl uninitialization */ + gplugin_perl_loader_uninit_perl(); +/****************************************************************************** + *****************************************************************************/ +gplugin_perl_loader_register(GPluginNativePlugin *plugin) + gplugin_perl_loader_register_type(G_TYPE_MODULE(plugin)); --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/perl5/gplugin-perl5-loader.h Sat Sep 05 20:05:36 2020 -0500
@@ -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/>. +#ifndef GPLUGIN_PERL_LOADER_H +#define GPLUGIN_PERL_LOADER_H +#include <gplugin-native.h> +#define GPLUGIN_PERL_TYPE_LOADER (gplugin_perl_loader_get_type()) +void gplugin_perl_loader_register(GPluginNativePlugin *plugin); +#endif /* GPLUGIN_PERL_PLUGIN_LOADER_H */ --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/perl5/gplugin-perl5-plugin.c Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,217 @@
+ * 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-perl5-plugin.h" +/****************************************************************************** + *****************************************************************************/ +struct _GPluginPerlPlugin { + PerlInterpreter *interpreter; + GPluginPluginInfo *info; + GPluginPluginState state; +/****************************************************************************** + *****************************************************************************/ + PROP_FILENAME = N_PROPERTIES, +static GParamSpec *properties[N_PROPERTIES] = { +/* I hate forward declarations... */ +static void gplugin_perl_plugin_iface_init(GPluginPluginInterface *iface); +G_DEFINE_DYNAMIC_TYPE_EXTENDED( + G_IMPLEMENT_INTERFACE(GPLUGIN_TYPE_PLUGIN, gplugin_perl_plugin_iface_init)); +/****************************************************************************** + * GPluginPlugin Implementation + *****************************************************************************/ +gplugin_perl_plugin_iface_init(G_GNUC_UNUSED GPluginPluginInterface *iface) +/****************************************************************************** + *****************************************************************************/ +gplugin_perl_plugin_get_property( + GPluginPerlPlugin *plugin = GPLUGIN_PERL_PLUGIN(obj); + gplugin_perl_plugin_get_interpreter(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_value_set_boxed(value, plugin->error); + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); +gplugin_perl_plugin_set_property( + GPluginPerlPlugin *plugin = GPLUGIN_PERL_PLUGIN(obj); + plugin->interpreter = 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); + plugin->error = g_value_dup_boxed(value); + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); +gplugin_perl_plugin_finalize(GObject *obj) + GPluginPerlPlugin *plugin = GPLUGIN_PERL_PLUGIN(obj); + perl_destruct(plugin->interpreter); + perl_free(plugin->interpreter); + plugin->interpreter = NULL; + g_clear_pointer(&plugin->filename, g_free); + g_clear_object(&plugin->loader); + g_clear_object(&plugin->info); + g_clear_error(&plugin->error); + G_OBJECT_CLASS(gplugin_perl_plugin_parent_class)->finalize(obj); +gplugin_perl_plugin_init(G_GNUC_UNUSED GPluginPerlPlugin *plugin) +gplugin_perl_plugin_class_finalize(G_GNUC_UNUSED GPluginPerlPluginClass *klass) +gplugin_perl_plugin_class_init(GPluginPerlPluginClass *klass) + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + obj_class->get_property = gplugin_perl_plugin_get_property; + obj_class->set_property = gplugin_perl_plugin_set_property; + obj_class->finalize = gplugin_perl_plugin_finalize; + properties[PROP_INTERPRETER] = g_param_spec_pointer( + "The PERL interpreter for this plugin", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + 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"); + g_object_class_override_property(obj_class, PROP_ERROR, "error"); +/****************************************************************************** + *****************************************************************************/ +gplugin_perl_plugin_register(GPluginNativePlugin *native) + gplugin_perl_plugin_register_type(G_TYPE_MODULE(native)); +gplugin_perl_plugin_get_interpreter(GPluginPerlPlugin *plugin) + g_return_val_if_fail(GPLUGIN_PERL_IS_PLUGIN(plugin), NULL); + return plugin->interpreter; --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/perl5/gplugin-perl5-plugin.h Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,57 @@
+ * 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_PERL_PLUGIN_H +#define GPLUGIN_PERL_PLUGIN_H +#include <gplugin-native.h> +#define PERL_NO_GET_CONTEXT +/* On FreeBSD, perl.h includes libutil.h (which doesn't appear necessary), and + * that defines some generic 'properties' type. So use the preprocessor to hide +#define properties freebsd_properties +/* perl define's _() to something completely different that we don't use. So + * we undef it so that we can use it for gettext. +#define GPLUGIN_PERL_TYPE_PLUGIN (gplugin_perl_plugin_get_type()) +void gplugin_perl_plugin_register(GPluginNativePlugin *native); +PerlInterpreter *gplugin_perl_plugin_get_interpreter(GPluginPerlPlugin *plugin); +#endif /* GPLUGIN_PERL_PLUGIN_H */ --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/perl5/meson.build Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,66 @@
+ if not get_option('introspection') + error('Perl plugin requires GObject Introspection.') + GPLUGIN_PERL_SOURCES = [ + 'gplugin-perl5-core.c', + 'gplugin-perl5-loader.c', + 'gplugin-perl5-plugin.c', + GPLUGIN_PERL_HEADERS = [ + 'gplugin-perl5-loader.h', + 'gplugin-perl5-plugin.h', + # make sure we have the perl executable, we need it to figure out the + PERL = find_program('perl') + # make sure we have the gobject introspection perl module. + '-e use Glib::Object::Introspection;', + 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(), + if host_machine.system() == 'freebsd' + perl_arch = 'sitearchexp' + perl_arch = 'vendorarchexp' + perl_arch = run_command(PERL, + '-e', 'if ($Config{@0@}) { print "$Config{@0@}" } else { exit 1 }'.format(perl_arch), + check : true).stdout().split() + glib_perl_incdir = '-I@0@/Glib/Install'.format(perl_arch[0]) + glib_perl_libdir = '@0@/auto/Glib/'.format(perl_arch[0]) + glib_perl_dep = compiler.find_library( + dirs : glib_perl_libdir, + has_headers : 'gperl.h', + header_args : glib_perl_incdir + glib_perl_dep = declare_dependency( + dependencies : glib_perl_dep, + # Annoyingly, this is not transferred over from the header_args. + compile_args : glib_perl_incdir + shared_library('gplugin-perl5', + dependencies : [GMODULE, gplugin_dep, perl_dep, glib_perl_dep], + install_dir : get_option('libdir') / 'gplugin' --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/perl5/tests/meson.build Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,12 @@
+e = executable('test-perl5-loader', 'test-perl5-loader.c', + '-DPERL5_LOADER_DIR="@0@/.."'.format(meson.current_build_dir()), + '-DPERL5_PLUGIN_DIR="@0@/plugins"'.format(meson.current_source_dir()), + link_with : gplugin_loader_tests, + dependencies : [GLIB, GOBJECT, gplugin_dep, perl_dep]) --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/perl5/tests/plugins/basic.pl Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,43 @@
+# 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 => "1.0", package=> "GPlugin"); + return GPlugin::PluginInfo->new( + id => "gplugin/perl5-basic-plugin", + abi_version => 0x01020304, + name => "basic plugin", + authors => ("author1"), + license_id => "license", + description => "description", --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/perl5/tests/plugins/dependent.pl Sat Sep 05 20:05:36 2020 -0500
@@ -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 => "1.0", package=> "GPlugin"); + return GPlugin::PluginInfo->new( + id => "gplugin/perl5-dependent-plugin", + dependencies => ['dependency1', 'dependency2'], --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/perl5/tests/plugins/load-exception.pl Sat Sep 05 20:05:36 2020 -0500
@@ -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 => "1.0", package=> "GPlugin"); + return GPlugin::PluginInfo->new( + id => "gplugin/perl5-load-exception", --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/perl5/tests/plugins/load-failed.pl Sat Sep 05 20:05:36 2020 -0500
@@ -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 => "1.0", package=> "GPlugin"); + return GPlugin::PluginInfo->new( + id => "gplugin/perl5-load-failed", --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/perl5/tests/plugins/unload-failed.pl Sat Sep 05 20:05:36 2020 -0500
@@ -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 => "1.0", package=> "GPlugin"); + return GPlugin::PluginInfo->new( + id => "gplugin/perl5-unload-failed", --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/perl5/tests/test-perl5-loader.c Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,31 @@
+ * 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(PERL5_LOADER_DIR, PERL5_PLUGIN_DIR, "perl5"); --- a/plugins/gplugin-license-check.c Thu Nov 07 23:09:55 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +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>
-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/license-check",
- GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
- "name", "License Check",
- "version", GPLUGIN_VERSION,
- "summary", "Checks the license compatibility of plugins",
- "website", GPLUGIN_WEBSITE,
-G_MODULE_EXPORT gboolean
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
-G_MODULE_EXPORT gboolean
-gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
--- a/plugins/meson.build Thu Nov 07 23:09:55 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-shared_library('gplugin-license-check',
- 'gplugin-license-check.c',
- dependencies : [gplugin_dep],
- install_dir : join_paths(get_option('libdir'), 'gplugin'))
--- a/po/POTFILES Thu Nov 07 23:09:55 2019 -0600
+++ b/po/POTFILES Sat Sep 05 20:05:36 2020 -0500
@@ -5,6 +5,7 @@
gplugin-gtk/gplugin-gtk-plugin-info.c
gplugin-gtk/gplugin-gtk-store.c
gplugin-gtk/gplugin-gtk-view.c
+gplugin-query/gplugin-query.c gplugin/gplugin-file-tree.c
@@ -15,22 +16,19 @@
gplugin/gplugin-plugin-info.c
gplugin/gplugin-private.c
gplugin/gplugin-version.c
lua/gplugin-lua-test-lgi.c
-perl/gplugin-perl-core.c
-perl/gplugin-perl-loader.c
-perl/gplugin-perl-plugin.c
-plugins/gplugin-license-check.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
+perl5/gplugin-perl5-core.c +perl5/gplugin-perl5-loader.c +perl5/gplugin-perl5-plugin.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 Thu Nov 07 23:09:55 2019 -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-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,
- "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 Thu Nov 07 23:09:55 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,394 +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 */
- plugin = g_object_new(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) {
- const gchar *program = NULL;
- wchar_t *argv[] = { NULL, NULL };
- /* Initializes Python */
- if(!Py_IsInitialized())
- Py_InitializeEx(FALSE);
- program = g_get_prgname();
- program = program ? program : "";
- len = mbstowcs(NULL, program, 0);
- if(len == (size_t)-1) {
- g_warning("Could not convert program name to wchar_t string.");
- argv[0] = g_new(wchar_t, len + 1);
- len = mbstowcs(argv[0], program, len + 1);
- if(len == (size_t)-1) {
- 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
-#if PY_VERSION_HEX < 0x03010300
- PySys_SetArgv(1, argv);
- PyRun_SimpleString("import sys; sys.path.pop(0)\n");
- PySys_SetArgvEx(1, 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 Thu Nov 07 23:09:55 2019 -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 Thu Nov 07 23:09:55 2019 -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 Thu Nov 07 23:09:55 2019 -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 Thu Nov 07 23:09:55 2019 -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 Thu Nov 07 23:09:55 2019 -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 Thu Nov 07 23:09:55 2019 -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 Sat Sep 05 20:05:36 2020 -0500
@@ -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 <glib/gi18n-lib.h> +#include <gplugin-native.h> +#include "gplugin-python3-loader.h" +#include "gplugin-python3-plugin.h" +G_MODULE_EXPORT GPluginPluginInfo * +gplugin_query(G_GNUC_UNUSED GError **error) + /* clang-format-11 formats this correctly, so this can be removed then. */ + 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, GError **error) + _("The Python loader can not be unloaded")); --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/python/gplugin-python3-loader.c Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,401 @@
+ * 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 <glib/gi18n-lib.h> +#include "gplugin-python3-plugin.h" +#include "gplugin-python3-utils.h" +struct _GPluginPython3Loader { + PyThreadState *py_thread_state; + gplugin_python3_loader, +/****************************************************************************** + * GPluginLoader Implementation + *****************************************************************************/ +gplugin_python3_loader_supported_extensions(G_GNUC_UNUSED GPluginLoader *l) + return g_slist_append(NULL, "py"); +gplugin_python3_loader_query( + 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"); + _("Failed to find the gplugin_query function in %s"), + pyg_gil_state_release(state); + if(!PyCallable_Check(query)) { + _("Found gplugin_query in %s but it is not a " + pyg_gil_state_release(state); + load = PyDict_GetItemString(module_dict, "gplugin_load"); + _("Failed to find the gplugin_load function in %s"), + pyg_gil_state_release(state); + if(!PyCallable_Check(load)) { + _("Found gplugin_load in %s but it is not a " + pyg_gil_state_release(state); + unload = PyDict_GetItemString(module_dict, "gplugin_unload"); + _("Failed to find the gplugin_unload function in %s"), + pyg_gil_state_release(state); + if(!PyCallable_Check(unload)) { + _("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); + *error = gplugin_python3_exception_to_gerror(); + ret = PyObject_IsTrue(result); + _("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); + _("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 Sat Sep 05 20:05:36 2020 -0500
@@ -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/>. +#ifndef GPLUGIN_PYTHON3_LOADER_H +#define GPLUGIN_PYTHON3_LOADER_H +#include <gplugin-native.h> +#define GPLUGIN_PYTHON3_TYPE_LOADER (gplugin_python3_loader_get_type()) + gplugin_python3_loader, +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 Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,310 @@
+ * 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] = { +/* I hate forward declarations... */ +static void gplugin_python3_plugin_iface_init(GPluginPluginInterface *iface); +G_DEFINE_DYNAMIC_TYPE_EXTENDED( + gplugin_python3_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( + GPluginPython3Plugin *plugin = GPLUGIN_PYTHON3_PLUGIN(obj); + g_value_set_pointer(value, plugin->module); + gplugin_python3_plugin_get_load_func(plugin)); + 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_value_set_boxed(value, plugin->error); + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); +gplugin_python3_plugin_set_property( + GPluginPython3Plugin *plugin = GPLUGIN_PYTHON3_PLUGIN(obj); + gplugin_python3_plugin_set_module( + g_value_get_pointer(value)); + gplugin_python3_plugin_set_load_func( + g_value_get_pointer(value)); + gplugin_python3_plugin_set_unload_func( + 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); + plugin->error = g_value_dup_boxed(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_clear_error(&plugin->error); + 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( + "The python load function", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + properties[PROP_UNLOAD_FUNC] = g_param_spec_pointer( + "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"); + g_object_class_override_property(obj_class, PROP_ERROR, "error"); +/****************************************************************************** + *****************************************************************************/ +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 Sat Sep 05 20:05:36 2020 -0500
@@ -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/>. +#ifndef GPLUGIN_PYTHON3_PLUGIN_H +#define GPLUGIN_PYTHON3_PLUGIN_H +#include <gplugin-native.h> +#define GPLUGIN_PYTHON3_TYPE_PLUGIN (gplugin_python3_plugin_get_type()) + gplugin_python3_plugin, +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 Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,64 @@
+ * 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); + if(len == (size_t)-1) { + printf("Failed to call mbstowcs to find length of argv[0]: %s\n", argv[0]); + wargv[0] = g_new0(wchar_t, len + 1); + len = mbstowcs(wargv[0], argv[0], len + 1); + if(len == (size_t)-1) { + printf("Failed to call mbstowcs to convert argv[0]: %s\n", argv[0]); + PySys_SetArgvEx(1, wargv, 0); + /* initialize pygobject */ + pygobject_init(3, 0, 0); + printf("Calling pygobject_init failed.\n"); --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/python/gplugin-python3-utils.c Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,117 @@
+ * 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" +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); + PyBytes_AsString(type_name), + PyBytes_AsString(value_str)); --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/python/gplugin-python3-utils.h Sat Sep 05 20:05:36 2020 -0500
@@ -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 Thu Nov 07 23:09:55 2019 -0600
+++ b/python/meson.build Sat Sep 05 20:05:36 2020 -0500
@@ -1,60 +1,60 @@
- if not get_option('gobject-introspection')
+if get_option('python3') + if not get_option('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', required: false)
+ PYTHON3 = dependency('python3-embed', version: '>=3.5.0', required: false) - PYTHON3 = dependency('python3')
+ PYTHON3 = dependency('python3', version: '>=3.5.0') - PYGOBJECT = dependency('pygobject-3.0', version : '>=3.0.0')
+ 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-python',
- 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')
+ install_dir : 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 Thu Nov 07 23:09:55 2019 -0600
+++ b/python/tests/meson.build Sat Sep 05 20:05:36 2020 -0500
@@ -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(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 Thu Nov 07 23:09:55 2019 -0600
+++ b/python/tests/plugins/basic.py Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -14,11 +14,15 @@
# 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/>.
-from gi.repository import GPlugin
+gi.require_version('GPlugin', '1.0') +from gi.repository import GPlugin # noqa return GPlugin.PluginInfo(
- id='gplugin/python-basic-plugin',
+ id='gplugin/python3-basic-plugin', @@ -30,10 +34,10 @@
description='description',
def gplugin_load(plugin):
def gplugin_unload(plugin):
--- a/python/tests/plugins/dependent.py Thu Nov 07 23:09:55 2019 -0600
+++ b/python/tests/plugins/dependent.py Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -14,18 +14,22 @@
# 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/>.
-from gi.repository import GPlugin
+gi.require_version('GPlugin', '1.0') +from gi.repository import GPlugin # noqa 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 Thu Nov 07 23:09:55 2019 -0600
+++ b/python/tests/plugins/load-exception.py Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -14,11 +14,15 @@
# 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/>.
-from gi.repository import GPlugin
+gi.require_version('GPlugin', '1.0') +from gi.repository import GPlugin # noqa return GPlugin.PluginInfo(
- id="gplugin/python-load-exception",
+ id="gplugin/python3-load-exception", @@ -28,5 +32,3 @@
def gplugin_unload(plugin):
--- a/python/tests/plugins/load-failed.py Thu Nov 07 23:09:55 2019 -0600
+++ b/python/tests/plugins/load-failed.py Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -14,11 +14,15 @@
# 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/>.
-from gi.repository import GPlugin
+gi.require_version('GPlugin', '1.0') +from gi.repository import GPlugin # noqa return GPlugin.PluginInfo(
- id="gplugin/python-load-failed",
+ id="gplugin/python3-load-failed", @@ -28,5 +32,3 @@
def gplugin_unload(plugin):
--- a/python/tests/plugins/unload-failed.py Thu Nov 07 23:09:55 2019 -0600
+++ b/python/tests/plugins/unload-failed.py Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -14,11 +14,15 @@
# 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/>.
-from gi.repository import GPlugin
+gi.require_version('GPlugin', '1.0') +from gi.repository import GPlugin # noqa return GPlugin.PluginInfo(
- id="gplugin/python-unload-failed",
+ id="gplugin/python3-unload-failed", @@ -28,5 +32,3 @@
def gplugin_unload(plugin):
--- a/python/tests/test-python-loader.c Thu Nov 07 23:09:55 2019 -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 Thu Nov 07 23:09:55 2019 -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 Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,37 @@
+ * 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( --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/python/tests/test-python3-utils.c Sat Sep 05 20:05:36 2020 -0500
@@ -0,0 +1,87 @@
+ * 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", + 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); + "/loaders/python/utils/filename_to_module/NULL", + test_filename_to_module_NULL); + "/loaders/python/utils/filename_to_module/NULL/subprocess", + test_filename_to_module_NULL_subprocess); + "/loaders/python/utils/filename_to_module/empty", + test_filename_to_module_empty); + "/loaders/python/utils/filename_to_module/no-extension", + test_filename_to_module_no_extension); --- a/tcc/gplugin-tcc-core.c Thu Nov 07 23:09:55 2019 -0600
+++ b/tcc/gplugin-tcc-core.c Sat Sep 05 20:05:36 2020 -0500
@@ -1,36 +1,34 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> - * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * 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 <glib/gi18n-lib.h> #include <gplugin-native.h>
-#include <glib/gi18n-lib.h>
#include "gplugin-tcc-loader.h"
#include "gplugin-tcc-plugin.h"
+G_MODULE_EXPORT GPluginPluginInfo * +gplugin_query(G_GNUC_UNUSED GError **error) + const gchar *const authors[] = {"Eion Robb <eion@robbmob.com>", NULL}; -G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
- const gchar * const authors[] = {
- "Eion Robb <eion@robbmob.com>",
return gplugin_plugin_info_new(
GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
@@ -38,39 +36,34 @@
"name", "C source plugin loader",
"version", GPLUGIN_VERSION,
+ "license-id", "LGPL-2.0-or-later", "summary", "A plugin that can load C source plugins",
- "description", "This plugin allows the loading of plugins written in C.",
+ "description", "This plugin allows the loading of plugins written in " "website", GPLUGIN_WEBSITE,
-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); -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
+gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin, GError **error) - _("The TCC loader can not be unloaded")
+ _("The TCC loader can not be unloaded"));
--- a/tcc/gplugin-tcc-loader.c Thu Nov 07 23:09:55 2019 -0600
+++ b/tcc/gplugin-tcc-loader.c Sat Sep 05 20:05:36 2020 -0500
@@ -1,49 +1,51 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> - * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * 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-tcc-loader.h"
-#include "gplugin-tcc-plugin.h"
+#include <glib/gi18n-lib.h> +#include "gplugin-tcc-plugin.h" struct _GPluginTccLoader {
-G_DEFINE_DYNAMIC_TYPE(GPluginTccLoader, gplugin_tcc_loader, GPLUGIN_TYPE_LOADER);
/******************************************************************************
* 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"); -gplugin_tcc_loader_query(GPluginLoader *loader, const gchar *filename,
+gplugin_tcc_loader_query( GPluginPlugin *plugin = NULL;
GPluginPluginInfo *info = NULL;
@@ -58,7 +60,12 @@
tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
if(tcc_add_file(s, filename) == -1) {
- g_set_error(error, GPLUGIN_DOMAIN, 0, "couldn't load file %s", filename);
+ "couldn't load file %s", @@ -67,7 +74,11 @@
/* copy code into memory */
if((memsize = tcc_relocate(s, NULL)) < 0) {
- g_set_error(error, GPLUGIN_DOMAIN, 0, "couldn't work out how much memory is needed");
+ "couldn't work out how much memory is needed"); @@ -75,16 +86,25 @@
memneeded = g_malloc0(memsize);
if(tcc_relocate(s, memneeded) < 0) {
- g_set_error(error, GPLUGIN_DOMAIN, 0, "could not relocate plugin into memory");
+ "could not relocate plugin into memory"); - gplugin_query = (GPluginTccPluginQueryFunc) tcc_get_symbol(s, "gplugin_query");
- if (gplugin_query == NULL) {
- g_set_error(error, GPLUGIN_DOMAIN, 0, "no gplugin_query function found");
+ (GPluginTccPluginQueryFunc)tcc_get_symbol(s, "gplugin_query"); + if(gplugin_query == NULL) { + "no gplugin_query function found"); @@ -98,27 +118,31 @@
- plugin = g_object_new(GPLUGIN_TCC_TYPE_PLUGIN,
+ GPLUGIN_TCC_TYPE_PLUGIN, -gplugin_tcc_loader_load(G_GNUC_UNUSED GPluginLoader *loader,
+gplugin_tcc_loader_load( + G_GNUC_UNUSED GPluginLoader *loader, GPluginTccPluginLoadFunc gplugin_load = NULL;
TCCState *s = gplugin_tcc_plugin_get_state(GPLUGIN_TCC_PLUGIN(plugin));
- gplugin_load = (GPluginTccPluginLoadFunc) tcc_get_symbol(s, "gplugin_load");
- if (gplugin_load == NULL) {
+ gplugin_load = (GPluginTccPluginLoadFunc)tcc_get_symbol(s, "gplugin_load"); + if(gplugin_load == NULL) { g_set_error(error, GPLUGIN_DOMAIN, 0, "no gplugin_load function found");
@@ -128,16 +152,22 @@
-gplugin_tcc_loader_unload(G_GNUC_UNUSED GPluginLoader *loader,
+gplugin_tcc_loader_unload( + G_GNUC_UNUSED GPluginLoader *loader, GPluginTccPluginLoadFunc gplugin_unload = NULL;
TCCState *s = gplugin_tcc_plugin_get_state(GPLUGIN_TCC_PLUGIN(plugin));
- gplugin_unload = (GPluginTccPluginUnloadFunc) tcc_get_symbol(s, "gplugin_unload");
- if (gplugin_unload == NULL) {
- g_set_error(error, GPLUGIN_DOMAIN, 0, "no gplugin_unload function found");
+ (GPluginTccPluginUnloadFunc)tcc_get_symbol(s, "gplugin_unload"); + if(gplugin_unload == NULL) { + "no gplugin_unload function found"); @@ -149,19 +179,22 @@
*****************************************************************************/
-gplugin_tcc_loader_init(G_GNUC_UNUSED GPluginTccLoader *loader) {
+gplugin_tcc_loader_init(G_GNUC_UNUSED GPluginTccLoader *loader) -gplugin_tcc_loader_class_finalize(G_GNUC_UNUSED GPluginTccLoaderClass *klass) {
+gplugin_tcc_loader_class_finalize(G_GNUC_UNUSED GPluginTccLoaderClass *klass) -gplugin_tcc_loader_class_init(GPluginTccLoaderClass *klass) {
+gplugin_tcc_loader_class_init(GPluginTccLoaderClass *klass) 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;
@@ -171,6 +204,7 @@
*****************************************************************************/
-gplugin_tcc_loader_register(GPluginNativePlugin *plugin) {
+gplugin_tcc_loader_register(GPluginNativePlugin *plugin) gplugin_tcc_loader_register_type(G_TYPE_MODULE(plugin));
--- a/tcc/gplugin-tcc-loader.h Thu Nov 07 23:09:55 2019 -0600
+++ b/tcc/gplugin-tcc-loader.h Sat Sep 05 20:05:36 2020 -0500
@@ -1,18 +1,18 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> - * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * 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_TCC_LOADER_H
#define GPLUGIN_TCC_LOADER_H
@@ -23,11 +23,15 @@
#define GPLUGIN_TCC_TYPE_LOADER (gplugin_tcc_loader_get_type())
-G_DECLARE_FINAL_TYPE(GPluginTccLoader, gplugin_tcc_loader, GPLUGIN_TCC, LOADER, GPluginLoader)
void gplugin_tcc_loader_register(GPluginNativePlugin *plugin);
#endif /* GPLUGIN_TCC_LOADER_H */
--- a/tcc/gplugin-tcc-plugin.c Thu Nov 07 23:09:55 2019 -0600
+++ b/tcc/gplugin-tcc-plugin.c Sat Sep 05 20:05:36 2020 -0500
@@ -1,18 +1,18 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> - * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * 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-tcc-plugin.h"
@@ -49,7 +49,9 @@
-static GParamSpec *properties[N_PROPERTIES] = {NULL,};
+static GParamSpec *properties[N_PROPERTIES] = { /* I hate forward declarations... */
static void gplugin_tcc_plugin_iface_init(GPluginPluginInterface *iface);
@@ -59,8 +61,7 @@
- G_IMPLEMENT_INTERFACE(GPLUGIN_TYPE_PLUGIN, gplugin_tcc_plugin_iface_init)
+ G_IMPLEMENT_INTERFACE(GPLUGIN_TYPE_PLUGIN, gplugin_tcc_plugin_iface_init)); /******************************************************************************
* GPluginPlugin Implementation
@@ -74,15 +75,17 @@
*****************************************************************************/
-gplugin_tcc_plugin_get_property(GObject *obj, guint param_id, GValue *value,
+gplugin_tcc_plugin_get_property( GPluginTccPlugin *plugin = GPLUGIN_TCC_PLUGIN(obj);
- g_value_set_pointer(value,
- gplugin_tcc_plugin_get_state(plugin));
+ g_value_set_pointer(value, gplugin_tcc_plugin_get_state(plugin)); @@ -106,8 +109,11 @@
-gplugin_tcc_plugin_set_property(GObject *obj, guint param_id,
- const GValue *value, GParamSpec *pspec)
+gplugin_tcc_plugin_set_property( GPluginTccPlugin *plugin = GPLUGIN_TCC_PLUGIN(obj);
@@ -140,7 +146,8 @@
-gplugin_tcc_plugin_finalize(GObject *obj) {
+gplugin_tcc_plugin_finalize(GObject *obj) GPluginTccPlugin *plugin = GPLUGIN_TCC_PLUGIN(obj);
g_clear_pointer(&plugin->s, tcc_delete);
@@ -154,15 +161,18 @@
-gplugin_tcc_plugin_init(G_GNUC_UNUSED GPluginTccPlugin *plugin) {
+gplugin_tcc_plugin_init(G_GNUC_UNUSED GPluginTccPlugin *plugin) -gplugin_tcc_plugin_class_finalize(G_GNUC_UNUSED GPluginTccPluginClass *klass) {
+gplugin_tcc_plugin_class_finalize(G_GNUC_UNUSED GPluginTccPluginClass *klass) -gplugin_tcc_plugin_class_init(GPluginTccPluginClass *klass) {
+gplugin_tcc_plugin_class_init(GPluginTccPluginClass *klass) GObjectClass *obj_class = G_OBJECT_CLASS(klass);
obj_class->get_property = gplugin_tcc_plugin_get_property;
@@ -170,16 +180,16 @@
obj_class->finalize = gplugin_tcc_plugin_finalize;
properties[PROP_TCC_STATE] = g_param_spec_pointer(
- "tcc-state", "tcc-state",
"The TCC compilation context for the plugin",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); properties[PROP_MEM] = g_param_spec_pointer(
"The memory allocated for the symbol table for the plugin",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
@@ -194,14 +204,15 @@
*****************************************************************************/
-gplugin_tcc_plugin_register(GPluginNativePlugin *native) {
+gplugin_tcc_plugin_register(GPluginNativePlugin *native) gplugin_tcc_plugin_register_type(G_TYPE_MODULE(native));
-gplugin_tcc_plugin_get_state(GPluginTccPlugin *plugin) {
+gplugin_tcc_plugin_get_state(GPluginTccPlugin *plugin) g_return_val_if_fail(GPLUGIN_TCC_IS_PLUGIN(plugin), NULL);
--- a/tcc/gplugin-tcc-plugin.h Thu Nov 07 23:09:55 2019 -0600
+++ b/tcc/gplugin-tcc-plugin.h Sat Sep 05 20:05:36 2020 -0500
@@ -1,18 +1,18 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> - * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * 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_TCC_PLUGIN_H
#define GPLUGIN_TCC_PLUGIN_H
@@ -25,17 +25,23 @@
#define GPLUGIN_TCC_TYPE_PLUGIN (gplugin_tcc_plugin_get_type())
-G_DECLARE_FINAL_TYPE(GPluginTccPlugin, gplugin_tcc_plugin, GPLUGIN_TCC, PLUGIN, GObject)
void gplugin_tcc_plugin_register(GPluginNativePlugin *native);
TCCState *gplugin_tcc_plugin_get_state(GPluginTccPlugin *plugin);
typedef GPluginPluginInfo *(*GPluginTccPluginQueryFunc)(GError **error);
-typedef gboolean (*GPluginTccPluginLoadFunc)(GPluginNativePlugin *plugin, GError **error);
-typedef gboolean (*GPluginTccPluginUnloadFunc)(GPluginNativePlugin *plugin, GError **error);
+ *GPluginTccPluginLoadFunc)(GPluginNativePlugin *plugin, GError **error); + *GPluginTccPluginUnloadFunc)(GPluginNativePlugin *plugin, GError **error); #endif /* GPLUGIN_TCC_PLUGIN_H */
--- a/tcc/meson.build Thu Nov 07 23:09:55 2019 -0600
+++ b/tcc/meson.build Sat Sep 05 20:05:36 2020 -0500
@@ -21,7 +21,7 @@
dependencies : [TCC, gplugin_dep],
- install_dir : join_paths(get_option('libdir'), 'gplugin')
+ install_dir : get_option('libdir') / 'gplugin' --- a/tcc/tests/meson.build Thu Nov 07 23:09:55 2019 -0600
+++ b/tcc/tests/meson.build Sat Sep 05 20:05:36 2020 -0500
@@ -2,7 +2,7 @@
e = executable('test-tcc-loader', 'test-tcc-loader.c',
- '-DTCC_LOADER_DIR="@0@"'.format(join_paths(meson.current_build_dir(), '..')),
+ '-DTCC_LOADER_DIR="@0@/.."'.format(meson.current_build_dir()), '-DTCC_PLUGIN_DIR="@0@/plugins"'.format(
meson.current_source_dir()),
--- a/tcc/tests/plugins/basic-plugin.c Thu Nov 07 23:09:55 2019 -0600
+++ b/tcc/tests/plugins/basic-plugin.c Sat Sep 05 20:05:36 2020 -0500
@@ -1,29 +1,28 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> - * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * 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>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
- const gchar * const authors[] = {
+gplugin_query(G_GNUC_UNUSED GError **error) + const gchar *const authors[] = {"author1", NULL}; return gplugin_plugin_info_new(
"gplugin/native-basic-plugin",
@@ -35,21 +34,22 @@
"description", "description",
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/tcc/tests/plugins/dependent.c Thu Nov 07 23:09:55 2019 -0600
+++ b/tcc/tests/plugins/dependent.c Sat Sep 05 20:05:36 2020 -0500
@@ -1,49 +1,48 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> - * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * 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>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
- const gchar * const dependencies[] = {
+gplugin_query(G_GNUC_UNUSED GError **error) + const gchar *const dependencies[] = {"dependency1", "dependency2", NULL}; return gplugin_plugin_info_new(
"gplugin/native-dependent-plugin",
GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
"dependencies", dependencies,
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/tcc/tests/plugins/load-exception.c Thu Nov 07 23:09:55 2019 -0600
+++ b/tcc/tests/plugins/load-exception.c Sat Sep 05 20:05:36 2020 -0500
@@ -1,42 +1,43 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> - * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * 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>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
+gplugin_query(G_GNUC_UNUSED GError **error) return gplugin_plugin_info_new(
"gplugin/native-load-exception",
GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/tcc/tests/plugins/load-failed.c Thu Nov 07 23:09:55 2019 -0600
+++ b/tcc/tests/plugins/load-failed.c Sat Sep 05 20:05:36 2020 -0500
@@ -1,42 +1,43 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> - * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * 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>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
+gplugin_query(G_GNUC_UNUSED GError **error) return gplugin_plugin_info_new(
"gplugin/native-load-failed",
GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin, GError **error) {
+gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin, GError **error) g_set_error(error, GPLUGIN_DOMAIN, 0, "expected error");
-gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error)
--- a/tcc/tests/plugins/unload-failed.c Thu Nov 07 23:09:55 2019 -0600
+++ b/tcc/tests/plugins/unload-failed.c Sat Sep 05 20:05:36 2020 -0500
@@ -1,42 +1,43 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> - * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * 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>
G_MODULE_EXPORT GPluginPluginInfo *
-gplugin_query(G_GNUC_UNUSED GError **error) {
+gplugin_query(G_GNUC_UNUSED GError **error) return gplugin_plugin_info_new(
"gplugin/native-unload-failed",
GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
-gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
- G_GNUC_UNUSED GError **error)
+ G_GNUC_UNUSED GPluginNativePlugin *plugin, + G_GNUC_UNUSED GError **error) -gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin, GError **error) {
+gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin, GError **error) g_set_error(error, GPLUGIN_DOMAIN, 0, "expected error");
--- a/tcc/tests/test-tcc-loader.c Thu Nov 07 23:09:55 2019 -0600
+++ b/tcc/tests/test-tcc-loader.c Sat Sep 05 20:05:36 2020 -0500
@@ -1,31 +1,31 @@
- * Copyright (C) 2011-2013 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> - * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * 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) {
+main(gint argc, gchar **argv) g_test_init(&argc, &argv, NULL);
gplugin_loader_tests_main(TCC_LOADER_DIR, TCC_PLUGIN_DIR, "c");
--- a/vala/meson.build Thu Nov 07 23:09:55 2019 -0600
+++ b/vala/meson.build Sat Sep 05 20:05:36 2020 -0500
@@ -1,5 +1,5 @@
- if not get_option('gobject-introspection')
+ if not get_option('introspection') error('Vala generation requires GObject Introspection.')
@@ -8,7 +8,7 @@
gplugin_vapi = gnome.generate_vapi('gplugin',
sources : gplugin_gir[0],
- gir_dirs : join_paths(meson.current_build_dir(), '..', 'gplugin'),
+ gir_dirs : meson.current_build_dir() / '..' / 'gplugin', @@ -16,7 +16,7 @@
sources : gplugin_gtk_gir[0],
packages : [ 'gtk+-3.0' ],
- gir_dirs : join_paths(meson.current_build_dir(), '..', 'gplugin'),
+ gir_dirs : meson.current_build_dir() / '..' / 'gplugin', --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vala/tests/genie-plugins/basic.gs Sat Sep 05 20:05:36 2020 -0500
@@ -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 Sat Sep 05 20:05:36 2020 -0500
@@ -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 Sat Sep 05 20:05:36 2020 -0500
@@ -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 Sat Sep 05 20:05:36 2020 -0500
@@ -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 Sat Sep 05 20:05:36 2020 -0500
@@ -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 Sat Sep 05 20:05:36 2020 -0500
@@ -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 Thu Nov 07 23:09:55 2019 -0600
+++ b/vala/tests/meson.build Sat Sep 05 20:05:36 2020 -0500
@@ -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 Thu Nov 07 23:09:55 2019 -0600
+++ b/vala/tests/plugins/basic.vala Sat Sep 05 20:05:36 2020 -0500
@@ -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 Thu Nov 07 23:09:55 2019 -0600
+++ b/vala/tests/plugins/dependent.vala Sat Sep 05 20:05:36 2020 -0500
@@ -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 Thu Nov 07 23:09:55 2019 -0600
+++ b/vala/tests/plugins/load-exception.vala Sat Sep 05 20:05:36 2020 -0500
@@ -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 Thu Nov 07 23:09:55 2019 -0600
+++ b/vala/tests/plugins/load-failed.vala Sat Sep 05 20:05:36 2020 -0500
@@ -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 Thu Nov 07 23:09:55 2019 -0600
+++ b/vala/tests/plugins/unload-failed.vala Sat Sep 05 20:05:36 2020 -0500
@@ -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 Sat Sep 05 20:05:36 2020 -0500
@@ -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/>. +#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 Thu Nov 07 23:09:55 2019 -0600
+++ b/vala/tests/test-vala-loading.c Sat Sep 05 20:05:36 2020 -0500
@@ -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
@@ -16,19 +16,19 @@
#include <gplugin/gplugin-loader-tests.h>
/******************************************************************************
*****************************************************************************/
-main(gint argc, gchar **argv) {
+main(gint argc, gchar **argv) g_test_init(&argc, &argv, NULL);
gplugin_loader_tests_main(NULL, VALA_PLUGIN_DIR, "vala");