gplugin/gplugin

Merge 0.28.1 into default

2019-09-30, Gary Kramlich
db0d1998fea4
Merge 0.28.1 into default
  • +1 -1
    .hgignore
  • +1 -0
    .hgtags
  • +2 -1
    COPYRIGHT
  • +42 -0
    ChangeLog
  • +10 -0
    HACKING.OSX
  • +41 -0
    HISTORY.md
  • +0 -35
    INSTALL
  • +39 -0
    INSTALL.md
  • +0 -41
    README
  • +32 -0
    README.md
  • +158 -47
    convey.yml
  • +5 -1
    gplugin-gtk-viewer/gplugin-gtk-viewer-window.c
  • +2 -25
    gplugin-gtk-viewer/gplugin-gtk-viewer-window.h
  • +15 -15
    gplugin-gtk-viewer/gplugin-gtk-viewer.c
  • +55 -51
    gplugin-gtk/gplugin-gtk-plugin-info.c
  • +2 -23
    gplugin-gtk/gplugin-gtk-plugin-info.h
  • +25 -0
    gplugin-gtk/gplugin-gtk-store.c
  • +5 -25
    gplugin-gtk/gplugin-gtk-store.h
  • +20 -13
    gplugin-gtk/gplugin-gtk-view.c
  • +2 -23
    gplugin-gtk/gplugin-gtk-view.h
  • +1 -0
    gplugin-gtk/meson.build
  • +6 -0
    gplugin-gtk/reference/Dockerfile
  • +5 -5
    gplugin-gtk/reference/meson.build
  • +0 -8
    gplugin.sublime-project
  • +0 -4
    gplugin/gplugin-core.c
  • +0 -69
    gplugin/gplugin-enums.c.tmpl
  • +0 -44
    gplugin/gplugin-enums.h.tmpl
  • +9 -17
    gplugin/gplugin-file-tree.c
  • +11 -11
    gplugin/gplugin-loader-tests.c
  • +36 -10
    gplugin/gplugin-loader.c
  • +11 -22
    gplugin/gplugin-loader.h
  • +49 -46
    gplugin/gplugin-manager.c
  • +0 -4
    gplugin/gplugin-marshallers.list
  • +55 -33
    gplugin/gplugin-native-loader.c
  • +2 -23
    gplugin/gplugin-native-loader.h
  • +40 -31
    gplugin/gplugin-native-plugin.c
  • +3 -26
    gplugin/gplugin-native-plugin.h
  • +8 -8
    gplugin/gplugin-options.c
  • +46 -27
    gplugin/gplugin-plugin-info.c
  • +7 -22
    gplugin/gplugin-plugin-info.h
  • +25 -4
    gplugin/gplugin-plugin.c
  • +8 -13
    gplugin/gplugin-plugin.h
  • +2 -2
    gplugin/gplugin-private.c
  • +20 -20
    gplugin/gplugin-query.c
  • +4 -4
    gplugin/gplugin-version.c
  • +5 -33
    gplugin/meson.build
  • +6 -0
    gplugin/reference/Dockerfile
  • +54 -0
    gplugin/reference/embedding.xml
  • +10 -0
    gplugin/reference/gplugin-docs.xml
  • +56 -0
    gplugin/reference/lua.xml
  • +10 -12
    gplugin/reference/meson.build
  • +80 -0
    gplugin/reference/native-plugins.xml
  • +56 -0
    gplugin/reference/python.xml
  • +74 -0
    gplugin/reference/vala.xml
  • +6 -7
    gplugin/tests/bad-plugins/query-error.c
  • +5 -5
    gplugin/tests/bind-local/bind-local.c
  • +7 -7
    gplugin/tests/dynamic-type/dynamic-type-provider.c
  • +12 -8
    gplugin/tests/dynamic-type/dynamic-type-user.c
  • +4 -0
    gplugin/tests/dynamic-type/meson.build
  • +5 -5
    gplugin/tests/id-collision/id-collision1.c
  • +5 -5
    gplugin/tests/id-collision/id-collision2.c
  • +5 -5
    gplugin/tests/load-on-query-fail/load-on-query-fail.c
  • +5 -5
    gplugin/tests/load-on-query-pass/load-on-query-pass.c
  • +5 -5
    gplugin/tests/plugins/basic-plugin.c
  • +5 -5
    gplugin/tests/plugins/broken-dependent-plugin.c
  • +5 -5
    gplugin/tests/plugins/dependent-plugin.c
  • +5 -5
    gplugin/tests/plugins/load-exception.c
  • +5 -6
    gplugin/tests/plugins/load-failed.c
  • +5 -6
    gplugin/tests/plugins/unload-failed.c
  • +3 -3
    gplugin/tests/test-bind-local.c
  • +6 -6
    gplugin/tests/test-dynamic-type.c
  • +2 -2
    gplugin/tests/test-id-collision.c
  • +2 -9
    gplugin/tests/test-load-on-query.c
  • +3 -10
    gplugin/tests/test-native-loader.c
  • +3 -5
    gplugin/tests/test-option-group.c
  • +37 -21
    gplugin/tests/test-plugin-info.c
  • +0 -2
    gplugin/tests/test-plugin-manager-paths.c
  • +30 -30
    gplugin/tests/test-signals.c
  • +11 -39
    gplugin/tests/test-version-compare.c
  • +3 -3
    gplugin/tests/test-versioned-dependencies.c
  • +11 -1
    gplugin/tests/unresolved-symbol/meson.build
  • +5 -5
    gplugin/tests/unresolved-symbol/unresolved-symbol.c
  • +5 -5
    gplugin/tests/versioned-dependencies/bar.c
  • +5 -5
    gplugin/tests/versioned-dependencies/baz.c
  • +5 -5
    gplugin/tests/versioned-dependencies/exact1.c
  • +5 -5
    gplugin/tests/versioned-dependencies/exact2.c
  • +5 -5
    gplugin/tests/versioned-dependencies/fez.c
  • +5 -5
    gplugin/tests/versioned-dependencies/greater-equal.c
  • +5 -5
    gplugin/tests/versioned-dependencies/greater.c
  • +5 -5
    gplugin/tests/versioned-dependencies/less-equal.c
  • +5 -5
    gplugin/tests/versioned-dependencies/less.c
  • +5 -5
    gplugin/tests/versioned-dependencies/no-version.c
  • +5 -5
    gplugin/tests/versioned-dependencies/super-dependent.c
  • +5 -5
    lua/gplugin-lua-core.c
  • +12 -11
    lua/gplugin-lua-loader.c
  • +3 -25
    lua/gplugin-lua-loader.h
  • +24 -31
    lua/gplugin-lua-plugin.c
  • +3 -25
    lua/gplugin-lua-plugin.h
  • +2 -1
    lua/meson.build
  • +2 -2
    lua/tests/meson.build
  • +4 -47
    meson.build
  • +6 -0
    meson_options.txt
  • +2 -2
    packaging/debian/changelog
  • +3 -2
    packaging/debian/control
  • +3 -0
    packaging/debian/libgplugin-dev.install
  • +2 -0
    packaging/debian/libgplugin-gtk-dev.install
  • +67 -25
    packaging/gplugin.spec.in
  • +46 -0
    packaging/mingw-cross/PKGBUILD
  • +2 -2
    perl/gplugin-perl-core.c
  • +13 -40
    perl/gplugin-perl-loader.c
  • +6 -32
    perl/gplugin-perl-loader.h
  • +89 -60
    perl/gplugin-perl-plugin.c
  • +5 -31
    perl/gplugin-perl-plugin.h
  • +5 -5
    plugins/gplugin-license-check.c
  • +36 -0
    po/POTFILES
  • +1 -1
    po/meson.build
  • +5 -5
    python/gplugin-python-core.c
  • +47 -36
    python/gplugin-python-loader.c
  • +3 -25
    python/gplugin-python-loader.h
  • +39 -84
    python/gplugin-python-plugin.c
  • +3 -25
    python/gplugin-python-plugin.h
  • +3 -1
    python/gplugin-python-test-pygobject.c
  • +2 -2
    python/tests/meson.build
  • +0 -7
    python/tests/test-python-utils.c
  • +0 -70
    scripts/bitbucket_upload
  • +0 -31
    scripts/makeviz.sh
  • +5 -5
    tcc/gplugin-tcc-core.c
  • +24 -51
    tcc/gplugin-tcc-loader.c
  • +3 -29
    tcc/gplugin-tcc-loader.h
  • +92 -70
    tcc/gplugin-tcc-plugin.c
  • +5 -26
    tcc/gplugin-tcc-plugin.h
  • +1 -1
    tcc/meson.build
  • +1 -1
    tcc/tests/meson.build
  • +5 -5
    tcc/tests/plugins/basic-plugin.c
  • +5 -5
    tcc/tests/plugins/dependent.c
  • +5 -5
    tcc/tests/plugins/load-exception.c
  • +5 -6
    tcc/tests/plugins/load-failed.c
  • +5 -6
    tcc/tests/plugins/unload-failed.c
  • +24 -0
    vala/meson.build
  • +14 -0
    vala/tests/meson.build
  • +54 -0
    vala/tests/plugins/basic.vala
  • +46 -0
    vala/tests/plugins/dependent.vala
  • +43 -0
    vala/tests/plugins/load-exception.vala
  • +43 -0
    vala/tests/plugins/load-failed.vala
  • +17 -0
    vala/tests/plugins/meson.build
  • +43 -0
    vala/tests/plugins/unload-failed.vala
  • +34 -0
    vala/tests/test-vala-loading.c
  • +0 -94
    xsl/gtester-junit.xsl
  • --- a/.hgignore Tue Jan 22 22:58:59 2019 -0600
    +++ b/.hgignore Mon Sep 30 01:28:39 2019 -0500
    @@ -7,7 +7,6 @@
    \#*.ui\#
    syntax: regexp
    -^artifacts\/
    ^build.*\/
    ^packaging\/debian\/tmp\/
    ^packaging\/debian\/(.+\.)?(substvars|debhelper\.log)$
    @@ -15,5 +14,6 @@
    ^packaging\/debian\/libgplugin0?(-.+)?\/
    ^packaging\/debian\/gir1.2-gplugin-0.0\/
    ^packaging\/debian\/files$
    +^po\/.*\.pot$
    ^obj-x86_64-linux-gnu\/
    ^debian\/?$
    --- a/.hgtags Tue Jan 22 22:58:59 2019 -0600
    +++ b/.hgtags Mon Sep 30 01:28:39 2019 -0500
    @@ -30,3 +30,4 @@
    0aec4b15554d3d5b9a8e24e84387bd81988071b0 v0.28.0
    741a484ae91c05937a9a4435497dbb4924a4681d v0.0.28
    0000000000000000000000000000000000000000 v0.0.28
    +85f1c51427fe6ad61aa43fb2724e994fe234383a v0.28.1
    --- a/COPYRIGHT Tue Jan 22 22:58:59 2019 -0600
    +++ b/COPYRIGHT Mon Sep 30 01:28:39 2019 -0500
    @@ -1,10 +1,11 @@
    The following individuals have contributed to this project.
    Ankit Vani <a@nevitus.org>
    -EionRobb
    +EionRobb <eion@robbmob.com>
    Elliott Sales de Andrade <quantum.analyst@gmail.com>
    Gary Kramlich <grim@reaperworld.com>
    Jason Scherer <schereja@gmail.com>
    John Bailey <rekkanoryo@rekkanoryo.org>
    Mike Ruprecht <cmaiku@gmail.com>
    +Olaf Hering <olaf@aepfle.de>
    Richard Laager <rlaager@pidgin.im>
    --- a/ChangeLog Tue Jan 22 22:58:59 2019 -0600
    +++ b/ChangeLog Mon Sep 30 01:28:39 2019 -0500
    @@ -1,3 +1,45 @@
    +0.28.1: 2019/09/30
    + General
    + * Fix a bug that scanbuild found in test-plugin-info (Gary Kramlich)
    + * Fix an issue pvs-studio found for using g_set_error instead of
    + g_error_set_literal (PR #34) (Gary Kramlich)
    + * Clean up the rpm spec.in file (PR #29) (Gary Kramlich)
    + * Fix the build when being built as a subproject in meson (PR #28) (Gary
    + Kramlich)
    + * Fix building the Lua loader on FreeBSD (PR #25) (Gary Kramlich)
    + * Look for plugins with both .so and .dylib extensions on MacOS (PR #16)
    + (Gary Kramlich)
    + * Fix a segfault in GPluginFileTree (PR #15) (Olaf Hering)
    + * Fix valgrind and other memory issues (PR #11, PR #12) (Elliot Sales de
    + Andrade)
    + * Fix warnings from Python headers (PR #10) (Elliott Sales de Andrade)
    + * Use g_set_error (PR #6) (Elliott Sales de Andrade)
    + * Use g_clear_pointer (PR #6) (Elliott Sales de Andrade)
    + * Use g_clear_object (PR #6) (Elliott Sales de Andrade)
    + * Use g_value_dup (PR #6) (Elliott Sales de Andrade)
    + * Remove null checks from g_strdup (PR #6) (Elliott Sales de Andrade)
    + * Make sure testing asserts can't be disabled (PR #6) (Elliott Sales de
    + Andrade)
    + * Fix some potential reference counting bugs (PR #6) (Elliott Sales de
    + Andrade)
    + * Removed checks for glib < 2.40 as that's our required minimum now. (PR #6)
    + (Elliott Sales de Andrade)
    + * Replaced GPLUGIN_UNUSED with G_GNUC_UNUSED (PR #6) (Elliott Sales de
    + Andrade)
    + * Created VAPI for Vala Bindings. (#76) (Gary Kramlich)
    + * Added docs for Vala. (#76) (Gary Kramlich)
    +
    + Python Loader
    + * Use Py_CLEAR and Py_XINCREF on private attributes (PR #6) (Elliott Sales de
    + Andrade)
    +
    + Perl Loader
    + * Made it compile again (still incomplete) (PR #7) (Elliott Sales de Andrade)
    +
    + TCC Loader
    + * Made it compile again, disabled by default (PR #7) (Elliott Sales de
    + Andrade)
    +
    0.28.0: 2019/01/22
    * Fixed building on OSX with homebrew
    * Added an RPM spec file
    --- a/HACKING.OSX Tue Jan 22 22:58:59 2019 -0600
    +++ b/HACKING.OSX Mon Sep 30 01:28:39 2019 -0500
    @@ -4,6 +4,16 @@
    support fink or macports, please let me know and I will merge your pull
    request.
    +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:
    +
    +```
    +export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:$(brew --prefix libffi)/lib/pkgconfig"
    +meson -Dlua=false -Dpython=false -Dgobject-introspection=false build
    +cd build
    +ninja
    +```
    +
    Lua
    ===
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/HISTORY.md Mon Sep 30 01:28:39 2019 -0500
    @@ -0,0 +1,41 @@
    +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.
    +
    +After trying to fix this numerous times in the Guifications 3 tree, I decided
    +I should really do this the UNIX way and write it as a stand alone library.
    +
    +During this time, I also got the idea that there was a good chance that someone
    +probably beat me to this... So I started searching and came across libpeas.
    +
    +Libpeas looked promising, but there was a few things about it that I really
    +didn't care for. First of all, the plugin information (id, name, author, etc)
    +are in a separate data file that gets stored in a separate location on disk.
    +
    +Getting people to write good plugins is difficult enough as it is, why bother
    +throwing more obstacles in their way? This data file is a essentially a
    +GKeyFile, which means you can store the translations of all the fields right in
    +it. Now this is great if your plugin doesn't have any strings to display at
    +runtime, but if it does, you still need to install the translation file itself.
    +So as long as your plugin has to display strings at runtime, all that data file
    +gave you was more work. So there was STRIKE ONE!
    +
    +So I continued to look at libpeas and noticed something odd in the earlier
    +mentioned data file. One of the fields you have to set is the Loader!? Yes,
    +the libpeas authors explicitly expect you to call out which loader you need. I
    +personally find this to be very lazy. I realize it makes it easier to code,
    +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
    +was STRIKE THREE!
    +
    +Libpeas had struck out for me, and as such I started GPlugin the very next day!
    +
    --- a/INSTALL Tue Jan 22 22:58:59 2019 -0600
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,35 +0,0 @@
    -Dependencies
    -============
    -GPlugin depends on the following at a bare minimum:
    - glib-2.0 >= 2.34.0
    - gobject-introspection, libgirepository1.0-dev
    - meson >= 0.37.0
    - gettext
    - help2man
    - a C compiler
    -
    -A full build (enabled by default) depends on the following:
    - gtk-3
    - python3-dev, python-gi-dev, python3-gi
    - liblua5.1-0-dev, lua-lgi
    - xsltproc
    -
    -All of these packages and their development headers need to be installed
    -prior to building GPlugin.
    -
    -Building
    -========
    -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.
    -
    -Meson requires you to build in a separate directory than your source. As such, these instructions use a separate build directory.
    -
    -To compile you need to run the following commands:
    -
    - meson build
    - cd build
    - ninja install
    -
    -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.
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/INSTALL.md Mon Sep 30 01:28:39 2019 -0500
    @@ -0,0 +1,39 @@
    +# Dependencies
    +
    +GPlugin depends on the following at a bare minimum:
    + * glib-2.0 >= 2.40.0
    + * gobject-introspection, libgirepository1.0-dev
    + * meson >= 0.42.0
    + * gettext
    + * help2man
    + * a C compiler
    +
    +A full build (enabled by default) depends on the following:
    + * gtk-3
    + * python3-dev, python-gi-dev, python3-gi
    + * liblua5.1-0-dev, lua-lgi
    + * valac
    +
    +All of these packages and their development headers need to be installed
    +prior to building GPlugin.
    +
    +# Building
    +
    +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.
    +
    +Meson requires you to build in a separate directory than your source. As such,
    +these instructions use a separate build directory.
    +
    +To compile you need to run the following commands:
    +
    +```
    +meson build
    +cd build
    +ninja install
    +```
    +
    +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.
    +
    --- a/README Tue Jan 22 22:58:59 2019 -0600
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,41 +0,0 @@
    -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.
    -
    -After trying to fix this numerous times in the Guifications 3 tree, I decided
    -I should really do this the UNIX way and write it as a stand alone library.
    -
    -During this time, I also got the idea that there was a good chance that someone
    -probably beat me to this... So I started searching and came across libpeas.
    -
    -Libpeas looked promising, but there was a few things about it that I really
    -didn't care for. First of all, the plugin information (id, name, author, etc)
    -are in a separate data file that gets stored in a separate location on disk.
    -
    -Getting people to write good plugins is difficult enough as it is, why bother
    -throwing more obstacles in their way? This data file is a essentially a
    -GKeyFile, which means you can store the translations of all the fields right in
    -it. Now this is great if your plugin doesn't have any strings to display at
    -runtime, but if it does, you still need to install the translation file itself.
    -So as long as your plugin has to display strings at runtime, all that data file
    -gave you was more work. So there was STRIKE ONE!
    -
    -So I continued to look at libpeas and noticed something odd in the earlier
    -mentioned data file. One of the fields you have to set is the Loader!? Yes,
    -the libpeas authors explicitly expect you to call out which loader you need. I
    -personally find this to be very lazy. I realize it makes it easier to code,
    -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
    -was STRIKE THREE!
    -
    -Libpeas had struck out for me, and as such I started GPlugin the very next day!
    -
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/README.md Mon Sep 30 01:28:39 2019 -0500
    @@ -0,0 +1,32 @@
    +# 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
    +to the other languages.
    +
    +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.
    +
    +## Build Status
    +
    +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/)
    +
    +## History
    +
    +GPlugin has a bit of history, you can read more about it in [HISTORY.md](HISTORY.md)
    +
    +## Language Support
    +
    +GPlugin currently supports plugins written in C/C++, Lua, Python, and Vala.
    +
    +## API Reference
    +
    +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).
    --- a/convey.yml Tue Jan 22 22:58:59 2019 -0600
    +++ b/convey.yml Mon Sep 30 01:28:39 2019 -0500
    @@ -2,21 +2,33 @@
    - PACKAGECLOUD_REPO=experimental
    - ARCH=amd64
    - BUILD_NUMBER
    + - REPOSITORY=gplugin/builders
    + - REGISTRY=docker.io
    + - REGISTRY_USERNAME
    + - REGISTRY_PASSWORD
    + - DOCS_BUILD_IMAGE=${REGISTRY}/${REPOSITORY}:debian-buster-amd64
    + - DOCS_VERSION=latest
    tasks:
    clean:
    type: convey/clean
    files:
    - alpine-edge-amd64
    + - debian-bullseye-amd64
    - debian-buster-amd64
    - - debian-stretch-amd64
    - - fedora-28-amd64
    + - dist
    + - docs
    + - elementary-juno-amd64
    - fedora-29-amd64
    + - fedora-30-amd64
    + - mingw-w64-i686
    + - mingw-w64-x86_64
    - opensuse-tumbleweed-amd64
    - pvs-studio
    - scanbuild
    - - ubuntu-xenial-amd64
    - ubuntu-bionic-amd64
    + - ubuntu-cosmic-amd64
    + - ubuntu-disco-amd64
    import:
    type: docker/import
    @@ -28,12 +40,47 @@
    build:
    type: docker/run
    - image: gplugin/builders:${DISTRO}-${VERSION}-${ARCH}
    + image: ${REGISTRY}/${REPOSITORY}:${DISTRO}-${VERSION}-${ARCH}
    export:
    type: docker/export
    files: ${DISTRO}-${VERSION}-${ARCH}
    + build-target:
    + type: docker/run
    + image: ${REGISTRY}/${REPOSITORY}:${TARGET}
    +
    + export-target:
    + type: docker/export
    + files: ${TARGET}
    +
    + login:
    + type: docker/login
    + server: ${REGISTRY}
    + username: ${REGISTRY_USERNAME}
    + password: ${REGISTRY_PASSWORD}
    +
    + logout:
    + type: docker/logout
    + server: ${REGISTRY}
    +
    + docs-build:
    + type: docker/run
    + image: ${DOCS_BUILD_IMAGE}
    + workdir: ${CONVEY_WORKSPACE}
    + script:
    + - set -ex
    + - meson build-docs-${TARGET}
    + - ninja -C build-docs-${TARGET} ${TARGET}-doc
    + docs-build-image:
    + type: docker/build
    + dockerfile: ${DOCS_PATH}/Dockerfile
    + tag: ${REGISTRY}/gplugin/${TARGET}-docs:${DOCS_VERSION}
    + files: build-docs-${TARGET}/${DOCS_PATH}/html:.
    + docs-publish-image:
    + type: docker/push
    + image: ${REGISTRY}/gplugin/${TARGET}-docs:${DOCS_VERSION}
    +
    package-cloud:
    type: docker/run
    image: rwgrim/package_cloud:latest
    @@ -57,21 +104,6 @@
    task: package-cloud
    environment: [PATTERN=x86_64/*.rpm]
    - pvs-studio:
    - type: docker/run
    - image: gplugin/builders:pvs-studio
    - environment: [PVS_STUDIO_USERNAME, PVS_STUDIO_KEY]
    - pvs-studio-export:
    - type: docker/export
    - files: pvs-studio
    -
    - scanbuild:
    - type: docker/run
    - image: gplugin/builders:scanbuild
    - scanbuild-export:
    - type: docker/export
    - files: scanbuild
    -
    plans:
    clean:
    stages:
    @@ -82,22 +114,65 @@
    stages:
    - tasks: [import, build, export]
    - debian-stretch-amd64:
    - environment: [DISTRO=debian, VERSION=stretch]
    - stages:
    - - tasks: [import, build, export]
    -
    debian-buster-amd64:
    environment: [DISTRO=debian, VERSION=buster]
    stages:
    - tasks: [import, build, export]
    - fedora-28-amd64:
    - environment: [DISTRO=fedora, VERSION=28]
    + debian-bullseye-amd64:
    + environment: [DISTRO=debian, VERSION=bullseye]
    + stages:
    + - tasks: [import, build, export]
    +
    + dist:
    + environment: [TARGET=dist]
    + stages:
    + - tasks: [import, build-target, export-target]
    +
    + elementary-juno-amd64:
    + environment: [DISTRO=elementary, VERSION=juno]
    + stages:
    + - tasks: [import, build, export]
    +
    + fedora-29-amd64:
    + environment: [DISTRO=fedora, VERSION=29]
    + stages:
    + - tasks: [import, build, export]
    + fedora-30-amd64:
    + environment: [DISTRO=fedora, VERSION=30]
    stages:
    - tasks: [import, build, export]
    - fedora-29-amd64:
    - environment: [DISTRO=fedora, VERSION=29]
    +
    + gplugin-docs:
    + environment: [TARGET=gplugin, DOCS_PATH=gplugin/reference]
    + stages:
    + - tasks: [import, docs-build, docs-build-image]
    + gplugin-docs-ci:
    + environment: [TARGET=gplugin, DOCS_PATH=gplugin/reference]
    + stages:
    + - tasks: [import, docs-build, docs-build-image]
    + - tasks: [login, docs-publish-image]
    + - tasks: [logout]
    + run: always
    +
    + gplugin-gtk-docs:
    + environment: [TARGET=gplugin-gtk, DOCS_PATH=gplugin-gtk/reference]
    + stages:
    + - tasks: [import, docs-build, docs-build-image]
    + gplugin-gtk-docs-ci:
    + environment: [TARGET=gplugin-gtk, DOCS_PATH=gplugin-gtk/reference]
    + stages:
    + - tasks: [import, docs-build, docs-build-image]
    + - tasks: [login, docs-publish-image]
    + - tasks: [logout]
    + run: always
    +
    + mingw-w64-i686:
    + environment: [DISTRO=mingw, VERSION=w64, ARCH=i686, PKGBUILD_DIR=mingw-cross]
    + stages:
    + - tasks: [import, build, export]
    + mingw-w64-x86_64:
    + environment: [DISTRO=mingw, VERSION=w64, ARCH=x86_64, PKGBUILD_DIR=mingw-cross]
    stages:
    - tasks: [import, build, export]
    @@ -107,57 +182,93 @@
    - tasks: [import, build, export]
    pvs-studio:
    + environment:
    + - TARGET=pvs-studio
    + - PVS_STUDIO_USERNAME
    + - PVS_STUDIO_KEY
    stages:
    - - tasks: [import, pvs-studio, pvs-studio-export]
    + - tasks: [import, build-target]
    + - tasks: [export-target]
    + run: always
    scanbuild:
    + environment: [TARGET=scanbuild]
    stages:
    - - tasks: [import, scanbuild, scanbuild-export]
    + - tasks: [import, build-target]
    + - tasks: [export-target]
    + run: always
    +
    + simple:
    + environment: [TARGET=simple]
    + stages:
    + - tasks: [import, build-target]
    ubuntu-bionic-amd64:
    environment: [DISTRO=ubuntu, VERSION=bionic]
    stages:
    - tasks: [import, build, export]
    + ubuntu-cosmic-amd64:
    + environment: [DISTRO=ubuntu, VERSION=cosmic]
    + stages:
    + - tasks: [import, build, export]
    + ubuntu-disco-amd64:
    + environment: [DISTRO=ubuntu, VERSION=disco]
    + stages:
    + - tasks: [import, build, export]
    +
    + valgrind:
    + environment: [TARGET=valgrind]
    + stages:
    + - tasks: [import, build-target]
    + - tasks: [export-target]
    + run: always
    publish:
    stages:
    - environment:
    - DISTRO=debian
    - - VERSION=stretch
    - tasks: [import-artifacts, publish-deb, publish-debsrc]
    - - environment:
    - - DISTRO=debian
    - VERSION=buster
    tasks: [import-artifacts, publish-deb, publish-debsrc]
    - environment:
    + - DISTRO=elementary
    + - VERSION=juno
    + tasks: [import-artifacts, publish-deb, publish-debsrc]
    + - environment:
    - DISTRO=fedora
    - - VERSION=28
    + - VERSION=29
    tasks: [import-artifacts, publish-rpm]
    - environment:
    - DISTRO=fedora
    - - VERSION=29
    + - VERSION=30
    tasks: [import-artifacts, publish-rpm]
    - environment:
    - DISTRO=ubuntu
    - VERSION=bionic
    tasks: [import-artifacts, publish-deb, publish-debsrc]
    + - environment:
    + - DISTRO=ubuntu
    + - VERSION=cosmic
    + tasks: [import-artifacts, publish-deb, publish-debsrc]
    + - environment:
    + - DISTRO=ubuntu
    + - VERSION=disco
    + tasks: [import-artifacts, publish-deb, publish-debsrc]
    meta-plans:
    - alpine:
    + all:
    plans:
    - alpine-edge-amd64
    - debian:
    - plans:
    - - debian-stretch-amd64
    + - debian-bullseye-amd64
    - debian-buster-amd64
    - fedora:
    - plans:
    - - fedora-28-amd64
    + - dist
    + - docs
    + - elementary-juno-amd64
    - fedora-29-amd64
    - opensuse:
    - plans:
    + - fedora-30-amd64
    - opensuse-tumbleweed-amd64
    - ubuntu:
    - plans:
    + - pvs-studio
    + - scanbuild
    - ubuntu-bionic-amd64
    + - ubuntu-cosmic-amd64
    + - ubuntu-disco-amd64
    --- a/gplugin-gtk-viewer/gplugin-gtk-viewer-window.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin-gtk-viewer/gplugin-gtk-viewer-window.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,6 +19,10 @@
    #include "gplugin-gtk-viewer-window.h"
    +struct _GPluginGtkViewerWindow {
    + GtkWindow parent;
    +};
    +
    G_DEFINE_TYPE(GPluginGtkViewerWindow, gplugin_gtk_viewer_window, GTK_TYPE_WINDOW)
    /******************************************************************************
    @@ -42,7 +46,7 @@
    *****************************************************************************/
    GtkWidget *gplugin_gtk_viewer_window_new(void) {
    return GTK_WIDGET(g_object_new(
    - GPLUGIN_GTK_TYPE_VIEWER_WINDOW,
    + GPLUGIN_GTK_VIEWER_TYPE_WINDOW,
    NULL
    ));
    }
    --- a/gplugin-gtk-viewer/gplugin-gtk-viewer-window.h Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin-gtk-viewer/gplugin-gtk-viewer-window.h Mon Sep 30 01:28:39 2019 -0500
    @@ -19,39 +19,16 @@
    #ifndef GPLUGIN_GTK_VIEWER_WINDOW_H
    #define GPLUGIN_GTK_VIEWER_WINDOW_H
    -#include <gtk/gtk.h>
    -
    -#define GPLUGIN_GTK_TYPE_VIEWER_WINDOW (gplugin_gtk_viewer_window_get_type())
    -#define GPLUGIN_GTK_VIEWER_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GPLUGIN_GTK_TYPE_VIEWER_WINDOW, GPluginGtkViewerWindow))
    -#define GPLUGIN_GTK_VIEWER_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GPLUGIN_GTK_TYPE_VIEWER_WINDOW, GPluginGtkViewerWindowClass))
    -#define GPLUGIN_GTK_IS_VIEWER_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GPLUGIN_GTK_TYPE_VIEWER_WINDOW))
    -#define GPLUGIN_GTK_IS_VIEWER_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GPLUGIN_GTK_TYPE_VIEWER_WINDOW))
    -#define GPLUGIN_GTK_VIEWER_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GPLUGIN_GTK_TYPE_VIEWER_WINDOW, GPluginGtkViewerWindowClass))
    -
    -typedef struct _GPluginGtkViewerWindow GPluginGtkViewerWindow;
    -typedef struct _GPluginGtkViewerWindowClass GPluginGtkViewerWindowClass;
    -
    #include <glib.h>
    #include <glib-object.h>
    #include <gtk/gtk.h>
    -struct _GPluginGtkViewerWindow {
    - GtkWindow parent;
    -
    - gpointer reserved[4];
    -};
    -
    -struct _GPluginGtkViewerWindowClass {
    - GtkWindowClass parent;
    -
    - gpointer reserved[4];
    -};
    +#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)
    G_BEGIN_DECLS
    -GType gplugin_gtk_viewer_window_get_type(void);
    -
    GtkWidget *gplugin_gtk_viewer_window_new(void);
    G_END_DECLS
    --- a/gplugin-gtk-viewer/gplugin-gtk-viewer.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin-gtk-viewer/gplugin-gtk-viewer.c Mon Sep 30 01:28:39 2019 -0500
    @@ -34,9 +34,9 @@
    * Callbacks
    *****************************************************************************/
    static gboolean
    -window_closed_cb(GPLUGIN_UNUSED GtkWidget *w,
    - GPLUGIN_UNUSED GdkEvent *e,
    - GPLUGIN_UNUSED gpointer d)
    +window_closed_cb(G_GNUC_UNUSED GtkWidget *w,
    + G_GNUC_UNUSED GdkEvent *e,
    + G_GNUC_UNUSED gpointer d)
    {
    gtk_main_quit();
    @@ -63,10 +63,10 @@
    * Helpers
    *****************************************************************************/
    static gboolean
    -internal_cb(GPLUGIN_UNUSED const gchar *n,
    - GPLUGIN_UNUSED const gchar *v,
    - GPLUGIN_UNUSED gpointer d,
    - GPLUGIN_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)
    {
    show_internal = TRUE;
    @@ -74,10 +74,10 @@
    }
    static gboolean
    -no_default_cb(GPLUGIN_UNUSED const gchar *n,
    - GPLUGIN_UNUSED const gchar *v,
    - GPLUGIN_UNUSED gpointer d,
    - GPLUGIN_UNUSED GError **e)
    +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)
    {
    add_default_paths = FALSE;
    @@ -85,10 +85,10 @@
    }
    static gboolean
    -version_cb(GPLUGIN_UNUSED const gchar *n,
    - GPLUGIN_UNUSED const gchar *v,
    - GPLUGIN_UNUSED gpointer d,
    - GPLUGIN_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)
    {
    version_only = TRUE;
    --- a/gplugin-gtk/gplugin-gtk-plugin-info.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin-gtk/gplugin-gtk-plugin-info.c Mon Sep 30 01:28:39 2019 -0500
    @@ -27,10 +27,24 @@
    * #GPluginGtkPluginInfo is a Gtk+ widget that shows information about plugins.
    */
    +/**
    + * GPLUGIN_GTK_TYPE_PLUGIN_INFO:
    + *
    + * The standard _get_type macro for #GPluginGtkPluginInfo.
    + */
    +
    +/**
    + * GPluginGtkPluginInfo:
    + *
    + * A widget that displays a #GPluginPluginInfo in a user friendly way.
    + */
    +
    /******************************************************************************
    * Structs
    *****************************************************************************/
    -typedef struct {
    +struct _GPluginGtkPluginInfo {
    + GtkBox parent;
    +
    GPluginPlugin *plugin;
    GtkWidget *name;
    @@ -47,7 +61,7 @@
    GtkWidget *loader;
    GtkWidget *internal;
    GtkWidget *load_on_query;
    -} GPluginGtkPluginInfoPrivate;
    +};
    /*****************************************************************************s
    * Enums
    @@ -59,14 +73,14 @@
    };
    static GParamSpec *properties[N_PROPERTIES] = {NULL,};
    -G_DEFINE_TYPE_WITH_PRIVATE(GPluginGtkPluginInfo, gplugin_gtk_plugin_info, GTK_TYPE_BOX);
    +G_DEFINE_TYPE(GPluginGtkPluginInfo, gplugin_gtk_plugin_info, GTK_TYPE_BOX);
    /******************************************************************************
    * Callbacks
    *****************************************************************************/
    static void
    gplugin_gtk_plugin_info_expander_activate(GtkExpander *expander,
    - GPLUGIN_UNUSED gpointer data)
    + G_GNUC_UNUSED gpointer data)
    {
    if(gtk_expander_get_expanded(expander))
    gtk_expander_set_label(expander, "More");
    @@ -78,7 +92,7 @@
    * Helpers
    *****************************************************************************/
    static void
    -_gplugin_gtk_plugin_info_refresh(GPluginGtkPluginInfoPrivate *priv,
    +_gplugin_gtk_plugin_info_refresh(GPluginGtkPluginInfo *info,
    GPluginPlugin *plugin)
    {
    GtkWidget *widget = NULL;
    @@ -93,7 +107,7 @@
    const gchar *filename = NULL;
    /* remove all the children from the authors box */
    - children = gtk_container_get_children(GTK_CONTAINER(priv->authors_box));
    + children = gtk_container_get_children(GTK_CONTAINER(info->authors_box));
    for(iter = children; iter; iter = iter->next)
    gtk_widget_destroy(GTK_WIDGET(iter->data));
    g_list_free(children);
    @@ -145,17 +159,17 @@
    g_object_unref(G_OBJECT(plugin_info));
    }
    - gtk_label_set_markup(GTK_LABEL(priv->name), (name) ? name : "Unnamed");
    - gtk_label_set_text(GTK_LABEL(priv->version), (version) ? version : "");
    - gtk_label_set_markup(GTK_LABEL(priv->website), (website) ? website : "");
    - gtk_label_set_text(GTK_LABEL(priv->summary), (summary) ? summary : "");
    - gtk_label_set_text(GTK_LABEL(priv->description), (description) ? description : "");
    - gtk_label_set_text(GTK_LABEL(priv->id), (id) ? id : "");
    - gtk_label_set_text(GTK_LABEL(priv->filename), (filename) ? filename : "");
    - gtk_label_set_text(GTK_LABEL(priv->abi_version), (abi_version) ? abi_version : "");
    - gtk_label_set_text(GTK_LABEL(priv->loader), (loader) ? loader : "Unknown");
    - gtk_label_set_text(GTK_LABEL(priv->internal), (internal) ? "Yes" : "No");
    - gtk_label_set_text(GTK_LABEL(priv->load_on_query), (loq) ? "Yes" : "No");
    + gtk_label_set_markup(GTK_LABEL(info->name), (name) ? name : "Unnamed");
    + 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_set_text(GTK_LABEL(info->id), (id) ? id : "");
    + 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_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");
    g_free(description);
    g_free(id);
    @@ -172,7 +186,7 @@
    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(priv->authors_box), widget, TRUE, TRUE, 0);
    + gtk_box_pack_start(GTK_BOX(info->authors_box), widget, TRUE, TRUE, 0);
    gtk_widget_show(widget);
    }
    }
    @@ -217,11 +231,9 @@
    static void
    gplugin_gtk_plugin_info_finalize(GObject *obj) {
    - GPluginGtkPluginInfoPrivate *priv = gplugin_gtk_plugin_info_get_instance_private(GPLUGIN_GTK_PLUGIN_INFO(obj));
    + GPluginGtkPluginInfo *info = GPLUGIN_GTK_PLUGIN_INFO(obj);
    - if(priv->plugin != NULL) {
    - g_object_unref(priv->plugin);
    - }
    + g_clear_object(&info->plugin);
    G_OBJECT_CLASS(gplugin_gtk_plugin_info_parent_class)->finalize(obj);
    }
    @@ -254,20 +266,20 @@
    "/org/bitbucket/gplugin/gplugin-gtk/plugin-info.ui"
    );
    - gtk_widget_class_bind_template_child_private(widget_class, GPluginGtkPluginInfo, name);
    - gtk_widget_class_bind_template_child_private(widget_class, GPluginGtkPluginInfo, version);
    - gtk_widget_class_bind_template_child_private(widget_class, GPluginGtkPluginInfo, authors_box);
    - gtk_widget_class_bind_template_child_private(widget_class, GPluginGtkPluginInfo, website);
    - gtk_widget_class_bind_template_child_private(widget_class, GPluginGtkPluginInfo, summary);
    - gtk_widget_class_bind_template_child_private(widget_class, GPluginGtkPluginInfo, description);
    - gtk_widget_class_bind_template_child_private(widget_class, GPluginGtkPluginInfo, dependencies);
    - gtk_widget_class_bind_template_child_private(widget_class, GPluginGtkPluginInfo, expander);
    - gtk_widget_class_bind_template_child_private(widget_class, GPluginGtkPluginInfo, id);
    - gtk_widget_class_bind_template_child_private(widget_class, GPluginGtkPluginInfo, filename);
    - gtk_widget_class_bind_template_child_private(widget_class, GPluginGtkPluginInfo, abi_version);
    - gtk_widget_class_bind_template_child_private(widget_class, GPluginGtkPluginInfo, loader);
    - gtk_widget_class_bind_template_child_private(widget_class, GPluginGtkPluginInfo, internal);
    - gtk_widget_class_bind_template_child_private(widget_class, GPluginGtkPluginInfo, load_on_query);
    + 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_callback(widget_class, gplugin_gtk_plugin_info_expander_activate);
    }
    @@ -302,23 +314,19 @@
    gplugin_gtk_plugin_info_set_plugin(GPluginGtkPluginInfo *info,
    GPluginPlugin *plugin)
    {
    - GPluginGtkPluginInfoPrivate *priv = NULL;
    + GPluginPlugin *orig_plugin;
    g_return_if_fail(GPLUGIN_GTK_IS_PLUGIN_INFO(info));
    - priv = gplugin_gtk_plugin_info_get_instance_private(info);
    -
    - if(GPLUGIN_IS_PLUGIN(priv->plugin)) {
    - g_object_unref(G_OBJECT(priv->plugin));
    - }
    -
    + orig_plugin = info->plugin;
    if(GPLUGIN_IS_PLUGIN(plugin)) {
    - priv->plugin = GPLUGIN_PLUGIN(g_object_ref(G_OBJECT(plugin)));
    + info->plugin = GPLUGIN_PLUGIN(g_object_ref(G_OBJECT(plugin)));
    } else {
    - priv->plugin = NULL;
    + info->plugin = NULL;
    }
    + g_object_unref(G_OBJECT(orig_plugin));
    - _gplugin_gtk_plugin_info_refresh(priv, plugin);
    + _gplugin_gtk_plugin_info_refresh(info, plugin);
    }
    /**
    @@ -332,11 +340,7 @@
    */
    GPluginPlugin *
    gplugin_gtk_plugin_info_get_plugin(GPluginGtkPluginInfo *info) {
    - GPluginGtkPluginInfoPrivate *priv = NULL;
    -
    g_return_val_if_fail(GPLUGIN_GTK_IS_PLUGIN_INFO(info), NULL);
    - priv = gplugin_gtk_plugin_info_get_instance_private(info);
    -
    - return (priv->plugin) ? GPLUGIN_PLUGIN(g_object_ref(G_OBJECT(priv->plugin))) : NULL;
    + return (info->plugin) ? GPLUGIN_PLUGIN(g_object_ref(G_OBJECT(info->plugin))) : NULL;
    }
    --- a/gplugin-gtk/gplugin-gtk-plugin-info.h Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin-gtk/gplugin-gtk-plugin-info.h Mon Sep 30 01:28:39 2019 -0500
    @@ -22,16 +22,6 @@
    #ifndef GPLUGIN_GTK_PLUGIN_INFO_H
    #define GPLUGIN_GTK_PLUGIN_INFO_H
    -#define GPLUGIN_GTK_TYPE_PLUGIN_INFO (gplugin_gtk_plugin_info_get_type())
    -#define GPLUGIN_GTK_PLUGIN_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GPLUGIN_GTK_TYPE_PLUGIN_INFO, GPluginGtkPluginInfo))
    -#define GPLUGIN_GTK_PLUGIN_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GPLUGIN_GTK_TYPE_PLUGIN_INFO, GPluginGtkPluginInfoClass))
    -#define GPLUGIN_GTK_IS_PLUGIN_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GPLUGIN_GTK_TYPE_PLUGIN_INFO))
    -#define GPLUGIN_GTK_IS_PLUGIN_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GPLUGIN_GTK_TYPE_PLUGIN_INFO))
    -#define GPLUING_GTK_PLUGIN_INFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GPLUGIN_GTK_TYPE_PLUGIN_INFO, GPluginGtkPluginInfoClass))
    -
    -typedef struct _GPluginGtkPluginInfo GPluginGtkPluginInfo;
    -typedef struct _GPluginGtkPluginInfoClass GPluginGtkPluginInfoClass;
    -
    #include <glib.h>
    #include <glib-object.h>
    @@ -39,21 +29,10 @@
    #include <gplugin/gplugin.h>
    -struct _GPluginGtkPluginInfo {
    - GtkFrame parent;
    -
    - gpointer reserved[4];
    -};
    -
    -struct _GPluginGtkPluginInfoClass {
    - GtkFrameClass parent;
    -
    - gpointer reserved[4];
    -};
    -
    G_BEGIN_DECLS
    -GType gplugin_gtk_plugin_info_get_type(void);
    +#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)
    GtkWidget *gplugin_gtk_plugin_info_new(void);
    --- a/gplugin-gtk/gplugin-gtk-store.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin-gtk/gplugin-gtk-store.c Mon Sep 30 01:28:39 2019 -0500
    @@ -27,6 +27,31 @@
    * #GPluginGtkStore is a GtkTreeModel populated with gplugins.
    */
    +/**
    + * GPLUGIN_GTK_TYPE_STORE:
    + *
    + * The standard _get_type macro for #GPluginGtkStore.
    + */
    +
    +/**
    + * GPluginGtkStoreColumns:
    + * @GPLUGIN_GTK_STORE_LOADED_COLUMN: The loaded column.
    + * @GPLUGIN_GTK_STORE_PLUGIN_COLUMN: The plugin column.
    + * @GPLUGIN_GTK_STORE_MARKUP_COLUMN: The markup column.
    + *
    + * An enum declaring the columns in a #GPluginGtkStore.
    + */
    +
    +/**
    + * GPluginGtkStore:
    + *
    + * A #GtkListStore that contains all of the known plugins in GPlugin.
    + */
    +
    +struct _GPluginGtkStore {
    + GtkListStore parent;
    +};
    +
    G_DEFINE_TYPE(GPluginGtkStore, gplugin_gtk_store, GTK_TYPE_LIST_STORE);
    /******************************************************************************
    --- a/gplugin-gtk/gplugin-gtk-store.h Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin-gtk/gplugin-gtk-store.h Mon Sep 30 01:28:39 2019 -0500
    @@ -22,45 +22,25 @@
    #ifndef GPLUGIN_GTK_STORE_H
    #define GPLUGIN_GTK_STORE_H
    -#define GPLUGIN_GTK_TYPE_STORE (gplugin_gtk_store_get_type())
    -#define GPLUGIN_GTK_STORE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GPLUGIN_GTK_TYPE_STORE, GPluginGtkStore))
    -#define GPLUGIN_GTK_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GPLUGIN_GTK_TYPE_STORE, GPluginGtkStoreClass))
    -#define GPLUGIN_GTK_IS_STORE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GPLUGIN_GTK_TYPE_STORE))
    -#define GPLUGIN_GTK_IS_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GPLUGIN_GTK_TYPE_STORE))
    -#define GPLUING_GTK_STORE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GPLUGIN_GTK_TYPE_STORE, GPluginGtkStoreClass))
    -
    -typedef struct _GPluginGtkStore GPluginGtkStore;
    -typedef struct _GPluginGtkStoreClass GPluginGtkStoreClass;
    -
    #include <glib.h>
    #include <glib-object.h>
    #include <gtk/gtk.h>
    -struct _GPluginGtkStore {
    - GtkListStore parent;
    -
    - gpointer reserved[4];
    -};
    +G_BEGIN_DECLS
    -struct _GPluginGtkStoreClass {
    - GtkListStoreClass parent;
    -
    - gpointer reserved[4];
    -};
    +#define GPLUGIN_GTK_TYPE_STORE (gplugin_gtk_store_get_type())
    +G_DECLARE_FINAL_TYPE(GPluginGtkStore, gplugin_gtk_store, GPLUGIN_GTK, STORE, GtkListStore)
    typedef enum {
    GPLUGIN_GTK_STORE_LOADED_COLUMN,
    GPLUGIN_GTK_STORE_PLUGIN_COLUMN,
    GPLUGIN_GTK_STORE_MARKUP_COLUMN,
    +
    + /*< private >*/
    GPLUGIN_GTK_STORE_N_COLUMNS,
    } GPluginGtkStoreColumns;
    -
    -G_BEGIN_DECLS
    -
    -GType gplugin_gtk_store_get_type(void);
    -
    GPluginGtkStore *gplugin_gtk_store_new(void);
    const GType *gplugin_gtk_get_store_column_types(void);
    --- a/gplugin-gtk/gplugin-gtk-view.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin-gtk/gplugin-gtk-view.c Mon Sep 30 01:28:39 2019 -0500
    @@ -26,12 +26,27 @@
    * #GPluginGtkView is a display widget for a list of GPlugins.
    */
    +/**
    + * GPLUGIN_GTK_TYPE_VIEW:
    + *
    + * The standard _get_type macro for #GPluginGtkView.
    + */
    +
    +/**
    + * GPluginGtkView:
    + *
    + * A #GtkTreeView widget that displays all the plugins and some basic
    + * information about them.
    + */
    +
    /******************************************************************************
    * Structs
    *****************************************************************************/
    -typedef struct {
    +struct _GPluginGtkView {
    + GtkTreeView parent;
    +
    gboolean show_internal;
    -} GPluginGtkViewPrivate;
    +};
    /******************************************************************************
    * Enums
    @@ -46,7 +61,7 @@
    /******************************************************************************
    * GObject Stuff
    *****************************************************************************/
    -G_DEFINE_TYPE_WITH_PRIVATE(GPluginGtkView, gplugin_gtk_view, GTK_TYPE_TREE_VIEW);
    +G_DEFINE_TYPE(GPluginGtkView, gplugin_gtk_view, GTK_TYPE_TREE_VIEW);
    static void
    gplugin_gtk_view_set_property(GObject *obj, guint prop_id, const GValue *value,
    @@ -187,13 +202,9 @@
    gplugin_gtk_view_set_show_internal(GPluginGtkView *view,
    gboolean show_internal)
    {
    - GPluginGtkViewPrivate *priv = NULL;
    -
    g_return_if_fail(GPLUGIN_GTK_IS_VIEW(view));
    - priv = gplugin_gtk_view_get_instance_private(view);
    -
    - priv->show_internal = show_internal;
    + view->show_internal = show_internal;
    g_object_notify(G_OBJECT(view), "show-internal");
    }
    @@ -206,12 +217,8 @@
    */
    gboolean
    gplugin_gtk_view_get_show_internal(GPluginGtkView *view) {
    - GPluginGtkViewPrivate *priv = NULL;
    -
    g_return_val_if_fail(GPLUGIN_GTK_IS_VIEW(view), FALSE);
    - priv = gplugin_gtk_view_get_instance_private(view);
    -
    - return priv->show_internal;
    + return view->show_internal;
    }
    --- a/gplugin-gtk/gplugin-gtk-view.h Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin-gtk/gplugin-gtk-view.h Mon Sep 30 01:28:39 2019 -0500
    @@ -22,36 +22,15 @@
    #ifndef GPLUGIN_GTK_VIEW_H
    #define GPLUGIN_GTK_VIEW_H
    -#define GPLUGIN_GTK_TYPE_VIEW (gplugin_gtk_view_get_type())
    -#define GPLUGIN_GTK_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GPLUGIN_GTK_TYPE_VIEW, GPluginGtkView))
    -#define GPLUGIN_GTK_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GPLUGIN_GTK_TYPE_VIEW, GPluginGtkViewClass))
    -#define GPLUGIN_GTK_IS_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GPLUGIN_GTK_TYPE_VIEW))
    -#define GPLUGIN_GTK_IS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GPLUGIN_GTK_TYPE_VIEW))
    -#define GPLUING_GTK_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GPLUGIN_GTK_TYPE_VIEW, GPluginGtkViewClass))
    -
    -typedef struct _GPluginGtkView GPluginGtkView;
    -typedef struct _GPluginGtkViewClass GPluginGtkViewClass;
    -
    #include <glib.h>
    #include <glib-object.h>
    #include <gtk/gtk.h>
    -struct _GPluginGtkView {
    - GtkTreeView parent;
    -
    - gpointer reserved[4];
    -};
    -
    -struct _GPluginGtkViewClass {
    - GtkTreeViewClass parent;
    -
    - gpointer reserved[4];
    -};
    -
    G_BEGIN_DECLS
    -GType gplugin_gtk_view_get_type(void);
    +#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);
    --- a/gplugin-gtk/meson.build Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin-gtk/meson.build Mon Sep 30 01:28:39 2019 -0500
    @@ -122,6 +122,7 @@
    symbol_prefix : 'gplugin_gtk',
    nsversion : '@0@.0'.format(GPLUGIN_MAJOR_VERSION),
    install : true,
    + export_packages: ['gplugin-gtk'],
    extra_args : ['--quiet', '-DGPLUGIN_GTK_COMPILATION'])
    endif
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk/reference/Dockerfile Mon Sep 30 01:28:39 2019 -0500
    @@ -0,0 +1,6 @@
    +FROM rwgrim/goserve
    +
    +EXPOSE 3000
    +
    +COPY html html
    +
    --- a/gplugin-gtk/reference/meson.build Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin-gtk/reference/meson.build Mon Sep 30 01:28:39 2019 -0500
    @@ -3,6 +3,7 @@
    # Header files or dirs to ignore when scanning. Use base file/dir names
    ignore_hfiles = [
    'gplugin-gtk.h',
    + 'gplugin-gtk-resources.h',
    ]
    ignore_hfiles += GPLUGIN_GTK_PRIVATE_HEADERS
    @@ -11,12 +12,10 @@
    '--deprecated-guards=GPLUGIN_GTK_DISABLE_DEPRECATED',
    '--rebuild-types',
    '--rebuild-sections',
    - '--ignore-headers=' + ' '.join(ignore_hfiles),
    ]
    -# Extra options to supply to gtkdoc-mkdb.
    -mkdb_args = [
    - '--ignore-files=' + ' '.join(ignore_hfiles),
    +fixxref_args = [
    + '--extra-dir', join_paths(meson.current_build_dir(), '../../gplugin/reference')
    ]
    gplugin_gtk_version_xml = configure_file(
    @@ -31,9 +30,10 @@
    main_xml : DOC_MODULE + '-docs.xml',
    src_dir : gplugin_gtk_inc,
    dependencies : gplugin_gtk_dep,
    + ignore_headers : ignore_hfiles,
    install : true,
    scan_args : scan_args,
    - mkdb_args : mkdb_args,
    gobject_typesfile : DOC_MODULE + '.types',
    content_files : content_files,
    + fixxref_args : fixxref_args,
    )
    --- a/gplugin.sublime-project Tue Jan 22 22:58:59 2019 -0600
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,8 +0,0 @@
    -{
    - "folders":
    - [
    - {
    - "path": "."
    - }
    - ]
    -}
    --- a/gplugin/gplugin-core.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/gplugin-core.c Mon Sep 30 01:28:39 2019 -0500
    @@ -64,10 +64,6 @@
    bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
    bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
    -#if !GLIB_CHECK_VERSION(2, 36, 0)
    - g_type_init();
    -#endif /* !GLIB_CHECK_VERSION(2, 36, 0) */
    -
    gplugin_manager_private_init();
    }
    --- a/gplugin/gplugin-enums.c.tmpl Tue Jan 22 22:58:59 2019 -0600
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,69 +0,0 @@
    -/*** BEGIN file-header ***/
    -/*
    - * vi:syntax=c
    - *
    - * Copyright (C) 2011-2013 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 program 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.
    - *
    - * You should have received a copy of the GNU General Public License
    - * along with this program. If not, see <http://www.gnu.org/licenses/>.
    - */
    -
    -#include <gplugin/gplugin-enums.h>
    -
    -/*** END file-header ***/
    -
    -/**
    - * SECTION:gplugin-enums
    - * @Title: Enumerations
    - * @Short_description: common enumerations
    - *
    - * The enums defined here are used throughout %GPlugin.
    - */
    -
    -/*** BEGIN file-production ***/
    -
    -/* enumerations from "@filename@" */
    -#include "gplugin/@basename@"
    -
    -/*** END file-production ***/
    -
    -/*** BEGIN value-header ***/
    -GType
    -@enum_name@_get_type(void) {
    - static volatile gsize g_define_type_id__volatile = 0;
    -
    - if(g_once_init_enter(&g_define_type_id__volatile)) {
    - static const G@Type@Value values [] = {
    -/*** END value-header ***/
    -
    -/*** BEGIN value-production ***/
    - { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
    -/*** END value-production ***/
    -
    -/*** BEGIN value-tail ***/
    - { 0, NULL, NULL }
    - };
    -
    - GType g_define_type_id =
    - g_@type@_register_static(g_intern_static_string("@EnumName@"), values);
    - g_once_init_leave(&g_define_type_id__volatile, g_define_type_id);
    - }
    -
    - return g_define_type_id__volatile;
    -}
    -
    -/*** END value-tail ***/
    -
    -/*** BEGIN file-tail ***/
    -/*** END file-tail ***/
    -
    --- a/gplugin/gplugin-enums.h.tmpl Tue Jan 22 22:58:59 2019 -0600
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,44 +0,0 @@
    -/*** BEGIN file-header ***/
    -/*
    - * vi:syntax=c
    - *
    - * Copyright (C) 2011-2013 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 program 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.
    - *
    - * You should have received a copy of the GNU General Public License
    - * along with this program. If not, see <http://www.gnu.org/licenses/>.
    - */
    -#ifndef GPLUGIN_ENUM_H
    -#define GPLUGIN_ENUM_H
    -
    -#include <glib-object.h>
    -
    -G_BEGIN_DECLS
    -/*** END file-header ***/
    -
    -/*** BEGIN file-production ***/
    -
    -/* enumerations from "@basename@" */
    -/*** END file-production ***/
    -
    -/*** BEGIN value-header ***/
    -GType @enum_name@_get_type(void) G_GNUC_CONST;
    -#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type())
    -/*** END value-header ***/
    -
    -/*** BEGIN file-tail ***/
    -
    -G_END_DECLS
    -
    -#endif /* GPLUGIN_ENUM_H */
    -/*** END file-tail ***/
    -
    --- a/gplugin/gplugin-file-tree.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/gplugin-file-tree.c Mon Sep 30 01:28:39 2019 -0500
    @@ -60,17 +60,11 @@
    * Helpers
    *****************************************************************************/
    static gboolean
    -gplugin_file_tree_free_leaves(GNode *n, GPLUGIN_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);
    -
    - return FALSE;
    -}
    -
    -static gboolean
    -gplugin_file_tree_free_non_leaves(GNode *n, GPLUGIN_UNUSED gpointer d) {
    - g_free(n->data);
    + if (e)
    + gplugin_file_tree_entry_free(e);
    return FALSE;
    }
    @@ -97,6 +91,7 @@
    GDir *dir = NULL;
    GError *error = NULL;
    GNode *node_dir = NULL;
    + GPluginFileTreeEntry *entry = NULL;
    const gchar *path = (const gchar *)iter->data;
    const gchar *filename = NULL;
    @@ -113,13 +108,13 @@
    }
    /* we have a usable directory, so prepend it into the tree */
    - node_dir = g_node_new(g_strdup(path));
    + entry = gplugin_file_tree_entry_new(path);
    + node_dir = g_node_new(entry);
    g_node_prepend(root, node_dir);
    /* now run through all of the files and add then to the dir node */
    while((filename = g_dir_read_name(dir)) != NULL) {
    GNode *file = NULL;
    - GPluginFileTreeEntry *entry = NULL;
    entry = gplugin_file_tree_entry_new(filename);
    file = g_node_new(entry);
    @@ -144,12 +139,9 @@
    gplugin_file_tree_free(GNode *root) {
    g_return_if_fail(root);
    - if(root->data) {
    - g_node_traverse(root, G_POST_ORDER, G_TRAVERSE_LEAVES, -1,
    - gplugin_file_tree_free_leaves, NULL);
    - g_node_traverse(root, G_POST_ORDER, G_TRAVERSE_NON_LEAVES, -1,
    - gplugin_file_tree_free_non_leaves, NULL);
    - }
    + g_node_traverse(root, G_POST_ORDER,
    + G_TRAVERSE_LEAVES | G_TRAVERSE_NON_LEAVES,
    + -1, gplugin_file_tree_free_helper, NULL);
    g_node_destroy(root);
    }
    --- a/gplugin/gplugin-loader-tests.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/gplugin-loader-tests.c Mon Sep 30 01:28:39 2019 -0500
    @@ -46,10 +46,10 @@
    id = g_strdup_printf("gplugin/%s-basic-plugin", (const gchar *)d);
    plugin = gplugin_manager_find_plugin(id);
    - g_assert(plugin != NULL);
    + g_assert_nonnull(plugin);
    info = gplugin_plugin_get_info(plugin);
    - g_assert(info != NULL);
    + g_assert_nonnull(info);
    g_assert_cmpstr(gplugin_plugin_info_get_id(info), ==, id);
    g_free(id);
    @@ -98,10 +98,10 @@
    id = g_strdup_printf("gplugin/%s-load-failed", (const gchar *)d);
    plugin = gplugin_manager_find_plugin(id);
    g_free(id);
    - g_assert(plugin != NULL);
    + g_assert_nonnull(plugin);
    ret = gplugin_manager_load_plugin(plugin, &error);
    - g_assert(ret == FALSE);
    + g_assert_false(ret);
    g_assert_error(error, GPLUGIN_DOMAIN, 0);
    g_assert_cmpint(gplugin_plugin_get_state(plugin), ==,
    GPLUGIN_PLUGIN_STATE_LOAD_FAILED);
    @@ -119,10 +119,10 @@
    id = g_strdup_printf("gplugin/%s-load-exception", (const gchar *)d);
    plugin = gplugin_manager_find_plugin(id);
    g_free(id);
    - g_assert(plugin != NULL);
    + g_assert_nonnull(plugin);
    ret = gplugin_manager_load_plugin(plugin, &error);
    - g_assert(ret == FALSE);
    + g_assert_false(ret);
    g_assert_error(error, GPLUGIN_DOMAIN, 0);
    g_assert_cmpint(gplugin_plugin_get_state(plugin), ==,
    GPLUGIN_PLUGIN_STATE_LOAD_FAILED);
    @@ -140,16 +140,16 @@
    id = g_strdup_printf("gplugin/%s-unload-failed", (const gchar *)d);
    plugin = gplugin_manager_find_plugin(id);
    g_free(id);
    - g_assert(plugin != NULL);
    + g_assert_nonnull(plugin);
    ret = gplugin_manager_load_plugin(plugin, &error);
    - g_assert(ret != FALSE);
    + g_assert_true(ret);
    g_assert_no_error(error);
    g_assert_cmpint(gplugin_plugin_get_state(plugin), ==,
    GPLUGIN_PLUGIN_STATE_LOADED);
    ret = gplugin_manager_unload_plugin(plugin, &error);
    - g_assert(ret != TRUE);
    + g_assert_false(ret);
    g_assert_error(error, GPLUGIN_DOMAIN, 0);
    g_assert_cmpint(gplugin_plugin_get_state(plugin), ==,
    GPLUGIN_PLUGIN_STATE_LOADED);
    @@ -169,10 +169,10 @@
    id = g_strdup_printf("gplugin/%s-dependent-plugin", (const gchar *)d);
    plugin = gplugin_manager_find_plugin(id);
    g_free(id);
    - g_assert(plugin != NULL);
    + g_assert_nonnull(plugin);
    info = gplugin_plugin_get_info(plugin);
    - g_assert(info != NULL);
    + g_assert_nonnull(info);
    deps = (gchar **)gplugin_plugin_info_get_dependencies(info);
    for(i = 0; r_deps[i]; i++)
    --- a/gplugin/gplugin-loader.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/gplugin-loader.c Mon Sep 30 01:28:39 2019 -0500
    @@ -20,6 +20,12 @@
    #include <gplugin/gplugin-core.h>
    /**
    + * GPLUGIN_TYPE_LOADER:
    + *
    + * The standard _get_type macro for #GPluginLoader.
    + */
    +
    +/**
    * SECTION:gplugin-loader
    * @Title: Plugin Loader Interface
    * @Short_description: interface for loading plugins
    @@ -28,17 +34,38 @@
    * be able to use it to load plugins.
    */
    +/**
    + * GPluginLoader:
    + *
    + * An abstract data type that should not be accessed directly.
    + */
    +
    +/**
    + * GPluginLoaderClass:
    + * @supported_extensions: The supported_extensions vfunc returns a #GList of
    + * file extensions that this loader supports without the
    + * leading dot. For example: 'so', 'dll', 'py', etc.
    + * @query: The query vfunc is called when the plugin manager needs to query a
    + * plugin that has a file extension from @supported_extensions.
    + * @load: The load vfunc is called when the plugin manager wants to load a
    + * plugin that was previously queried by this loader.
    + * @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.
    + */
    +
    /******************************************************************************
    * GObject Stuff
    *****************************************************************************/
    G_DEFINE_ABSTRACT_TYPE(GPluginLoader, gplugin_loader, G_TYPE_OBJECT);
    static void
    -gplugin_loader_init(GPluginLoader *loader) {
    +gplugin_loader_init(G_GNUC_UNUSED GPluginLoader *loader) {
    }
    static void
    -gplugin_loader_class_init(GPluginLoaderClass *klass) {
    +gplugin_loader_class_init(G_GNUC_UNUSED GPluginLoaderClass *klass) {
    }
    /******************************************************************************
    @@ -96,16 +123,15 @@
    g_return_val_if_fail(loader != NULL, FALSE);
    g_return_val_if_fail(GPLUGIN_IS_LOADER(loader), FALSE);
    g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), FALSE);
    - g_return_val_if_fail(error != NULL, FALSE);
    klass = GPLUGIN_LOADER_GET_CLASS(loader);
    if(klass && klass->load)
    ret = klass->load(loader, plugin, error);
    - if(!ret && error && *error == NULL) {
    - *error = g_error_new(GPLUGIN_DOMAIN, 0,
    - "Failed to load plugin : unknown");
    + if (!ret && error && *error == NULL) {
    + g_set_error(error, GPLUGIN_DOMAIN, 0,
    + "Failed to load plugin : unknown");
    }
    return ret;
    @@ -138,9 +164,9 @@
    if(klass && klass->unload)
    ret = klass->unload(loader, plugin, error);
    - if(!ret && error && *error == NULL) {
    - *error = g_error_new(GPLUGIN_DOMAIN, 0,
    - "Failed to unload plugin : unknown");
    + if (!ret && error && *error == NULL) {
    + g_set_error(error, GPLUGIN_DOMAIN, 0,
    + "Failed to unload plugin : unknown");
    }
    return ret;
    @@ -156,7 +182,7 @@
    * extensions that the loader supports.
    */
    GSList *
    -gplugin_loader_class_get_supported_extensions(const GPluginLoaderClass *klass) {
    +gplugin_loader_class_get_supported_extensions(GPluginLoaderClass *klass) {
    g_return_val_if_fail(GPLUGIN_IS_LOADER_CLASS(klass), NULL);
    if(klass->supported_extensions)
    --- a/gplugin/gplugin-loader.h Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/gplugin-loader.h Mon Sep 30 01:28:39 2019 -0500
    @@ -22,45 +22,34 @@
    #ifndef GPLUGIN_LOADER_H
    #define GPLUGIN_LOADER_H
    -#define GPLUGIN_TYPE_LOADER (gplugin_loader_get_type())
    -#define GPLUGIN_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GPLUGIN_TYPE_LOADER, GPluginLoader))
    -#define GPLUGIN_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GPLUGIN_TYPE_LOADER, GPluginLoaderClass))
    -#define GPLUGIN_IS_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GPLUGIN_TYPE_LOADER))
    -#define GPLUGIN_IS_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GPLUGIN_TYPE_LOADER))
    -#define GPLUGIN_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GPLUGIN_TYPE_LOADER, GPluginLoaderClass))
    -
    -typedef struct _GPluginLoader GPluginLoader;
    -typedef struct _GPluginLoaderClass GPluginLoaderClass;
    -
    #include <glib.h>
    #include <glib-object.h>
    +G_BEGIN_DECLS
    +
    +#define GPLUGIN_TYPE_LOADER (gplugin_loader_get_type())
    +G_DECLARE_DERIVABLE_TYPE(GPluginLoader, gplugin_loader, GPLUGIN, LOADER, GObject)
    +
    +/* circular include so this needs to be after the G_DECLARE_* marcro */
    #include <gplugin/gplugin-plugin.h>
    -struct _GPluginLoader {
    - GObject gparent;
    -
    - gpointer reserved[4];
    -};
    -
    struct _GPluginLoaderClass {
    + /*< private >*/
    GObjectClass gparent;
    - GSList *(*supported_extensions)(const GPluginLoaderClass *klass);
    + /*< public >*/
    + GSList *(*supported_extensions)(GPluginLoaderClass *klass);
    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);
    + /*< private >*/
    gpointer reserved[4];
    };
    -G_BEGIN_DECLS
    -
    -GType gplugin_loader_get_type(void);
    -
    -GSList *gplugin_loader_class_get_supported_extensions(const GPluginLoaderClass *klass);
    +GSList *gplugin_loader_class_get_supported_extensions(GPluginLoaderClass *klass);
    GPluginPlugin *gplugin_loader_query_plugin(GPluginLoader *loader, const gchar *filename, GError **error);
    --- a/gplugin/gplugin-manager.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/gplugin-manager.c Mon Sep 30 01:28:39 2019 -0500
    @@ -23,7 +23,6 @@
    #include <gplugin/gplugin-manager.h>
    #include <gplugin/gplugin-core.h>
    -#include <gplugin/gplugin-marshallers.h>
    #include <gplugin/gplugin-private.h>
    @@ -141,9 +140,9 @@
    }
    static gboolean
    -gplugin_manager_remove_list_value(GPLUGIN_UNUSED gpointer k,
    +gplugin_manager_remove_list_value(G_GNUC_UNUSED gpointer k,
    gpointer v,
    - GPLUGIN_UNUSED gpointer d)
    + G_GNUC_UNUSED gpointer d)
    {
    GSList *l = NULL;
    @@ -360,13 +359,13 @@
    manager->refresh_needed = FALSE;
    for(dir = root->children; dir; dir = dir->next) {
    + GPluginFileTreeEntry *e = dir->data;
    GNode *file = NULL;
    - const gchar *path = (const gchar *)dir->data;
    + const gchar *path = e->filename;
    for(file = dir->children; file; file = file->next) {
    GPluginPlugin *plugin = NULL;
    GPluginLoader *loader = NULL;
    - GPluginFileTreeEntry *e = NULL;
    GError *error = NULL;
    GSList *l = NULL;
    gchar *filename = NULL;
    @@ -436,7 +435,7 @@
    /* if the plugin instance is good, then break out of this
    * loop.
    */
    - if(plugin != NULL && GPLUGIN_IS_PLUGIN(plugin)) {
    + if(GPLUGIN_IS_PLUGIN(plugin)) {
    break;
    }
    @@ -449,7 +448,7 @@
    * don't need to do anything but free the filename which we'll
    * do later.
    */
    - if(plugin != NULL && GPLUGIN_IS_PLUGIN(plugin)) {
    + if(GPLUGIN_IS_PLUGIN(plugin)) {
    /* we have a good plugin, huzzah! We need to add it to our
    * "view" as well as the main plugin hash table.
    */
    @@ -477,20 +476,22 @@
    }
    /* now insert into our view */
    - g_hash_table_insert(manager->plugins_filename_view,
    - real_filename,
    - g_object_ref(G_OBJECT(plugin)));
    + g_hash_table_replace(manager->plugins_filename_view,
    + real_filename,
    + 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);
    + l = g_hash_table_lookup(manager->plugins, id); //-V1004
    for(ll = l; ll; ll = ll->next) {
    GPluginPlugin *splugin = GPLUGIN_PLUGIN(ll->data);
    - const gchar *sfilename = gplugin_plugin_get_filename(splugin);
    + gchar *sfilename = gplugin_plugin_get_filename(splugin);
    if(!g_strcmp0(real_filename, sfilename))
    seen = TRUE;
    +
    + g_free(sfilename);
    }
    if(!seen) {
    l = g_slist_prepend(l, g_object_ref(plugin));
    @@ -639,8 +640,12 @@
    /* now look for a plugin matching the id */
    matches = gplugin_manager_find_plugins(oid);
    - if(matches == NULL)
    + if(matches == NULL) {
    + g_free(oid);
    + g_free(oop);
    + g_free(over);
    continue;
    + }
    /* now iterate the matches and check if we need to check their
    * version.
    @@ -699,6 +704,10 @@
    }
    }
    + g_free(oid);
    + g_free(oop);
    + g_free(over);
    +
    if(found)
    break;
    }
    @@ -717,7 +726,7 @@
    }
    static GSList *
    -gplugin_manager_real_get_plugin_dependencies(GPluginManager *manager,
    +gplugin_manager_real_get_plugin_dependencies(G_GNUC_UNUSED GPluginManager *manager,
    GPluginPlugin *plugin,
    GError **error)
    {
    @@ -775,11 +784,9 @@
    /* now try to get the plugin info from the plugin */
    info = gplugin_plugin_get_info(plugin);
    if(info == NULL) {
    - if(error) {
    - *error = g_error_new(GPLUGIN_DOMAIN, 0,
    - _("Plugin %s did not return value plugin info"),
    - gplugin_plugin_get_filename(plugin));
    - }
    + g_set_error(error, GPLUGIN_DOMAIN, 0,
    + _("Plugin %s did not return value plugin info"),
    + gplugin_plugin_get_filename(plugin));
    gplugin_plugin_set_state(plugin, GPLUGIN_PLUGIN_STATE_LOAD_FAILED);
    @@ -798,12 +805,10 @@
    loader = gplugin_plugin_get_loader(plugin);
    if(!GPLUGIN_IS_LOADER(loader)) {
    - if(error) {
    - *error = g_error_new(GPLUGIN_DOMAIN, 0,
    - _("The loader for %s is not a loader. This "
    - "should not happened!"),
    - gplugin_plugin_get_filename(plugin));
    - }
    + g_set_error(error, GPLUGIN_DOMAIN, 0,
    + _("The loader for %s is not a loader. This "
    + "should not happened!"),
    + gplugin_plugin_get_filename(plugin));
    gplugin_plugin_set_state(plugin, GPLUGIN_PLUGIN_STATE_LOAD_FAILED);
    @@ -844,10 +849,8 @@
    loader = gplugin_plugin_get_loader(plugin);
    if(!GPLUGIN_IS_LOADER(loader)) {
    - if(error) {
    - *error = g_error_new(GPLUGIN_DOMAIN, 0,
    - _("Plugin loader is not a loader"));
    - }
    + g_set_error_literal(error, GPLUGIN_DOMAIN, 0,
    + _("Plugin loader is not a loader"));
    return FALSE;
    }
    @@ -867,17 +870,17 @@
    }
    static gboolean
    -gplugin_manager_loading_cb(GPLUGIN_UNUSED GObject *manager,
    - GPLUGIN_UNUSED GPluginPlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_manager_loading_cb(G_GNUC_UNUSED GObject *manager,
    + G_GNUC_UNUSED GPluginPlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    static gboolean
    -gplugin_manager_unloading_cb(GPLUGIN_UNUSED GObject *manager,
    - GPLUGIN_UNUSED GPluginPlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_manager_unloading_cb(G_GNUC_UNUSED GObject *manager,
    + G_GNUC_UNUSED GPluginPlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    @@ -890,21 +893,22 @@
    GPluginManager *manager = GPLUGIN_MANAGER(obj);
    g_queue_free_full(manager->paths, g_free);
    + manager->paths = NULL;
    /* free all the data in the plugins hash table and destroy it */
    g_hash_table_foreach_remove(manager->plugins,
    gplugin_manager_remove_list_value,
    NULL);
    - g_hash_table_destroy(manager->plugins);
    + g_clear_pointer(&manager->plugins, g_hash_table_destroy);
    /* destroy the filename view */
    - g_hash_table_destroy(manager->plugins_filename_view);
    + g_clear_pointer(&manager->plugins_filename_view, g_hash_table_destroy);
    /* free all the data in the loaders hash table and destroy it */
    g_hash_table_foreach_remove(manager->loaders,
    gplugin_manager_remove_list_value,
    NULL);
    - g_hash_table_destroy(manager->loaders);
    + g_clear_pointer(&manager->loaders, g_hash_table_destroy);
    /* call the base class's destructor */
    G_OBJECT_CLASS(gplugin_manager_parent_class)->finalize(obj);
    @@ -961,7 +965,7 @@
    G_STRUCT_OFFSET(GPluginManagerClass,
    loading_plugin),
    gplugin_boolean_accumulator, NULL,
    - gplugin_marshal_BOOLEAN__OBJECT_POINTER,
    + NULL,
    G_TYPE_BOOLEAN,
    2,
    G_TYPE_OBJECT, G_TYPE_POINTER);
    @@ -981,7 +985,7 @@
    G_STRUCT_OFFSET(GPluginManagerClass,
    loaded_plugin),
    NULL, NULL,
    - gplugin_marshal_VOID__OBJECT,
    + NULL,
    G_TYPE_NONE,
    1,
    G_TYPE_OBJECT);
    @@ -1000,7 +1004,7 @@
    G_STRUCT_OFFSET(GPluginManagerClass, load_failed),
    NULL,
    NULL,
    - gplugin_marshal_VOID__OBJECT,
    + NULL,
    G_TYPE_NONE,
    1,
    G_TYPE_OBJECT);
    @@ -1021,7 +1025,7 @@
    G_STRUCT_OFFSET(GPluginManagerClass,
    unloading_plugin),
    gplugin_boolean_accumulator, NULL,
    - gplugin_marshal_BOOLEAN__OBJECT_POINTER,
    + NULL,
    G_TYPE_BOOLEAN,
    2,
    G_TYPE_OBJECT, G_TYPE_POINTER);
    @@ -1041,7 +1045,7 @@
    G_STRUCT_OFFSET(GPluginManagerClass,
    unloaded_plugin),
    NULL, NULL,
    - gplugin_marshal_VOID__OBJECT,
    + NULL,
    G_TYPE_NONE,
    1,
    G_TYPE_OBJECT);
    @@ -1061,7 +1065,7 @@
    * a value of the plugin itself.
    */
    manager->plugins_filename_view =
    - g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_object_unref);
    + 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
    @@ -1233,8 +1237,7 @@
    * Gets the list of paths which will be search for plugins.
    *
    * Return value: (element-type utf8) (transfer none): list of paths which will
    - * be searched for plugins. free the list with g_list_free when
    - * done.
    + * be searched for plugins.
    */
    GList *
    gplugin_manager_get_paths(void) {
    --- a/gplugin/gplugin-marshallers.list Tue Jan 22 22:58:59 2019 -0600
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,4 +0,0 @@
    -BOOLEAN:OBJECT,POINTER
    -VOID:ENUM,ENUM
    -VOID:INT,INT
    -VOID:OBJECT
    --- a/gplugin/gplugin-native-loader.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/gplugin-native-loader.c Mon Sep 30 01:28:39 2019 -0500
    @@ -39,12 +39,28 @@
    */
    /**
    + * GPLUGIN_TYPE_NATIVE_LOADER:
    + *
    + * The standard _get_type macro for #GPluginNativeLoader.
    + */
    +
    +/**
    + * GPluginNativeLoader:
    + *
    + * A #GPluginLoader subclass that is able to load native plugins.
    + */
    +
    +/**
    * GPLUGIN_NATIVE_PLUGIN_ABI_VERSION:
    *
    * The ABI version of the #GPluginNativeLoader. Your plugin should use this
    * as the value for #abi_version when call #gplugin_plugin_info_new.
    */
    +struct _GPluginNativeLoader {
    + GPluginLoader parent;
    +};
    +
    G_DEFINE_TYPE(GPluginNativeLoader, gplugin_native_loader, GPLUGIN_TYPE_LOADER);
    /******************************************************************************
    @@ -59,11 +75,8 @@
    g_return_val_if_fail(module != NULL, NULL);
    if(!g_module_symbol(module, name, &symbol)) {
    - if(error) {
    - *error = g_error_new(GPLUGIN_DOMAIN, 0,
    - _("symbol %s was not found"), name);
    -
    - }
    + g_set_error(error, GPLUGIN_DOMAIN, 0,
    + _("symbol %s was not found"), name);
    return NULL;
    }
    @@ -96,8 +109,18 @@
    * GPluginLoaderInterface API
    *****************************************************************************/
    static GSList *
    -gplugin_native_loader_class_supported_extensions(GPLUGIN_UNUSED const GPluginLoaderClass *klass) {
    - return g_slist_append(NULL, G_MODULE_SUFFIX);
    +gplugin_native_loader_class_supported_extensions(G_GNUC_UNUSED GPluginLoaderClass *klass) {
    + 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.
    + * See: https://gitlab.gnome.org/GNOME/glib/issues/1413
    + */
    + exts = g_slist_append(exts, "dylib");
    +#endif
    +
    + return exts;
    }
    static GPluginPluginInfo *
    @@ -110,21 +133,27 @@
    GPluginPluginInfo *info = NULL;
    *module = gplugin_native_loader_open(filename, flags, error);
    - if((*module == NULL) || (error && *error))
    + if (*module == NULL) {
    return NULL;
    + } else if (error && *error) {
    + g_module_close(*module);
    + *module = NULL;
    + return NULL;
    + }
    *query = gplugin_native_loader_lookup_symbol(*module, GPLUGIN_QUERY_SYMBOL,
    error);
    if((*query == NULL) || (error && *error)) {
    g_module_close(*module);
    + *module = NULL;
    return NULL;
    }
    info = ((GPluginNativePluginQueryFunc)(*query))(error);
    if(error && *error) {
    g_module_close(*module);
    -
    + *module = NULL;
    return NULL;
    }
    @@ -146,13 +175,10 @@
    info = gplugin_native_loader_open_and_query(filename, &module, 0, &query,
    error);
    if(!GPLUGIN_IS_PLUGIN_INFO(info)) {
    - if(module)
    - g_module_close(module);
    -
    - if(error && !*error) {
    - *error = g_error_new(GPLUGIN_DOMAIN, 0,
    - _("the query function did not return a "
    - "GPluginPluginInfo instance"));
    + if (error && *error == NULL) {
    + g_set_error_literal(error, GPLUGIN_DOMAIN, 0,
    + _("the query function did not return a "
    + "GPluginPluginInfo instance"));
    }
    return NULL;
    @@ -166,12 +192,10 @@
    G_MODULE_BIND_LOCAL,
    &query, error);
    if(!GPLUGIN_IS_PLUGIN_INFO(info)) {
    - g_module_close(module);
    -
    - if(error && !*error) {
    - *error = g_error_new(GPLUGIN_DOMAIN, 0,
    - _("the query function did not return a "
    - "GPluginPluginInfo instance"));
    + if (error && *error == NULL) {
    + g_set_error_literal(error, GPLUGIN_DOMAIN, 0,
    + _("the query function did not return a "
    + "GPluginPluginInfo instance"));
    }
    return NULL;
    @@ -215,10 +239,8 @@
    g_object_unref(G_OBJECT(info));
    if(!GPLUGIN_IS_NATIVE_PLUGIN(plugin)) {
    - if(error) {
    - *error = g_error_new(GPLUGIN_DOMAIN, 0,
    - _("failed to create plugin instance"));
    - }
    + g_set_error_literal(error, GPLUGIN_DOMAIN, 0,
    + _("failed to create plugin instance"));
    return NULL;
    }
    @@ -226,7 +248,7 @@
    }
    static gboolean
    -gplugin_native_loader_load(GPLUGIN_UNUSED GPluginLoader *loader,
    +gplugin_native_loader_load(G_GNUC_UNUSED GPluginLoader *loader,
    GPluginPlugin *plugin,
    GError **error)
    {
    @@ -238,8 +260,8 @@
    /* 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)
    - *error = g_error_new(GPLUGIN_DOMAIN, 0, _("unknown failure"));
    + if (error && *error == NULL)
    + g_set_error_literal(error, GPLUGIN_DOMAIN, 0, _("unknown failure"));
    return FALSE;
    }
    @@ -248,7 +270,7 @@
    }
    static gboolean
    -gplugin_native_loader_unload(GPLUGIN_UNUSED GPluginLoader *loader,
    +gplugin_native_loader_unload(G_GNUC_UNUSED GPluginLoader *loader,
    GPluginPlugin *plugin,
    GError **error)
    {
    @@ -271,8 +293,8 @@
    /* now call the function */
    if(!func(GPLUGIN_NATIVE_PLUGIN(plugin), error)) {
    - if(error && *error)
    - *error = g_error_new(GPLUGIN_DOMAIN, 0, _("unknown failure"));
    + if (error && *error == NULL)
    + g_set_error_literal(error, GPLUGIN_DOMAIN, 0, _("unknown failure"));
    return FALSE;
    }
    @@ -281,7 +303,7 @@
    }
    static void
    -gplugin_native_loader_init(GPluginNativeLoader *loader) {
    +gplugin_native_loader_init(G_GNUC_UNUSED GPluginNativeLoader *loader) {
    }
    static void
    --- a/gplugin/gplugin-native-loader.h Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/gplugin-native-loader.h Mon Sep 30 01:28:39 2019 -0500
    @@ -22,16 +22,6 @@
    #ifndef GPLUGIN_NATIVE_LOADER_H
    #define GPLUGIN_NATIVE_LOADER_H
    -#define GPLUGIN_TYPE_NATIVE_LOADER (gplugin_native_loader_get_type())
    -#define GPLUGIN_NATIVE_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GPLUGIN_TYPE_NATIVE_LOADER, GPluginNativeLoader))
    -#define GPLUGIN_NATIVE_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((obj), GPLUGIN_TYPE_NATIVE_LOADER, GPluginNativeLoaderClass))
    -#define GPLUGIN_IS_NATIVE_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GPLUGIN_TYPE_NATIVE_LOADER))
    -#define GPLUGIN_IS_NATIVE_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((obj), GPLUGIN_TYPE_NATIVE_LOADER))
    -#define GPLUGIN_NATIVE_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GPLUGIN_TYPE_NATIVE_LOADER, GPluginNativeLoaderClass))
    -
    -typedef struct _GPluginNativeLoader GPluginNativeLoader;
    -typedef struct _GPluginNativeLoaderClass GPluginNativeLoaderClass;
    -
    #include <glib.h>
    #include <glib-object.h>
    @@ -39,21 +29,10 @@
    #define GPLUGIN_NATIVE_PLUGIN_ABI_VERSION 0x01000000
    -struct _GPluginNativeLoader {
    - GPluginLoader parent;
    -
    - gpointer reserved[4];
    -};
    -
    -struct _GPluginNativeLoaderClass {
    - GPluginLoaderClass parent;
    -
    - gpointer reserved[4];
    -};
    -
    G_BEGIN_DECLS
    -GType gplugin_native_loader_get_type(void);
    +#define GPLUGIN_TYPE_NATIVE_LOADER (gplugin_native_loader_get_type())
    +G_DECLARE_FINAL_TYPE(GPluginNativeLoader, gplugin_native_loader, GPLUGIN, NATIVE_LOADER, GPluginLoader)
    G_END_DECLS
    --- a/gplugin/gplugin-native-plugin.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/gplugin-native-plugin.c Mon Sep 30 01:28:39 2019 -0500
    @@ -35,10 +35,25 @@
    * language.
    */
    +/**
    + * GPLUGIN_TYPE_NATIVE_PLUGIN:
    + *
    + * The standard _get_type macro for #GPluginNativePlugin.
    + */
    +
    +/**
    + * GPluginNativePlugin:
    + *
    + * An instance of a loaded native plugin. A native plugin is a plugin that was
    + * compiled to machine native code, typically these are written in C/C++.
    + */
    +
    /******************************************************************************
    * Structs
    *****************************************************************************/
    -typedef struct {
    +struct _GPluginNativePlugin {
    + GTypeModule parent;
    +
    GModule *module;
    gpointer load_func;
    @@ -48,7 +63,7 @@
    GPluginLoader *loader;
    GPluginPluginInfo *info;
    GPluginPluginState state;
    -} GPluginNativePluginPrivate;
    +};
    /******************************************************************************
    * Enums
    @@ -71,7 +86,7 @@
    * GPluginPlugin Implementation
    *****************************************************************************/
    static void
    -gplugin_native_plugin_iface_init(GPluginPluginInterface *iface) {
    +gplugin_native_plugin_iface_init(G_GNUC_UNUSED GPluginPluginInterface *iface) {
    /* we just override properites from GPluginPlugin */
    }
    @@ -79,12 +94,12 @@
    * GTypeModule Implementation
    *****************************************************************************/
    static gboolean
    -gplugin_native_plugin_load(GTypeModule *module) {
    +gplugin_native_plugin_load(G_GNUC_UNUSED GTypeModule *module) {
    return TRUE;
    }
    static void
    -gplugin_native_plugin_unload(GTypeModule *module) {
    +gplugin_native_plugin_unload(G_GNUC_UNUSED GTypeModule *module) {
    }
    /******************************************************************************
    @@ -94,7 +109,6 @@
    GPluginNativePlugin,
    gplugin_native_plugin,
    G_TYPE_TYPE_MODULE,
    - G_ADD_PRIVATE(GPluginNativePlugin)
    G_IMPLEMENT_INTERFACE(GPLUGIN_TYPE_PLUGIN, gplugin_native_plugin_iface_init)
    );
    @@ -103,7 +117,6 @@
    GParamSpec *pspec)
    {
    GPluginNativePlugin *plugin = GPLUGIN_NATIVE_PLUGIN(obj);
    - GPluginNativePluginPrivate *priv = gplugin_native_plugin_get_instance_private(plugin);
    switch(param_id) {
    case PROP_MODULE:
    @@ -111,24 +124,24 @@
    gplugin_native_plugin_get_module(plugin));
    break;
    case PROP_LOAD_FUNC:
    - g_value_set_pointer(value, priv->load_func);
    + g_value_set_pointer(value, plugin->load_func);
    break;
    case PROP_UNLOAD_FUNC:
    - g_value_set_pointer(value, priv->unload_func);
    + g_value_set_pointer(value, plugin->unload_func);
    break;
    /* overrides */
    case PROP_FILENAME:
    - g_value_set_string(value, priv->filename);
    + g_value_set_string(value, plugin->filename);
    break;
    case PROP_LOADER:
    - g_value_set_object(value, priv->loader);
    + g_value_set_object(value, plugin->loader);
    break;
    case PROP_INFO:
    - g_value_set_object(value, priv->info);
    + g_value_set_object(value, plugin->info);
    break;
    case PROP_STATE:
    - g_value_set_enum(value, priv->state);
    + g_value_set_enum(value, plugin->state);
    break;
    default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
    @@ -140,31 +153,31 @@
    gplugin_native_plugin_set_property(GObject *obj, guint param_id,
    const GValue *value, GParamSpec *pspec)
    {
    - GPluginNativePluginPrivate *priv = gplugin_native_plugin_get_instance_private(GPLUGIN_NATIVE_PLUGIN(obj));
    + GPluginNativePlugin *plugin = GPLUGIN_NATIVE_PLUGIN(obj);
    switch(param_id) {
    case PROP_MODULE:
    - priv->module = g_value_get_pointer(value);
    + plugin->module = g_value_get_pointer(value);
    break;
    case PROP_LOAD_FUNC:
    - priv->load_func = g_value_get_pointer(value);
    + plugin->load_func = g_value_get_pointer(value);
    break;
    case PROP_UNLOAD_FUNC:
    - priv->unload_func = g_value_get_pointer(value);
    + plugin->unload_func = g_value_get_pointer(value);
    break;
    /* overrides */
    case PROP_FILENAME:
    - priv->filename = g_strdup(g_value_get_string(value));
    + plugin->filename = g_value_dup_string(value);
    break;
    case PROP_LOADER:
    - priv->loader = g_object_ref(g_value_get_object(value));
    + plugin->loader = g_value_dup_object(value);
    break;
    case PROP_INFO:
    - priv->info = g_object_ref(g_value_get_object(value));
    + plugin->info = g_value_dup_object(value);
    break;
    case PROP_STATE:
    - priv->state = g_value_get_enum(value);
    + plugin->state = g_value_get_enum(value);
    break;
    default:
    @@ -175,17 +188,17 @@
    static void
    gplugin_native_plugin_finalize(GObject *obj) {
    - GPluginNativePluginPrivate *priv = gplugin_native_plugin_get_instance_private(GPLUGIN_NATIVE_PLUGIN(obj));
    + GPluginNativePlugin *plugin = GPLUGIN_NATIVE_PLUGIN(obj);
    - g_free(priv->filename);
    - g_object_unref(G_OBJECT(priv->loader));
    - g_object_unref(G_OBJECT(priv->info));
    + g_clear_pointer(&plugin->filename, g_free);
    + g_clear_object(&plugin->loader);
    + g_clear_object(&plugin->info);
    G_OBJECT_CLASS(gplugin_native_plugin_parent_class)->finalize(obj);
    }
    static void
    -gplugin_native_plugin_init(GPluginNativePlugin *plugin) {
    +gplugin_native_plugin_init(G_GNUC_UNUSED GPluginNativePlugin *plugin) {
    }
    static void
    @@ -257,12 +270,8 @@
    */
    GModule *
    gplugin_native_plugin_get_module(GPluginNativePlugin *plugin) {
    - GPluginNativePluginPrivate *priv = NULL;
    -
    g_return_val_if_fail(GPLUGIN_IS_NATIVE_PLUGIN(plugin), NULL);
    - priv = gplugin_native_plugin_get_instance_private(plugin);
    -
    - return priv->module;
    + return plugin->module;
    }
    --- a/gplugin/gplugin-native-plugin.h Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/gplugin-native-plugin.h Mon Sep 30 01:28:39 2019 -0500
    @@ -22,37 +22,14 @@
    #ifndef GPLUGIN_NATIVE_PLUGIN_H
    #define GPLUGIN_NATIVE_PLUGIN_H
    -#define GPLUGIN_TYPE_NATIVE_PLUGIN (gplugin_native_plugin_get_type())
    -#define GPLUGIN_NATIVE_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GPLUGIN_TYPE_NATIVE_PLUGIN, GPluginNativePlugin))
    -#define GPLUGIN_NATIVE_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((obj), GPLUGIN_TYPE_NATIVE_PLUGIN, GPluginNativePluginClass))
    -#define GPLUGIN_IS_NATIVE_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GPLUGIN_TYPE_NATIVE_PLUGIN))
    -#define GPLUGIN_IS_NATIVE_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((obj), GPLUGIN_TYPE_NATIVE_PLUGIN))
    -#define GPLUGIN_NATIVE_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GPLUGIN_TYPE_NATIVE_PLUGIN, GPluginNativePluginClass))
    -
    -typedef struct _GPluginNativePlugin GPluginNativePlugin;
    -typedef struct _GPluginNativePluginClass GPluginNativePluginClass;
    +#include <gmodule.h>
    #include <gplugin/gplugin-plugin.h>
    -#include <gmodule.h>
    -
    -struct _GPluginNativePlugin {
    - /*< private >*/
    - GTypeModule parent;
    -
    - gpointer reserved[4];
    -};
    -
    -struct _GPluginNativePluginClass {
    - /*< private >*/
    - GTypeModuleClass parent;
    -
    - gpointer reserved[4];
    -};
    -
    G_BEGIN_DECLS
    -GType gplugin_native_plugin_get_type(void);
    +#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);
    --- a/gplugin/gplugin-options.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/gplugin-options.c Mon Sep 30 01:28:39 2019 -0500
    @@ -41,10 +41,10 @@
    static gchar **paths = NULL;
    static gboolean
    -gplugin_options_no_default_paths_cb(GPLUGIN_UNUSED const gchar *n,
    - GPLUGIN_UNUSED const gchar *v,
    - GPLUGIN_UNUSED gpointer d,
    - GPLUGIN_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;
    @@ -67,10 +67,10 @@
    };
    static gboolean
    -gplugin_options_post_parse_cb(GPLUGIN_UNUSED GOptionContext *ctx,
    - GPLUGIN_UNUSED GOptionGroup *group,
    - GPLUGIN_UNUSED gpointer data,
    - GPLUGIN_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)
    {
    gint i = 0;
    --- a/gplugin/gplugin-plugin-info.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/gplugin-plugin-info.c Mon Sep 30 01:28:39 2019 -0500
    @@ -29,6 +29,25 @@
    * #GPluginPluginInfo holds metadata for plugins.
    */
    +/**
    + * GPLUGIN_TYPE_PLUGIN_INFO:
    + *
    + * The standard _get_type macro for #GPluginPluginInfo.
    + */
    +
    +/**
    + * GPluginPluginInfo:
    + *
    + * #GPluginPluginInfo holds all of the data about a plugin. It is created when
    + * a plugin is queried.
    + */
    +
    +/**
    + * GPluginPluginInfoClass:
    + *
    + * The class structure for #GPluginPluginInfo.
    + */
    +
    /******************************************************************************
    * Structs
    *****************************************************************************/
    @@ -90,7 +109,7 @@
    };
    static GParamSpec *properties[N_PROPERTIES] = {NULL,};
    -G_DEFINE_TYPE_WITH_PRIVATE(GPluginPluginInfo, gplugin_plugin_info, G_TYPE_INITIALLY_UNOWNED)
    +G_DEFINE_TYPE_WITH_PRIVATE(GPluginPluginInfo, gplugin_plugin_info, G_TYPE_INITIALLY_UNOWNED)
    /******************************************************************************
    * Private API
    @@ -100,7 +119,7 @@
    GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    g_free(priv->id);
    - priv->id = (id) ? g_strdup(id) : NULL;
    + priv->id = g_strdup(id);
    }
    static void
    @@ -140,7 +159,7 @@
    GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    g_free(priv->name);
    - priv->name = (name) ? g_strdup(name) : NULL;
    + priv->name = g_strdup(name);
    }
    static void
    @@ -150,7 +169,7 @@
    GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    g_free(priv->version);
    - priv->version = (version) ? g_strdup(version) : NULL;
    + priv->version = g_strdup(version);
    }
    static void
    @@ -169,7 +188,7 @@
    GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    g_free(priv->license_id);
    - priv->license_id = (license_id) ? g_strdup(license_id) : NULL;
    + priv->license_id = g_strdup(license_id);
    }
    @@ -180,7 +199,7 @@
    GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    g_free(priv->license_text);
    - priv->license_text = (license_text) ? g_strdup(license_text) : NULL;
    + priv->license_text = g_strdup(license_text);
    }
    @@ -191,7 +210,7 @@
    GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    g_free(priv->license_url);
    - priv->license_url = (license_url) ? g_strdup(license_url) : NULL;
    + priv->license_url = g_strdup(license_url);
    }
    static void
    @@ -199,7 +218,7 @@
    GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    g_free(priv->icon);
    - priv->icon = (icon) ? g_strdup(icon) : NULL;
    + priv->icon = g_strdup(icon);
    }
    static void
    @@ -209,7 +228,7 @@
    GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    g_free(priv->summary);
    - priv->summary = (summary) ? g_strdup(summary) : NULL;
    + priv->summary = g_strdup(summary);
    }
    static void
    @@ -219,7 +238,7 @@
    GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    g_free(priv->description);
    - priv->description = (description) ? g_strdup(description) : NULL;
    + priv->description = g_strdup(description);
    }
    static void
    @@ -229,7 +248,7 @@
    GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    g_free(priv->category);
    - priv->category = (category) ? g_strdup(category) : NULL;
    + priv->category = g_strdup(category);
    }
    static void
    @@ -248,7 +267,7 @@
    GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    g_free(priv->help);
    - priv->help = (help) ? g_strdup(help) : NULL;
    + priv->help = g_strdup(help);
    }
    static void
    @@ -258,7 +277,7 @@
    GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    g_free(priv->website);
    - priv->website = (website) ? g_strdup(website) : NULL;
    + priv->website = g_strdup(website);
    }
    static void
    @@ -435,25 +454,25 @@
    gplugin_plugin_info_finalize(GObject *obj) {
    GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(GPLUGIN_PLUGIN_INFO(obj));
    - g_free(priv->id);
    - g_free(priv->name);
    - g_free(priv->version);
    - g_free(priv->license_id);
    - g_free(priv->license_text);
    - g_free(priv->license_url);
    - g_free(priv->icon);
    - g_free(priv->summary);
    - g_free(priv->description);
    - g_strfreev(priv->authors);
    - g_free(priv->help);
    - g_free(priv->website);
    - g_strfreev(priv->dependencies);
    + g_clear_pointer(&priv->id, g_free);
    + g_clear_pointer(&priv->name, g_free);
    + g_clear_pointer(&priv->version, g_free);
    + 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->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_OBJECT_CLASS(gplugin_plugin_info_parent_class)->finalize(obj);
    }
    static void
    -gplugin_plugin_info_init(GPluginPluginInfo *info) {
    +gplugin_plugin_info_init(G_GNUC_UNUSED GPluginPluginInfo *info) {
    }
    static void
    --- a/gplugin/gplugin-plugin-info.h Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/gplugin-plugin-info.h Mon Sep 30 01:28:39 2019 -0500
    @@ -22,39 +22,24 @@
    #ifndef GPLUGIN_PLUGIN_INFO_H
    #define GPLUGIN_PLUGIN_INFO_H
    -#define GPLUGIN_TYPE_PLUGIN_INFO (gplugin_plugin_info_get_type())
    -#define GPLUGIN_PLUGIN_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GPLUGIN_TYPE_PLUGIN_INFO, GPluginPluginInfo))
    -#define GPLUGIN_PLUGIN_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GPLUGIN_TYPE_PLUGIN_INFO, GPluginPluginInfoClass))
    -#define GPLUGIN_IS_PLUGIN_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GPLUGIN_TYPE_PLUGIN_INFO))
    -#define GPLUGIN_IS_PLUGIN_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GPLUGIN_TYPE_PLUGIN_INFO))
    -#define GPLUGIN_PLUGIN_INFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GPLUGIN_TYPE_PLUGIN_INFO, GPluginPluginInfoClass))
    -
    -typedef struct _GPluginPluginInfo GPluginPluginInfo;
    -typedef struct _GPluginPluginInfoClass GPluginPluginInfoClass;
    -
    #include <glib.h>
    #include <glib-object.h>
    +G_BEGIN_DECLS
    +
    +#define GPLUGIN_TYPE_PLUGIN_INFO (gplugin_plugin_info_get_type())
    +G_DECLARE_DERIVABLE_TYPE(GPluginPluginInfo, gplugin_plugin_info, GPLUGIN, PLUGIN_INFO, GInitiallyUnowned)
    +
    #include <gplugin/gplugin-loader.h>
    #include <gplugin/gplugin-version.h>
    -struct _GPluginPluginInfo {
    - GInitiallyUnowned gparent;
    -};
    -
    struct _GPluginPluginInfoClass {
    + /*< private >*/
    GInitiallyUnownedClass gparent;
    - void (*_gplugin_reserved_1)(void);
    - void (*_gplugin_reserved_2)(void);
    - void (*_gplugin_reserved_3)(void);
    - void (*_gplugin_reserved_4)(void);
    + gpointer reserved[4];
    };
    -G_BEGIN_DECLS
    -
    -GType gplugin_plugin_info_get_type(void);
    -
    #define gplugin_plugin_info_new(id, abi_version, ...) \
    GPLUGIN_PLUGIN_INFO( \
    g_object_new(GPLUGIN_TYPE_PLUGIN_INFO, \
    --- a/gplugin/gplugin-plugin.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/gplugin-plugin.c Mon Sep 30 01:28:39 2019 -0500
    @@ -18,7 +18,6 @@
    #include <gplugin/gplugin-plugin.h>
    #include <gplugin/gplugin-enums.h>
    -#include <gplugin/gplugin-marshallers.h>
    #include <gplugin/gplugin-private.h>
    /**
    @@ -44,6 +43,26 @@
    * The expected states of a plugin.
    */
    +/**
    + * GPLUGIN_TYPE_PLUGIN:
    + *
    + * The standard _get_type macro for #GPluginPlugin.
    + */
    +
    +/**
    + * GPluginPlugin:
    + *
    + * #GPluginPlugin is an opaque data structure and should not be used directly.
    + */
    +
    +/**
    + * GPluginPluginInterface:
    + * @state_changed: The class closure for the #GPluginPlugin::state-changed signal.
    + *
    + * The interface that defines the behavior of plugins, including properties and
    + * signals.
    + */
    +
    /******************************************************************************
    * Enums
    *****************************************************************************/
    @@ -128,11 +147,13 @@
    GPLUGIN_TYPE_PLUGIN,
    G_SIGNAL_RUN_LAST,
    G_STRUCT_OFFSET(GPluginPluginInterface, state_changed),
    - NULL, NULL,
    - gplugin_marshal_VOID__ENUM_ENUM,
    + NULL,
    + NULL,
    + NULL,
    G_TYPE_NONE,
    2,
    - GPLUGIN_TYPE_PLUGIN_STATE, GPLUGIN_TYPE_PLUGIN_STATE);
    + GPLUGIN_TYPE_PLUGIN_STATE,
    + GPLUGIN_TYPE_PLUGIN_STATE);
    }
    /******************************************************************************
    --- a/gplugin/gplugin-plugin.h Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/gplugin-plugin.h Mon Sep 30 01:28:39 2019 -0500
    @@ -22,13 +22,8 @@
    #ifndef GPLUGIN_PLUGIN_H
    #define GPLUGIN_PLUGIN_H
    -#define GPLUGIN_TYPE_PLUGIN (gplugin_plugin_get_type())
    -#define GPLUGIN_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GPLUGIN_TYPE_PLUGIN, GPluginPlugin))
    -#define GPLUGIN_IS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GPLUGIN_TYPE_PLUGIN))
    -#define GPLUGIN_PLUGIN_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE((obj), GPLUGIN_TYPE_PLUGIN, GPluginPluginInterface))
    -
    -typedef struct _GPluginPlugin GPluginPlugin;
    -typedef struct _GPluginPluginInterface GPluginPluginInterface;
    +#include <glib.h>
    +#include <glib-object.h>
    typedef enum /*< prefix=GPLUGIN_PLUGIN_STATE,underscore_name=GPLUGIN_PLUGIN_STATE >*/ {
    GPLUGIN_PLUGIN_STATE_UNKNOWN = -1,
    @@ -42,9 +37,12 @@
    GPLUGIN_PLUGIN_STATES, /*< skip >*/
    } GPluginPluginState;
    -#include <glib.h>
    -#include <glib-object.h>
    +G_BEGIN_DECLS
    +#define GPLUGIN_TYPE_PLUGIN (gplugin_plugin_get_type())
    +G_DECLARE_INTERFACE(GPluginPlugin, gplugin_plugin, GPLUGIN, PLUGIN, GObject)
    +
    +/* circular dependencies suck... */
    #include <gplugin/gplugin-plugin-info.h>
    #include <gplugin/gplugin-loader.h>
    @@ -52,16 +50,13 @@
    /*< private >*/
    GTypeInterface parent;
    + /*< public >*/
    void (*state_changed)(GPluginPlugin *plugin, GPluginPluginState oldstate, GPluginPluginState newstate);
    /*< private >*/
    gpointer reserved[8];
    };
    -G_BEGIN_DECLS
    -
    -GType gplugin_plugin_get_type(void);
    -
    gchar *gplugin_plugin_get_filename(GPluginPlugin *plugin);
    GPluginLoader *gplugin_plugin_get_loader(GPluginPlugin *plugin);
    GPluginPluginInfo *gplugin_plugin_get_info(GPluginPlugin *plugin);
    --- a/gplugin/gplugin-private.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/gplugin-private.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,10 +19,10 @@
    /* A GSignalAccumulator that stops emission if a handler returns FALSE */
    gboolean
    -gplugin_boolean_accumulator(GPLUGIN_UNUSED GSignalInvocationHint *hint,
    +gplugin_boolean_accumulator(G_GNUC_UNUSED GSignalInvocationHint *hint,
    GValue *return_accu,
    const GValue *handler_return,
    - GPLUGIN_UNUSED gpointer data)
    + G_GNUC_UNUSED gpointer data)
    {
    gboolean continue_emission;
    gboolean handler_returned;
    --- a/gplugin/gplugin-query.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/gplugin-query.c Mon Sep 30 01:28:39 2019 -0500
    @@ -36,10 +36,10 @@
    * Helpers
    *****************************************************************************/
    static gboolean
    -verbosity_cb(GPLUGIN_UNUSED const gchar *n,
    - GPLUGIN_UNUSED const gchar *v,
    - GPLUGIN_UNUSED gpointer d,
    - GPLUGIN_UNUSED GError **e)
    +verbosity_cb(G_GNUC_UNUSED const gchar *n,
    + G_GNUC_UNUSED const gchar *v,
    + G_GNUC_UNUSED gpointer d,
    + G_GNUC_UNUSED GError **e)
    {
    verbosity++;
    @@ -47,10 +47,10 @@
    }
    static gboolean
    -full_verbosity_cb(GPLUGIN_UNUSED const gchar *n,
    - GPLUGIN_UNUSED const gchar *v,
    - GPLUGIN_UNUSED gpointer d,
    - GPLUGIN_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)
    {
    verbosity = 1 << 11;
    @@ -58,10 +58,10 @@
    }
    static gboolean
    -internal_cb(GPLUGIN_UNUSED const gchar *n,
    - GPLUGIN_UNUSED const gchar *v,
    - GPLUGIN_UNUSED gpointer d,
    - GPLUGIN_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)
    {
    show_internal = TRUE;
    @@ -69,10 +69,10 @@
    }
    static gboolean
    -version_cb(GPLUGIN_UNUSED const gchar *n,
    - GPLUGIN_UNUSED const gchar *v,
    - GPLUGIN_UNUSED gpointer d,
    - GPLUGIN_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);
    @@ -82,10 +82,10 @@
    }
    static gboolean
    -list_cb(GPLUGIN_UNUSED const gchar *n,
    - GPLUGIN_UNUSED const gchar *v,
    - GPLUGIN_UNUSED gpointer d,
    - GPLUGIN_UNUSED GError **e)
    +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_paths = TRUE;
    --- a/gplugin/gplugin-version.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/gplugin-version.c Mon Sep 30 01:28:39 2019 -0500
    @@ -76,10 +76,8 @@
    matches = g_regex_match(regex, v, 0, &info);
    if(!matches) {
    - if(error) {
    - *error = g_error_new(GPLUGIN_DOMAIN, 0,
    - _("%s does not match the version regex"), v);
    - }
    + g_set_error(error, GPLUGIN_DOMAIN, 0,
    + _("%s does not match the version regex"), v);
    return FALSE;
    }
    @@ -109,6 +107,8 @@
    if(extra)
    *extra = g_match_info_fetch_named(info, "extra");
    + g_match_info_unref(info);
    +
    return TRUE;
    }
    --- a/gplugin/meson.build Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/meson.build Mon Sep 30 01:28:39 2019 -0500
    @@ -65,13 +65,12 @@
    'gplugin-plugin.h',
    ]
    -enums = gnome.mkenums('gplugin-enums',
    +enums = gnome.mkenums_simple(
    + 'gplugin-enums',
    sources : ENUM_HEADERS,
    - c_template : 'gplugin-enums.c.tmpl',
    - h_template : 'gplugin-enums.h.tmpl',
    - identifier_prefix : 'GPlugin',
    install_header : true,
    install_dir : join_paths(get_option('includedir'), 'gplugin-1.0', 'gplugin'))
    +
    enums_c = enums[0]
    enums_h = enums[1]
    @@ -83,23 +82,6 @@
    enums_c
    ]
    -###############################################################################
    -# gplugin-marshallers.[ch] generation
    -###############################################################################
    -marshallers = gnome.genmarshal('gplugin-marshallers',
    - sources : 'gplugin-marshallers.list',
    - prefix : 'gplugin_marshal')
    -marshallers_c = marshallers[0]
    -marshallers_h = marshallers[1]
    -
    -GPLUGIN_PRIVATE_BUILT_HEADERS += [
    - marshallers_h
    -]
    -
    -GPLUGIN_PRIVATE_BUILT_SOURCES += [
    - marshallers_c
    -]
    -
    ##############################################################################
    # Helper Variables
    ###############################################################################
    @@ -120,7 +102,6 @@
    gplugin_version_h
    ]
    -
    gplugin_inc = include_directories('.')
    # Build gplugin.h
    @@ -206,17 +187,6 @@
    ],
    )
    -# nls
    -if get_option('nls')
    -# gettextize_pot_file(
    -# SORT
    -# LANGUAGES C
    -# SOURCES ${GPLUGIN_SOURCES} ${GPLUGIN_NATIVE_SOURCES} gplugin-query.c
    -# BUILT_SOURCES ${GPLUGIN_PUBLIC_BUILT_SOURCES}
    -# FILENAME gplugin.pot
    -# )
    -endif
    -
    ###############################################################################
    # gplugin-query executable
    ###############################################################################
    @@ -256,10 +226,12 @@
    GPLUGIN_PUBLIC_BUILT_SOURCES +
    GPLUGIN_PUBLIC_BUILT_HEADERS,
    includes : ['GModule-2.0', 'GObject-2.0'],
    + header : 'gplugin.h',
    namespace : 'GPlugin',
    symbol_prefix : 'gplugin',
    nsversion : '@0@.0'.format(GPLUGIN_MAJOR_VERSION),
    install : true,
    + export_packages : ['gplugin'],
    extra_args : ['--quiet', '-DGPLUGIN_COMPILATION'])
    endif
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin/reference/Dockerfile Mon Sep 30 01:28:39 2019 -0500
    @@ -0,0 +1,6 @@
    +FROM rwgrim/goserve
    +
    +EXPOSE 3000
    +
    +COPY html html
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin/reference/embedding.xml Mon Sep 30 01:28:39 2019 -0500
    @@ -0,0 +1,54 @@
    +<?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-embedding">
    + <title>Embedding GPlugin</title>
    +
    + <simplesect id="intro">
    + <para>
    + You can embed GPlugin into any language that has GObject-Introspection
    + support, but in this example we're going to look at embedding GPlugin
    + into a C based project.
    + </para>
    +
    + <para>
    + Using GPlugin is pretty simple and I'd like to think straight forward
    + since that's the way I designed it.
    + </para>
    + </simplesect>
    +
    + <simplesect id="initialization">
    + <para>
    + During the start up of your application you need to add the following
    + code:
    + <informalexample><programlisting>
    + /* Initialize the GPlugin library */
    + gplugin_init();
    +
    + /* Tell GPlugin to look for plugins in its default paths */
    + gplugin_manager_add_default_paths();
    +
    + /* Optionally tell GPlugin to look for plugins in application specific
    + * paths.
    + */
    + 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>
    + </para>
    + </simplesect>
    +
    + <simplesect id="shutdown">
    + <para>
    + When your application is shutting down you need to uninitialize GPlugin
    + by calling
    + <informalexample><programlisting>
    + gplugin_uninit();
    + </programlisting></informalexample>
    + </para>
    + </simplesect>
    +</chapter>
    \ No newline at end of file
    --- a/gplugin/reference/gplugin-docs.xml Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/reference/gplugin-docs.xml Mon Sep 30 01:28:39 2019 -0500
    @@ -19,6 +19,16 @@
    </abstract>
    </bookinfo>
    + <part id="tutorials">
    + <title>Tutorials</title>
    +
    + <xi:include href="embedding.xml"/>
    + <xi:include href="native-plugins.xml"/>
    + <xi:include href="lua.xml"/>
    + <xi:include href="python.xml"/>
    + <xi:include href="vala.xml"/>
    + </part>
    +
    <part id="object-hierarchy">
    <title>Object Hierarchy</title>
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin/reference/lua.xml Mon Sep 30 01:28:39 2019 -0500
    @@ -0,0 +1,56 @@
    +<?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-lua">
    + <title>Lua Plugins</title>
    +
    + <warning>
    + <para>
    + You <emphasis role="strong">MUST</emphasis> have the Lua loader
    + plugin installed and working as well as the gobject-introspection
    + package for GPlugin installed to use Lua plugins.
    + </para>
    + </warning>
    +
    + <simplesect>
    + <title>Example Lua Plugin</title>
    +
    + <para>
    + Like all plugins in GPlugin, Lua plugins must also implement
    + the <code>gplugin_query</code>, <code>gplugin_load</code>, and
    + <code>gplugin_unload</code> functions.
    + </para>
    +
    + <para>
    + The following is a basic Lua plugin.
    + <informalexample><programlisting>
    + local lgi = require 'lgi'
    + local GPlugin = lgi.GPlugin
    +
    + function gplugin_query()
    + return GPlugin.PluginInfo {
    + id = "gplugin-lua/basic-plugin",
    + abi_version = 0x01020304,
    + name = "basic plugin",
    + category = "test",
    + version = "0.0.10",
    + license_id = "license-id",
    + summary = "basic lua plugin",
    + description = "description of the basic lua plugin",
    + authors = { "Gary Kramlich &lt;grim@reaperworld.com&gt;" },
    + website = "https://bitbucket.org/gplugin/gplugin/"
    + }
    + end
    +
    + function gplugin_load(plugin)
    + return true
    + end
    +
    + function gplugin_unload(plugin)
    + return true
    + end
    + </programlisting></informalexample>
    + </para>
    + </simplesect>
    +</chapter>
    --- a/gplugin/reference/meson.build Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/reference/meson.build Mon Sep 30 01:28:39 2019 -0500
    @@ -2,13 +2,13 @@
    # Header files or dirs to ignore when scanning. Use base file/dir names
    ignore_hfiles = [
    - 'gplugin.h',
    - 'gplugin-private.h',
    + 'dynamic-test.h',
    + 'gplugin-enums.h',
    'gplugin-loader-tests.h',
    - 'gplugin-marshallers.h',
    + 'gplugin-native-private.h',
    'gplugin-native.h',
    - 'gplugin-native-private.h',
    - 'dynamic-test.h',
    + 'gplugin-private.h',
    + 'gplugin.h',
    ]
    ignore_hfiles += GPLUGIN_PRIVATE_HEADERS
    @@ -17,12 +17,6 @@
    '--deprecated-guards=GPLUGIN_DISABLE_DEPRECATED',
    '--rebuild-types',
    '--rebuild-sections',
    - '--ignore-headers=' + ' '.join(ignore_hfiles),
    -]
    -
    -# Extra options to supply to gtkdoc-mkdb.
    -mkdb_args = [
    - '--ignore-files=' + ' '.join(ignore_hfiles),
    ]
    gplugin_version_xml = configure_file(
    @@ -31,15 +25,19 @@
    configuration : version_conf)
    content_files = [
    + 'embedding.xml',
    + 'lua.xml',
    + 'native-plugins.xml',
    + 'python.xml',
    ]
    gnome.gtkdoc(DOC_MODULE,
    main_xml : DOC_MODULE + '-docs.xml',
    src_dir : gplugin_inc,
    dependencies : gplugin_dep,
    + ignore_headers : ignore_hfiles,
    install : true,
    scan_args : scan_args,
    - mkdb_args : mkdb_args,
    gobject_typesfile : DOC_MODULE + '.types',
    content_files : content_files,
    )
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin/reference/native-plugins.xml Mon Sep 30 01:28:39 2019 -0500
    @@ -0,0 +1,80 @@
    +<?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-native-plugins">
    + <title>Writing Native Plugins</title>
    +
    + <simplesect id="intro">
    + <para>
    + Writing Native plugins is very simple, but since it's C/C++ it's a bit
    + more complicated.
    + </para>
    +
    + <para>
    + There are currently no C++ bindings and no intention to write them, but
    + the C API is still usable from C++.
    + </para>
    + </simplesect>
    +
    + <simplesect id="example">
    + <para>
    + <informalexample><programlisting>
    + #include &lt;gplugin.h&gt;
    + #include &lt;gplugin-native.h&gt;
    +
    + /* 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
    + * returned.
    + */
    + 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 &lt;user@domain.com&gt;" format.
    + */
    + const gchar * const authors[] = {
    + "author",
    + NULL
    + };
    +
    + /* gplugin_plugin_info_new only requires that the id be set, and the
    + * rest are here for demonstration purposes.
    + */
    + return gplugin_plugin_info_new(
    + "gplugin/basic-native-plugin",
    + GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
    + "name", "name",
    + "version", "version",
    + "summary", "summary",
    + "description", "description",
    + "authors", authors,
    + "website", "website",
    + NULL
    + );
    + }
    +
    + /* gplugin_plugin_load is called by the loader when the plugin should
    + * be loaded. It must have this exact signature and return TRUE if
    + * loading was successful, otherwise it should return FALSE with error
    + * set to a valid GError.
    + */
    + G_MODULE_EXPORT gboolean
    + gplugin_plugin_load(GPluginNativePlugin *plugin, GError **error) {
    + return TRUE;
    + }
    +
    + /* gplugin_plugin_unload is called by the loader when the plugin should
    + * be unloaded. It must have this exact signature and should return TRUE
    + * if unloading was successful, otherwise it should return FALSE with
    + * error set to a valid GError.
    + */
    + G_MODULE_EXPORT gboolean
    + gplugin_plugin_unload(GPluginNativePlugin *plugin, GError **error) {
    + return TRUE;
    + }
    + </programlisting></informalexample>
    + </para>
    + </simplesect>
    +</chapter>
    \ No newline at end of file
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin/reference/python.xml Mon Sep 30 01:28:39 2019 -0500
    @@ -0,0 +1,56 @@
    +<?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-python">
    + <title>Python Plugins</title>
    +
    + <warning>
    + <para>
    + You <emphasis role="strong">MUST</emphasis> have the Python loader
    + plugin installed and working as well as the gobject-introspection
    + package for GPlugin installed to use Python plugins.
    + </para>
    + </warning>
    +
    + <simplesect>
    + <title>Example Python Plugin</title>
    +
    + <para>
    + Like all plugins in GPlugin, Python plugins must also implement
    + the <code>gplugin_query</code>, <code>gplugin_load</code>, and
    + <code>gplugin_unload</code> functions.
    + </para>
    +
    + <para>
    + The following is a basic Python plugin.
    + <informalexample><programlisting>
    + import gi
    +
    + 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,
    + name='basic plugin',
    + authors=['author1'],
    + category='test',
    + version='version',
    + license_id='license',
    + summary='summary',
    + website='website',
    + description='description',
    + )
    +
    + def gplugin_plugin_load(plugin):
    + return True
    +
    +
    + def gplugin_plugin_unload(plugin):
    + return True
    + </programlisting></informalexample>
    + </para>
    + </simplesect>
    +</chapter>
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin/reference/vala.xml Mon Sep 30 01:28:39 2019 -0500
    @@ -0,0 +1,74 @@
    +<?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-vala">
    + <title>Vala Plugins</title>
    +
    + <warning>
    + <para>
    + You <emphasis role="strong">MUST</emphasis> have the Vala bindings
    + installed on your system for this to work. They are built by the
    + default GPlugin build.
    + </para>
    + </warning>
    +
    + <simplesect>
    + <title>Example Vala Plugin</title>
    +
    + <para>
    + Like all plugins in GPlugin, Vala plugins must also implement
    + the <code>gplugin_query</code>, <code>gplugin_load</code>, and
    + <code>gplugin_unload</code> functions.
    + </para>
    +
    + <para>
    + Due to the way <code>GPlugin.PluginInfo</code> info works, you must
    + subclass it and set your values in the new constructor.
    + </para>
    +
    + <para>
    + The following is a basic Vala plugin.
    + <informalexample><programlisting>
    + using GPlugin;
    +
    + public class BasicPluginInfo : GPlugin.PluginInfo {
    + public BasicPluginInfo() {
    + string[] authors = {"author1"};
    +
    + Object(
    + id: "gplugin/vala-basic-plugin",
    + abi_version: 0x01020304,
    + name: "basic plugin",
    + authors: authors,
    + category: "test",
    + version: "version",
    + license_id: "license",
    + summary: "summary",
    + website: "website",
    + description: "description"
    + );
    + }
    + }
    +
    + public GPlugin.PluginInfo gplugin_query(out Error error) {
    + error = null;
    +
    + return new BasicPluginInfo();
    + }
    +
    + public bool gplugin_load(GPlugin.Plugin plugin, out Error error) {
    + error = null;
    +
    + return true;
    + }
    +
    + public bool gplugin_unload(GPlugin.Plugin plugin, out Error error) {
    + error = null;
    +
    + return true;
    + }
    + </programlisting></informalexample>
    + </para>
    + </simplesect>
    +</chapter>
    --- a/gplugin/tests/bad-plugins/query-error.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/bad-plugins/query-error.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,23 +19,22 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    - if(error)
    - *error = g_error_new(GPLUGIN_DOMAIN, 0, "expected error");
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    + g_set_error(error, GPLUGIN_DOMAIN, 0, "expected error");
    return NULL;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/gplugin/tests/bind-local/bind-local.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/bind-local/bind-local.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,7 +19,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    return gplugin_plugin_info_new(
    "gplugin/bind-local",
    0x04030201,
    @@ -29,15 +29,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/gplugin/tests/dynamic-type/dynamic-type-provider.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/dynamic-type/dynamic-type-provider.c Mon Sep 30 01:28:39 2019 -0500
    @@ -23,21 +23,21 @@
    G_DEFINE_DYNAMIC_TYPE(DynamicTest, dynamic_test, G_TYPE_OBJECT);
    static void
    -dynamic_test_init(DynamicTest *inst) {
    +dynamic_test_init(G_GNUC_UNUSED DynamicTest *inst) {
    g_message("instance created");
    }
    static void
    -dynamic_test_class_finalize(DynamicTestClass *klass) {
    +dynamic_test_class_finalize(G_GNUC_UNUSED DynamicTestClass *klass) {
    }
    static void
    -dynamic_test_class_init(DynamicTestClass *klass) {
    +dynamic_test_class_init(G_GNUC_UNUSED DynamicTestClass *klass) {
    g_message("class created");
    }
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    return gplugin_plugin_info_new(
    "gplugin/dynamic-type-provider",
    GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
    @@ -46,15 +46,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPluginNativePlugin *plugin, GError **error) {
    +gplugin_load(GPluginNativePlugin *plugin, G_GNUC_UNUSED GError **error) {
    dynamic_test_register_type(G_TYPE_MODULE(plugin));
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/gplugin/tests/dynamic-type/dynamic-type-user.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/dynamic-type/dynamic-type-user.c Mon Sep 30 01:28:39 2019 -0500
    @@ -23,7 +23,7 @@
    static DynamicTest *test_object = NULL;
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    const gchar * const dependencies[] = {
    "gplugin/dynamic-type-provider",
    NULL
    @@ -38,12 +38,12 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_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) {
    - *error = g_error_new(GPLUGIN_DOMAIN, 0,
    - "could not create an instance of DynamicTest");
    + g_set_error(error, GPLUGIN_DOMAIN, 0,
    + "could not create an instance of DynamicTest");
    return FALSE;
    }
    @@ -51,12 +51,16 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin, GError **error) {
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin, GError **error)
    +{
    + gpointer weak_test_object = test_object;
    + g_object_add_weak_pointer(G_OBJECT(test_object), &weak_test_object);
    +
    g_object_unref(test_object);
    - if (DYNAMIC_IS_TEST(test_object)) {
    - *error = g_error_new(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");
    return FALSE;
    }
    --- a/gplugin/tests/dynamic-type/meson.build Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/dynamic-type/meson.build Mon Sep 30 01:28:39 2019 -0500
    @@ -1,3 +1,5 @@
    +if host_machine.system() != 'windows'
    +
    dynamic_type_provider = shared_library('dynamic-type-provider',
    'dynamic-type-provider.c',
    name_prefix : '',
    @@ -6,3 +8,5 @@
    shared_module('dynamic-type-user', 'dynamic-type-user.c',
    name_prefix : '',
    dependencies : [gplugin_dep, GLIB])
    +
    +endif
    --- a/gplugin/tests/id-collision/id-collision1.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/id-collision/id-collision1.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,7 +19,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    return gplugin_plugin_info_new(
    "gplugin/id-collision",
    GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
    @@ -29,15 +29,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/gplugin/tests/id-collision/id-collision2.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/id-collision/id-collision2.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,7 +19,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    return gplugin_plugin_info_new(
    "gplugin/id-collision",
    GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
    @@ -29,15 +29,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/gplugin/tests/load-on-query-fail/load-on-query-fail.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/load-on-query-fail/load-on-query-fail.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,7 +19,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_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,
    @@ -29,17 +29,17 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin, GError **error) {
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin, GError **error) {
    static int count = 1;
    - *error = g_error_new(GPLUGIN_DOMAIN, 0, "called %d times", count++);
    + g_set_error(error, GPLUGIN_DOMAIN, 0, "called %d times", count++);
    return FALSE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/gplugin/tests/load-on-query-pass/load-on-query-pass.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/load-on-query-pass/load-on-query-pass.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,7 +19,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    return gplugin_plugin_info_new(
    "gplugin/load-on-query",
    GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
    @@ -29,15 +29,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/gplugin/tests/plugins/basic-plugin.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/plugins/basic-plugin.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,7 +19,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    const gchar * const authors[] = {
    "author1",
    NULL
    @@ -41,15 +41,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/gplugin/tests/plugins/broken-dependent-plugin.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/plugins/broken-dependent-plugin.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,7 +19,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    const gchar * const dependencies[] = {
    "gplugin/does-not-exist",
    NULL
    @@ -34,15 +34,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/gplugin/tests/plugins/dependent-plugin.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/plugins/dependent-plugin.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,7 +19,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    const gchar * const dependencies[] = {
    "dependency1",
    "dependency2",
    @@ -35,15 +35,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/gplugin/tests/plugins/load-exception.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/plugins/load-exception.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,7 +19,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    return gplugin_plugin_info_new(
    "gplugin/native-load-exception",
    GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
    @@ -28,15 +28,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return FALSE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/gplugin/tests/plugins/load-failed.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/plugins/load-failed.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,7 +19,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    return gplugin_plugin_info_new(
    "gplugin/native-load-failed",
    GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
    @@ -28,16 +28,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin, GError **error) {
    - if(error)
    - *error = g_error_new(GPLUGIN_DOMAIN, 0, "expected error");
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin, GError **error) {
    + g_set_error(error, GPLUGIN_DOMAIN, 0, "expected error");
    return FALSE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/gplugin/tests/plugins/unload-failed.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/plugins/unload-failed.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,7 +19,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    return gplugin_plugin_info_new(
    "gplugin/native-unload-failed",
    GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
    @@ -28,16 +28,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin, GError **error) {
    - if(error)
    - *error = g_error_new(GPLUGIN_DOMAIN, 0, "expected error");
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin, GError **error) {
    + g_set_error(error, GPLUGIN_DOMAIN, 0, "expected error");
    return FALSE;
    }
    --- a/gplugin/tests/test-bind-local.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/test-bind-local.c Mon Sep 30 01:28:39 2019 -0500
    @@ -39,9 +39,9 @@
    gplugin_manager_refresh();
    plugin = gplugin_manager_find_plugin("gplugin/bind-local");
    - g_assert(plugin);
    - g_assert(GPLUGIN_IS_PLUGIN(plugin));
    - g_assert(GPLUGIN_IS_NATIVE_PLUGIN(plugin));
    + g_assert_nonnull(plugin);
    + g_assert_true(GPLUGIN_IS_PLUGIN(plugin));
    + g_assert_true(GPLUGIN_IS_NATIVE_PLUGIN(plugin));
    }
    /******************************************************************************
    --- a/gplugin/tests/test-dynamic-type.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/test-dynamic-type.c Mon Sep 30 01:28:39 2019 -0500
    @@ -38,8 +38,8 @@
    provider = gplugin_manager_find_plugin("gplugin/dynamic-type-provider");
    - g_assert(provider);
    - g_assert(gplugin_manager_load_plugin(provider, &error));
    + g_assert_nonnull(provider);
    + g_assert_true(gplugin_manager_load_plugin(provider, &error));
    g_assert_no_error(error);
    state = gplugin_plugin_get_state(provider);
    @@ -47,21 +47,21 @@
    user = gplugin_manager_find_plugin("gplugin/dynamic-type-user");
    - g_assert(user);
    - g_assert(gplugin_manager_load_plugin(user, &error));
    + g_assert_nonnull(user);
    + g_assert_true(gplugin_manager_load_plugin(user, &error));
    g_assert_no_error(error);
    state = gplugin_plugin_get_state(user);
    g_assert_cmpint(state, ==, GPLUGIN_PLUGIN_STATE_LOADED);
    /* now unload the plugin */
    - g_assert(gplugin_manager_unload_plugin(user, &error));
    + g_assert_true(gplugin_manager_unload_plugin(user, &error));
    g_assert_no_error(error);
    state = gplugin_plugin_get_state(user);
    g_assert_cmpint(state, ==, GPLUGIN_PLUGIN_STATE_QUERIED);
    - g_assert(gplugin_manager_unload_plugin(provider, &error));
    + g_assert_true(gplugin_manager_unload_plugin(provider, &error));
    g_assert_no_error(error);
    state = gplugin_plugin_get_state(provider);
    --- a/gplugin/tests/test-id-collision.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/test-id-collision.c Mon Sep 30 01:28:39 2019 -0500
    @@ -35,9 +35,9 @@
    gplugin_manager_refresh();
    plugins = gplugin_manager_find_plugins("gplugin/id-collision");
    - g_assert(plugins);
    + g_assert_nonnull(plugins);
    - g_assert(g_slist_length(plugins) == 2);
    + g_assert_cmpuint(g_slist_length(plugins), ==, 2);
    gplugin_manager_free_plugin_list(plugins);
    }
    --- a/gplugin/tests/test-load-on-query.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/test-load-on-query.c Mon Sep 30 01:28:39 2019 -0500
    @@ -35,8 +35,8 @@
    gplugin_manager_refresh();
    plugin = gplugin_manager_find_plugin("gplugin/load-on-query");
    - g_assert(plugin);
    - g_assert(GPLUGIN_IS_PLUGIN(plugin));
    + g_assert_nonnull(plugin);
    + g_assert_true(GPLUGIN_IS_PLUGIN(plugin));
    g_assert_cmpint(gplugin_plugin_get_state(plugin), ==,
    GPLUGIN_PLUGIN_STATE_LOADED);
    @@ -61,12 +61,7 @@
    static void
    test_load_on_query_fail(void) {
    -#if GLIB_CHECK_VERSION(2,38,0)
    g_test_trap_subprocess("/loaders/native/load-on-query/fail/subprocess", 0, 0);
    -#else
    - if(g_test_trap_fork(0, G_TEST_TRAP_SILENCE_STDERR))
    - test_load_on_query_fail_subprocess();
    -#endif
    g_test_trap_assert_stderr("*failed to load*during query*");
    }
    @@ -86,10 +81,8 @@
    test_load_on_query);
    g_test_add_func("/loaders/native/load-on-query/fail",
    test_load_on_query_fail);
    -#if GLIB_CHECK_VERSION(2,38,0)
    g_test_add_func("/loaders/native/load-on-query/fail/subprocess",
    test_load_on_query_fail_subprocess);
    -#endif
    return g_test_run();
    }
    --- a/gplugin/tests/test-native-loader.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/test-native-loader.c Mon Sep 30 01:28:39 2019 -0500
    @@ -42,13 +42,13 @@
    /* find the dependent plugin and make sure it isn't loaded */
    plugin =
    gplugin_manager_find_plugin("gplugin/broken-dependent-native-plugin");
    - g_assert(plugin != NULL);
    + g_assert_nonnull(plugin);
    state = gplugin_plugin_get_state(plugin);
    g_assert_cmpint(state, !=, GPLUGIN_PLUGIN_STATE_LOADED);
    /* now attempt to load the dependent plugin, it's supposed to fail */
    - g_assert(!gplugin_manager_load_plugin(plugin, &error));
    + g_assert_false(gplugin_manager_load_plugin(plugin, &error));
    }
    /******************************************************************************
    @@ -66,17 +66,12 @@
    /* find the query-error plugin */
    plugin = gplugin_manager_find_plugin("gplugin/query-error");
    - g_assert(plugin == NULL);
    + g_assert_null(plugin);
    }
    static void
    test_query_error(void) {
    -#if GLIB_CHECK_VERSION(2,38,0)
    g_test_trap_subprocess("/loaders/native/error/query/subprocess", 0, 0);
    -#else
    - if(g_test_trap_fork(0, G_TEST_TRAP_SILENCE_STDERR))
    - test_query_error_subprocess();
    -#endif
    g_test_trap_assert_failed();
    }
    @@ -99,10 +94,8 @@
    /* bad plugin tests */
    g_test_add_func("/loaders/native/error/query",
    test_query_error);
    -#if GLIB_CHECK_VERSION(2,38,0)
    g_test_add_func("/loaders/native/error/query/subprocess",
    test_query_error_subprocess);
    -#endif
    return g_test_run();
    }
    --- a/gplugin/tests/test-option-group.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/test-option-group.c Mon Sep 30 01:28:39 2019 -0500
    @@ -29,15 +29,13 @@
    GOptionGroup *group = NULL;
    GList *paths = NULL, *l1 = NULL, *l2 = NULL;
    gchar **argv = NULL;
    - gint argc = 0;
    argv = g_strsplit(args, ",", 0);
    - argc = g_strv_length(argv);
    ctx = g_option_context_new(NULL);
    group = gplugin_get_option_group();
    g_option_context_add_group(ctx, group);
    - g_option_context_parse(ctx, &argc, &argv, &error);
    + g_option_context_parse_strv(ctx, &argv, &error);
    g_option_context_free(ctx);
    g_strfreev(argv);
    @@ -45,7 +43,7 @@
    paths = gplugin_manager_get_paths();
    paths = g_list_sort(paths, g_str_equal);
    - expected = g_list_sort(expected, g_str_equal);
    + expected = g_list_sort(expected, g_str_equal); //-V522
    g_assert_cmpuint(g_list_length(paths), ==, g_list_length(expected));
    @@ -54,7 +52,7 @@
    }
    /* now check to see if we exited early */
    - g_assert(l1 == NULL || l2 == NULL);
    + g_assert_true(l1 == NULL || l2 == NULL);
    for(l2 = expected; l2; l2 = l2->next)
    g_free(l2->data);
    --- a/gplugin/tests/test-plugin-info.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/test-plugin-info.c Mon Sep 30 01:28:39 2019 -0500
    @@ -31,9 +31,14 @@
    g_assert_cmpuint((var), ==, gplugin_plugin_info_get_##var(info)); \
    } G_STMT_END
    -#define test_bool(var, value) G_STMT_START { \
    - g_assert((var) == (value)); \
    - g_assert((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)); \
    +} G_STMT_END
    +
    +#define test_false(var) G_STMT_START { \
    + g_assert_false((var)); \
    + g_assert_false(gplugin_plugin_info_get_##var(info)); \
    } G_STMT_END
    typedef gchar **(*TestStringVFunc)(GPluginPluginInfo *info);
    @@ -42,18 +47,27 @@
    test_stringv(gchar **got, const gchar * const * const expected,
    TestStringVFunc func, GPluginPluginInfo *info)
    {
    - gint i = 0;
    - gchar **tmp = NULL;
    + gint i = 0;
    + gchar **tmp = NULL;
    - for(i = 0; got[i]; i++)
    - g_assert_cmpstr(got[i], ==, expected[i]);
    + /* make sure our arrarys are the same length */
    + g_assert_cmpuint(g_strv_length(got), ==, g_strv_length((gchar **)expected));
    +
    + /* now walk through until expected[i] is null comparing each entry */
    + for(i = 0; expected[i]; i++)
    + g_assert_cmpstr(got[i], ==, expected[i]);
    - tmp = func(info);
    + /* call the accessor on the GPluginPluginInfo object */
    + tmp = func(info);
    +
    + /* verify that the accessor returned the proper value as well */
    + g_assert_cmpuint(g_strv_length(tmp), ==, g_strv_length((gchar **)expected));
    - for(i = 0; got[i]; i++)
    - g_assert_cmpstr(got[i], ==, tmp[i]);
    + for(i = 0; expected[i]; i++)
    + g_assert_cmpstr(tmp[i], ==, expected[i]);
    - g_strfreev(tmp);
    + g_strfreev(got);
    + g_strfreev(tmp);
    }
    /******************************************************************************
    @@ -93,7 +107,7 @@
    NULL
    );
    - g_assert(GPLUGIN_IS_PLUGIN_INFO(info));
    + g_assert_true(GPLUGIN_IS_PLUGIN_INFO(info));
    g_object_get(G_OBJECT(info),
    "id", &id,
    @@ -118,8 +132,8 @@
    test_string(id, "gplugin-test/plugin-info-test");
    test_uint(abi_version, GPLUGIN_NATIVE_PLUGIN_ABI_VERSION);
    - test_bool(internal, TRUE);
    - test_bool(load_on_query, TRUE);
    + test_true(internal);
    + test_true(load_on_query);
    test_string(name, "name");
    test_string(version, "version");
    test_string(license_id, "license-id");
    @@ -145,7 +159,7 @@
    info = gplugin_plugin_info_new("empty", 1, NULL);
    - g_assert(GPLUGIN_IS_PLUGIN_INFO(info));
    + g_assert_true(GPLUGIN_IS_PLUGIN_INFO(info));
    g_object_get(G_OBJECT(info),
    "id", &id,
    @@ -192,7 +206,7 @@
    NULL
    );
    - g_assert(GPLUGIN_IS_PLUGIN_INFO(info));
    + g_assert_true(GPLUGIN_IS_PLUGIN_INFO(info));
    g_object_get(G_OBJECT(info),
    "id", &id,
    @@ -217,8 +231,8 @@
    test_string(id, "gplugin-test/plugin-info-test");
    test_uint(abi_version, GPLUGIN_NATIVE_PLUGIN_ABI_VERSION);
    - test_bool(internal, TRUE);
    - test_bool(load_on_query, TRUE);
    + test_true(internal);
    + test_true(load_on_query);
    test_string(name, "name");
    test_string(version, "version");
    test_string(license_id, "license-id");
    @@ -337,12 +351,14 @@
    NULL);
    got = gplugin_plugin_info_get_version_func(info);
    - g_assert(func == got);
    + g_assert_true(func == got);
    }
    static gint
    -test_gplugin_version_compare(GPLUGIN_UNUSED const gchar *v1,
    - GPLUGIN_UNUSED const gchar *v2) {
    +test_gplugin_version_compare(G_GNUC_UNUSED const gchar *v1,
    + G_GNUC_UNUSED const gchar *v2,
    + G_GNUC_UNUSED GError *error)
    +{
    return 0;
    }
    --- a/gplugin/tests/test-plugin-manager-paths.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/test-plugin-manager-paths.c Mon Sep 30 01:28:39 2019 -0500
    @@ -106,7 +106,6 @@
    for(l = paths; l; l = l->next) {
    g_hash_table_remove(req, l->data);
    }
    - g_list_free(paths);
    size = g_hash_table_size(req);
    @@ -142,7 +141,6 @@
    paths = gplugin_manager_get_paths();
    for(l = paths; l != NULL; l = l->next)
    g_hash_table_remove(req, l->data);
    - g_list_free(paths);
    /* now check the hash table size, if it's > 0 then an expected path wasn't
    * added.
    --- a/gplugin/tests/test-signals.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/test-signals.c Mon Sep 30 01:28:39 2019 -0500
    @@ -31,9 +31,9 @@
    * Callbacks
    *****************************************************************************/
    static gboolean
    -test_gplugin_manager_signals_normal_loading(GPLUGIN_UNUSED GObject *manager,
    - GPLUGIN_UNUSED GPluginPlugin *plugin,
    - GPLUGIN_UNUSED GError **error,
    +test_gplugin_manager_signals_normal_loading(G_GNUC_UNUSED GObject *manager,
    + G_GNUC_UNUSED GPluginPlugin *plugin,
    + G_GNUC_UNUSED GError **error,
    gpointer d)
    {
    TestGPluginManagerSignalsData *data = (TestGPluginManagerSignalsData *)d;
    @@ -44,8 +44,8 @@
    }
    static void
    -test_gplugin_manager_signals_normal_loaded(GPLUGIN_UNUSED GObject *manager,
    - GPLUGIN_UNUSED GPluginPlugin *plugin,
    +test_gplugin_manager_signals_normal_loaded(G_GNUC_UNUSED GObject *manager,
    + G_GNUC_UNUSED GPluginPlugin *plugin,
    gpointer d)
    {
    TestGPluginManagerSignalsData *data = (TestGPluginManagerSignalsData *)d;
    @@ -54,9 +54,9 @@
    }
    static gboolean
    -test_gplugin_manager_signals_normal_unloading(GPLUGIN_UNUSED GObject *manager,
    - GPLUGIN_UNUSED GPluginPlugin *plugin,
    - GPLUGIN_UNUSED GError **error,
    +test_gplugin_manager_signals_normal_unloading(G_GNUC_UNUSED GObject *manager,
    + G_GNUC_UNUSED GPluginPlugin *plugin,
    + G_GNUC_UNUSED GError **error,
    gpointer d)
    {
    TestGPluginManagerSignalsData *data = (TestGPluginManagerSignalsData *)d;
    @@ -67,8 +67,8 @@
    }
    static void
    -test_gplugin_manager_signals_normal_unloaded(GPLUGIN_UNUSED GObject *manager,
    - GPLUGIN_UNUSED GPluginPlugin *plugin,
    +test_gplugin_manager_signals_normal_unloaded(G_GNUC_UNUSED GObject *manager,
    + G_GNUC_UNUSED GPluginPlugin *plugin,
    gpointer d)
    {
    TestGPluginManagerSignalsData *data = (TestGPluginManagerSignalsData *)d;
    @@ -77,8 +77,8 @@
    }
    static gboolean
    -test_gplugin_manager_signals_stop_loading(GPLUGIN_UNUSED GObject *manager,
    - GPLUGIN_UNUSED GPluginPlugin *plugin,
    +test_gplugin_manager_signals_stop_loading(G_GNUC_UNUSED GObject *manager,
    + G_GNUC_UNUSED GPluginPlugin *plugin,
    GError **error,
    gpointer d)
    {
    @@ -92,8 +92,8 @@
    }
    static gboolean
    -test_gplugin_manager_signals_stop_unloading(GPLUGIN_UNUSED GObject *manager,
    - GPLUGIN_UNUSED GPluginPlugin *plugin,
    +test_gplugin_manager_signals_stop_unloading(G_GNUC_UNUSED GObject *manager,
    + G_GNUC_UNUSED GPluginPlugin *plugin,
    GError **error,
    gpointer d)
    {
    @@ -107,8 +107,8 @@
    }
    static void
    -test_gplugin_manager_signals_load_failed(GPLUGIN_UNUSED GObject *manager,
    - GPLUGIN_UNUSED GPluginPlugin *plugin,
    +test_gplugin_manager_signals_load_failed(G_GNUC_UNUSED GObject *manager,
    + G_GNUC_UNUSED GPluginPlugin *plugin,
    gpointer d)
    {
    TestGPluginManagerSignalsData *data = (TestGPluginManagerSignalsData *)d;
    @@ -150,13 +150,13 @@
    plugin = gplugin_manager_find_plugin("gplugin/native-basic-plugin");
    gplugin_manager_load_plugin(plugin, &error);
    g_assert_no_error(error);
    - g_assert(data.loading);
    - g_assert(data.loaded);
    + g_assert_true(data.loading);
    + g_assert_true(data.loaded);
    gplugin_manager_unload_plugin(plugin, &error);
    g_assert_no_error(error);
    - g_assert(data.unloading);
    - g_assert(data.unloaded);
    + g_assert_true(data.unloading);
    + g_assert_true(data.unloaded);
    g_signal_handler_disconnect(manager, signals[0]);
    g_signal_handler_disconnect(manager, signals[1]);
    @@ -195,10 +195,10 @@
    plugin = gplugin_manager_find_plugin("gplugin/native-basic-plugin");
    gplugin_manager_load_plugin(plugin, &error);
    g_assert_error(error, GPLUGIN_DOMAIN, 0);
    - g_assert(data.loading);
    - g_assert(data.loaded == FALSE);
    - g_assert(data.unloading == FALSE);
    - g_assert(data.unloaded == FALSE);
    + g_assert_true(data.loading);
    + g_assert_false(data.loaded);
    + g_assert_false(data.unloading);
    + g_assert_false(data.unloaded);
    g_signal_handler_disconnect(manager, signals[0]);
    g_signal_handler_disconnect(manager, signals[1]);
    @@ -237,13 +237,13 @@
    plugin = gplugin_manager_find_plugin("gplugin/native-basic-plugin");
    gplugin_manager_load_plugin(plugin, &error);
    g_assert_no_error(error);
    - g_assert(data.loading);
    - g_assert(data.loaded);
    + 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(data.unloading);
    - g_assert(data.unloaded == FALSE);
    + g_assert_true(data.unloading);
    + g_assert_false(data.unloaded);
    g_signal_handler_disconnect(manager, signals[0]);
    g_signal_handler_disconnect(manager, signals[1]);
    @@ -274,8 +274,8 @@
    plugin = gplugin_manager_find_plugin("gplugin/native-load-failed");
    gplugin_manager_load_plugin(plugin, &error);
    g_assert_error(error, GPLUGIN_DOMAIN, 0);
    - g_assert(data.loading);
    - g_assert(data.load_failed);
    + g_assert_true(data.loading);
    + g_assert_true(data.load_failed);
    g_signal_handler_disconnect(manager, signals[0]);
    g_signal_handler_disconnect(manager, signals[1]);
    --- a/gplugin/tests/test-version-compare.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/test-version-compare.c Mon Sep 30 01:28:39 2019 -0500
    @@ -28,12 +28,7 @@
    static void
    test_gplugin_version_null__null(void) {
    -#if GLIB_CHECK_VERSION(2,38,0)
    g_test_trap_subprocess("/version-check/null__null/subprocess", 0, 0);
    -#else
    - if(g_test_trap_fork(0, G_TEST_TRAP_SILENCE_STDERR))
    - test_gplugin_version_null__null_subprocess();
    -#endif
    g_test_trap_assert_failed();
    g_test_trap_assert_stderr("*gplugin_version_compare*assertion*");
    @@ -46,12 +41,7 @@
    static void
    test_gplugin_version_null__1_2_3(void) {
    -#if GLIB_CHECK_VERSION(2,38,0)
    g_test_trap_subprocess("/version-check/null__1_2_3/subprocess", 0, 0);
    -#else
    - if(g_test_trap_fork(0, G_TEST_TRAP_SILENCE_STDERR))
    - test_gplugin_version_null__1_2_3_subprocess();
    -#endif
    g_test_trap_assert_failed();
    g_test_trap_assert_stderr("*gplugin_version_compare*assertion*");
    @@ -64,12 +54,7 @@
    static void
    test_gplugin_version_1_2_3__null(void) {
    -#if GLIB_CHECK_VERSION(2,38,0)
    g_test_trap_subprocess("/version-check/1_2_3__null/subprocess", 0, 0);
    -#else
    - if(g_test_trap_fork(0, G_TEST_TRAP_SILENCE_STDERR))
    - test_gplugin_version_1_2_3__null_subprocess();
    -#endif
    g_test_trap_assert_failed();
    g_test_trap_assert_stderr("*gplugin_version_compare*assertion*");
    @@ -82,18 +67,13 @@
    t = gplugin_version_compare("abc", "1.2.3", &error);
    - g_assert(t == 1);
    + g_assert_cmpint(t, ==, 1);
    g_assert_no_error(error);
    }
    static void
    test_gplugin_version_abc__1_2_3(void) {
    -#if GLIB_CHECK_VERSION(2,38,0)
    g_test_trap_subprocess("/version-check/abc__1_2_3/subprocess", 0, 0);
    -#else
    - if(g_test_trap_fork(0, G_TEST_TRAP_SILENCE_STDERR))
    - test_gplugin_version_abc__1_2_3_subprocess();
    -#endif
    g_test_trap_assert_failed();
    g_test_trap_assert_stderr("*assertion*");
    @@ -106,18 +86,13 @@
    t = gplugin_version_compare("1.2.3", "abc", &error);
    - g_assert(t == -1);
    + g_assert_cmpint(t, ==, -1);
    g_assert_no_error(error);
    }
    static void
    test_gplugin_version_1_2_3__abc(void) {
    -#if GLIB_CHECK_VERSION(2,38,0)
    g_test_trap_subprocess("/version-check/1_2_3__abc/subprocess", 0, 0);
    -#else
    - if(g_test_trap_fork(0, G_TEST_TRAP_SILENCE_STDERR))
    - test_gplugin_version_1_2_3__abc_subprocess();
    -#endif
    g_test_trap_assert_failed();
    g_test_trap_assert_stderr("*assertion*");
    @@ -126,49 +101,49 @@
    /* major version tests */
    static void
    test_gplugin_version_1_0_0__0_0_0(void) {
    - g_assert(gplugin_version_compare("1.0.0", "0.0.0", NULL) == -1);
    + g_assert_cmpint(gplugin_version_compare("1.0.0", "0.0.0", NULL), ==, -1);
    }
    static void
    test_gplugin_version_1_0_0__1_0_0(void) {
    - g_assert(gplugin_version_compare("1.0.0", "1.0.0", NULL) == 0);
    + g_assert_cmpint(gplugin_version_compare("1.0.0", "1.0.0", NULL), ==, 0);
    }
    static void
    test_gplugin_version_0_0_0__1_0_0(void) {
    - g_assert(gplugin_version_compare("0.0.0", "1.0.0", NULL) == 1);
    + g_assert_cmpint(gplugin_version_compare("0.0.0", "1.0.0", NULL), ==, 1);
    }
    /* minor version tests */
    static void
    test_gplugin_version_0_1_0__0_0_0(void) {
    - g_assert(gplugin_version_compare("0.1.0", "0.0.0", NULL) == -1);
    + g_assert_cmpint(gplugin_version_compare("0.1.0", "0.0.0", NULL), ==, -1);
    }
    static void
    test_gplugin_version_0_1_0__0_1_0(void) {
    - g_assert(gplugin_version_compare("0.1.0", "0.1.0", NULL) == 0);
    + g_assert_cmpint(gplugin_version_compare("0.1.0", "0.1.0", NULL), ==, 0);
    }
    static void
    test_gplugin_version_0_0_0__0_1_0(void) {
    - g_assert(gplugin_version_compare("0.0.0", "0.1.0", NULL) == 1);
    + g_assert_cmpint(gplugin_version_compare("0.0.0", "0.1.0", NULL), ==, 1);
    }
    /* micro version tests */
    static void
    test_gplugin_version_0_0_1__0_0_0(void) {
    - g_assert(gplugin_version_compare("0.1.0", "0.0.0", NULL) == -1);
    + g_assert_cmpint(gplugin_version_compare("0.1.0", "0.0.0", NULL), ==, -1);
    }
    static void
    test_gplugin_version_0_0_1__0_0_1(void) {
    - g_assert(gplugin_version_compare("0.1.0", "0.1.0", NULL) == 0);
    + g_assert_cmpint(gplugin_version_compare("0.1.0", "0.1.0", NULL), ==, 0);
    }
    static void
    test_gplugin_version_0_0_0__0_0_1(void) {
    - g_assert(gplugin_version_compare("0.0.0", "0.1.0", NULL) == 1);
    + g_assert_cmpint(gplugin_version_compare("0.0.0", "0.1.0", NULL), ==, 1);
    }
    /* major-minor tests */
    @@ -217,8 +192,6 @@
    test_gplugin_version_abc__1_2_3);
    g_test_add_func("/version-check/1_2_3__abc",
    test_gplugin_version_1_2_3__abc);
    -
    -#if GLIB_CHECK_VERSION(2,38,0)
    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",
    @@ -229,7 +202,6 @@
    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);
    -#endif
    /* major version */
    g_test_add_func("/version-check/1_0_0__0_0_0",
    --- a/gplugin/tests/test-versioned-dependencies.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/test-versioned-dependencies.c Mon Sep 30 01:28:39 2019 -0500
    @@ -27,7 +27,7 @@
    *****************************************************************************/
    static void
    _test_plugin_load_and_has_dependent(GPluginPlugin *dependent,
    - const gchar *id)
    + G_GNUC_UNUSED const gchar *id)
    {
    GPluginPlugin *plugin = NULL;
    GSList *deps = NULL, *l = NULL;
    @@ -66,8 +66,8 @@
    gplugin_manager_refresh();
    plugin = gplugin_manager_find_plugin("gplugin/super-dependent");
    - g_assert(plugin);
    - g_assert(GPLUGIN_IS_PLUGIN(plugin));
    + g_assert_nonnull(plugin);
    + g_assert_true(GPLUGIN_IS_PLUGIN(plugin));
    gplugin_manager_load_plugin(plugin, &error);
    g_assert_no_error(error);
    --- a/gplugin/tests/unresolved-symbol/meson.build Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/unresolved-symbol/meson.build Mon Sep 30 01:28:39 2019 -0500
    @@ -1,4 +1,14 @@
    +if host_machine.system() != 'windows'
    +
    +if compiler.get_id() == 'gcc'
    + link_args = '-Wl,--warn-unresolved-symbols'
    +else
    + link_args = []
    +endif
    +
    shared_module('unresolved-symbol', 'unresolved-symbol.c',
    name_prefix : '',
    - link_args : '-Wl,--warn-unresolved-symbols',
    + link_args : link_args,
    dependencies : [gplugin_dep, GLIB])
    +
    +endif
    --- a/gplugin/tests/unresolved-symbol/unresolved-symbol.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/unresolved-symbol/unresolved-symbol.c Mon Sep 30 01:28:39 2019 -0500
    @@ -21,22 +21,22 @@
    void some_unresolved_symbol(void);
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    some_unresolved_symbol();
    return NULL;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/gplugin/tests/versioned-dependencies/bar.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/versioned-dependencies/bar.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,7 +19,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    return gplugin_plugin_info_new(
    "gplugin/bar",
    0x04030201,
    @@ -29,15 +29,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/gplugin/tests/versioned-dependencies/baz.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/versioned-dependencies/baz.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,7 +19,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    return gplugin_plugin_info_new(
    "gplugin/baz",
    0x04030201,
    @@ -29,15 +29,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/gplugin/tests/versioned-dependencies/exact1.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/versioned-dependencies/exact1.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,7 +19,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    return gplugin_plugin_info_new(
    "gplugin/test-exact1",
    0x04030201,
    @@ -29,15 +29,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/gplugin/tests/versioned-dependencies/exact2.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/versioned-dependencies/exact2.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,7 +19,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    return gplugin_plugin_info_new(
    "gplugin/test-exact2",
    0x04030201,
    @@ -29,15 +29,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/gplugin/tests/versioned-dependencies/fez.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/versioned-dependencies/fez.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,7 +19,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    return gplugin_plugin_info_new(
    "gplugin/fez",
    0x04030201,
    @@ -29,15 +29,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/gplugin/tests/versioned-dependencies/greater-equal.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/versioned-dependencies/greater-equal.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,7 +19,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    return gplugin_plugin_info_new(
    "gplugin/test-greater-equal",
    0x04030201,
    @@ -29,15 +29,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/gplugin/tests/versioned-dependencies/greater.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/versioned-dependencies/greater.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,7 +19,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    return gplugin_plugin_info_new(
    "gplugin/test-greater",
    0x04030201,
    @@ -29,15 +29,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/gplugin/tests/versioned-dependencies/less-equal.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/versioned-dependencies/less-equal.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,7 +19,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    return gplugin_plugin_info_new(
    "gplugin/test-less-equal",
    0x04030201,
    @@ -29,15 +29,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/gplugin/tests/versioned-dependencies/less.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/versioned-dependencies/less.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,7 +19,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    return gplugin_plugin_info_new(
    "gplugin/test-less",
    0x04030201,
    @@ -29,15 +29,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/gplugin/tests/versioned-dependencies/no-version.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/versioned-dependencies/no-version.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,7 +19,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    return gplugin_plugin_info_new(
    "gplugin/test-no-version",
    0x04030201,
    @@ -28,15 +28,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/gplugin/tests/versioned-dependencies/super-dependent.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/gplugin/tests/versioned-dependencies/super-dependent.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,7 +19,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    const gchar * const dependencies[] = {
    "gplugin/test-no-version",
    "gplugin/test-exact1==1.0",
    @@ -44,15 +44,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/lua/gplugin-lua-core.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/lua/gplugin-lua-core.c Mon Sep 30 01:28:39 2019 -0500
    @@ -23,7 +23,7 @@
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    const gchar * const authors[] = {
    "Gary Kramlich <grim@reaperworld.com>",
    NULL
    @@ -49,19 +49,19 @@
    G_MODULE_EXPORT gboolean
    gplugin_load(GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    + G_GNUC_UNUSED GError **error)
    {
    gplugin_lua_loader_register(plugin);
    gplugin_lua_plugin_register(plugin);
    - gplugin_manager_register_loader(gplugin_lua_loader_get_type());
    + gplugin_manager_register_loader(GPLUGIN_LUA_TYPE_LOADER);
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return FALSE;
    }
    --- a/lua/gplugin-lua-loader.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/lua/gplugin-lua-loader.c Mon Sep 30 01:28:39 2019 -0500
    @@ -25,6 +25,10 @@
    #include <lauxlib.h>
    #include <lualib.h>
    +struct _GPluginLuaLoader {
    + GPluginLoader parent;
    +};
    +
    G_DEFINE_DYNAMIC_TYPE(GPluginLuaLoader, gplugin_lua_loader, GPLUGIN_TYPE_LOADER);
    /******************************************************************************
    @@ -39,12 +43,11 @@
    msg = lua_tostring(L, -1);
    - *error = g_error_new(GPLUGIN_DOMAIN, 0,
    - "%s", (msg) ? msg : "Unknown");
    + g_set_error_literal(error, GPLUGIN_DOMAIN, 0, (msg) ? msg : "Unknown");
    }
    static gboolean
    -_gplugin_lua_loader_load_unload_plugin(GPLUGIN_UNUSED GPluginLoader *loader,
    +_gplugin_lua_loader_load_unload_plugin(G_GNUC_UNUSED GPluginLoader *loader,
    GPluginPlugin *plugin,
    const gchar *function,
    GError **error)
    @@ -78,7 +81,7 @@
    * GPluginLoaderInterface API
    *****************************************************************************/
    static GSList *
    -gplugin_lua_loader_class_supported_extensions(GPLUGIN_UNUSED const GPluginLoaderClass *klass) {
    +gplugin_lua_loader_class_supported_extensions(G_GNUC_UNUSED GPluginLoaderClass *klass) {
    GSList *exts = NULL;
    exts = g_slist_append(exts, "lua");
    @@ -112,8 +115,7 @@
    }
    if(!lua_istable(L, -1)) {
    - if(error)
    - *error = g_error_new(GPLUGIN_DOMAIN, 0, "moonscript returned an unexpected value");
    + g_set_error(error, GPLUGIN_DOMAIN, 0, "moonscript returned an unexpected value");
    return NULL;
    }
    @@ -143,8 +145,7 @@
    lua_getglobal(L, "gplugin_query");
    if(lua_isnil(L, -1)) {
    - if(error)
    - *error = g_error_new(GPLUGIN_DOMAIN, 0, "no gplugin_query function found");
    + g_set_error(error, GPLUGIN_DOMAIN, 0, "no gplugin_query function found");
    return NULL;
    }
    @@ -164,7 +165,7 @@
    info = lua_touserdata(L, -1);
    lua_pop(L, 1);
    - plugin = g_object_new(GPLUGIN_TYPE_LUA_PLUGIN,
    + plugin = g_object_new(GPLUGIN_LUA_TYPE_PLUGIN,
    "filename", filename,
    "loader", loader,
    "lua-state", L,
    @@ -195,11 +196,11 @@
    * GObject Stuff
    *****************************************************************************/
    static void
    -gplugin_lua_loader_init(GPluginLuaLoader *loader) {
    +gplugin_lua_loader_init(G_GNUC_UNUSED GPluginLuaLoader *loader) {
    }
    static void
    -gplugin_lua_loader_class_finalize(GPluginLuaLoaderClass *klass) {
    +gplugin_lua_loader_class_finalize(G_GNUC_UNUSED GPluginLuaLoaderClass *klass) {
    }
    static void
    --- a/lua/gplugin-lua-loader.h Tue Jan 22 22:58:59 2019 -0600
    +++ b/lua/gplugin-lua-loader.h Mon Sep 30 01:28:39 2019 -0500
    @@ -18,37 +18,15 @@
    #ifndef GPLUGIN_LUA_LOADER_H
    #define GPLUGIN_LUA_LOADER_H
    -#define GPLUGIN_TYPE_LUA_LOADER (gplugin_lua_loader_get_type())
    -#define GPLUGIN_LUA_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GPLUGIN_TYPE_LUA_LOADER, GPluginLuaLoader))
    -#define GPLUGIN_LUA_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((obj), GPLUGIN_TYPE_LUA_LOADER, GPluginLuaLoaderClass))
    -#define GPLUGIN_IS_LUA_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GPLUGIN_TYPE_LUA_LOADER))
    -#define GPLUGIN_IS_LUA_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((obj), GPLUGIN_TYPE_LUA_LOADER))
    -#define GPLUGIN_LUA_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GPLUGIN_TYPE_LUA_LOADER, GPluginLuaLoaderClass))
    -
    -typedef struct _GPluginLuaLoader GPluginLuaLoader;
    -typedef struct _GPluginLuaLoaderClass GPluginLuaLoaderClass;
    -
    #include <gplugin.h>
    #include <gplugin-native.h>
    -struct _GPluginLuaLoader {
    - /*< private >*/
    - GPluginLoader parent;
    -
    - gpointer reserved[4];
    -};
    -
    -struct _GPluginLuaLoaderClass {
    - /*< private >*/
    - GPluginLoaderClass parent;
    -
    - gpointer reserved[4];
    -};
    -
    G_BEGIN_DECLS
    +#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);
    -GType gplugin_lua_loader_get_type(void);
    G_END_DECLS
    --- a/lua/gplugin-lua-plugin.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/lua/gplugin-lua-plugin.c Mon Sep 30 01:28:39 2019 -0500
    @@ -22,14 +22,16 @@
    /******************************************************************************
    * Typedefs
    *****************************************************************************/
    -typedef struct {
    +struct _GPluginLuaPlugin {
    + GObject parent;
    +
    lua_State *L;
    gchar *filename;
    GPluginLoader *loader;
    GPluginPluginInfo *info;
    GPluginPluginState state;
    -} GPluginLuaPluginPrivate;
    +};
    /******************************************************************************
    * Enums
    @@ -54,7 +56,6 @@
    gplugin_lua_plugin,
    G_TYPE_OBJECT,
    0,
    - G_ADD_PRIVATE_DYNAMIC(GPluginLuaPlugin)
    G_IMPLEMENT_INTERFACE(GPLUGIN_TYPE_PLUGIN, gplugin_lua_plugin_iface_init)
    );
    @@ -62,7 +63,7 @@
    * GPluginPlugin Implementation
    *****************************************************************************/
    static void
    -gplugin_lua_plugin_iface_init(GPluginPluginInterface *iface) {
    +gplugin_lua_plugin_iface_init(G_GNUC_UNUSED GPluginPluginInterface *iface) {
    }
    /******************************************************************************
    @@ -73,25 +74,24 @@
    GParamSpec *pspec)
    {
    GPluginLuaPlugin *plugin = GPLUGIN_LUA_PLUGIN(obj);
    - GPluginLuaPluginPrivate *priv = gplugin_lua_plugin_get_instance_private(plugin);
    switch(param_id) {
    case PROP_LUA_STATE:
    - g_value_set_pointer(value, priv->L);
    + g_value_set_pointer(value, plugin->L);
    break;
    /* overrides */
    case PROP_FILENAME:
    - g_value_set_string(value, priv->filename);
    + g_value_set_string(value, plugin->filename);
    break;
    case PROP_LOADER:
    - g_value_set_object(value, priv->loader);
    + g_value_set_object(value, plugin->loader);
    break;
    case PROP_INFO:
    - g_value_set_object(value, priv->info);
    + g_value_set_object(value, plugin->info);
    break;
    case PROP_STATE:
    - g_value_set_enum(value, priv->state);
    + g_value_set_enum(value, plugin->state);
    break;
    default:
    @@ -105,25 +105,24 @@
    const GValue *value, GParamSpec *pspec)
    {
    GPluginLuaPlugin *plugin = GPLUGIN_LUA_PLUGIN(obj);
    - GPluginLuaPluginPrivate *priv = gplugin_lua_plugin_get_instance_private(plugin);
    switch(param_id) {
    case PROP_LUA_STATE:
    - priv->L = g_value_get_pointer(value);
    + plugin->L = g_value_get_pointer(value);
    break;
    /* overrides */
    case PROP_FILENAME:
    - priv->filename = g_strdup(g_value_get_string(value));
    + plugin->filename = g_value_dup_string(value);
    break;
    case PROP_LOADER:
    - priv->loader = g_object_ref(g_value_get_object(value));
    + plugin->loader = g_value_dup_object(value);
    break;
    case PROP_INFO:
    - priv->info = g_object_ref(g_value_get_object(value));
    + plugin->info = g_value_dup_object(value);
    break;
    case PROP_STATE:
    - priv->state = g_value_get_enum(value);
    + plugin->state = g_value_get_enum(value);
    break;
    default:
    @@ -134,24 +133,22 @@
    static void
    gplugin_lua_plugin_finalize(GObject *obj) {
    - GPluginLuaPluginPrivate *priv = gplugin_lua_plugin_get_instance_private(GPLUGIN_LUA_PLUGIN(obj));
    + GPluginLuaPlugin *plugin = GPLUGIN_LUA_PLUGIN(obj);
    - if(priv->L)
    - lua_close(priv->L);
    -
    - g_free(priv->filename);
    - g_object_unref(G_OBJECT(priv->loader));
    - g_object_unref(G_OBJECT(priv->info));
    + 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_OBJECT_CLASS(gplugin_lua_plugin_parent_class)->finalize(obj);
    }
    static void
    -gplugin_lua_plugin_init(GPluginLuaPlugin *plugin) {
    +gplugin_lua_plugin_init(G_GNUC_UNUSED GPluginLuaPlugin *plugin) {
    }
    static void
    -gplugin_lua_plugin_class_finalize(GPluginLuaPluginClass *klass) {
    +gplugin_lua_plugin_class_finalize(G_GNUC_UNUSED GPluginLuaPluginClass *klass) {
    }
    static void
    @@ -187,11 +184,7 @@
    lua_State *
    gplugin_lua_plugin_get_state(GPluginLuaPlugin *plugin) {
    - GPluginLuaPluginPrivate *priv = NULL;
    -
    - g_return_val_if_fail(GPLUGIN_IS_LUA_PLUGIN(plugin), NULL);
    + g_return_val_if_fail(GPLUGIN_LUA_IS_PLUGIN(plugin), NULL);
    - priv = gplugin_lua_plugin_get_instance_private(plugin);
    -
    - return priv->L;
    + return plugin->L;
    }
    --- a/lua/gplugin-lua-plugin.h Tue Jan 22 22:58:59 2019 -0600
    +++ b/lua/gplugin-lua-plugin.h Mon Sep 30 01:28:39 2019 -0500
    @@ -18,39 +18,17 @@
    #ifndef GPLUGIN_LUA_PLUGIN_H
    #define GPLUGIN_LUA_PLUGIN_H
    -#define GPLUGIN_TYPE_LUA_PLUGIN (gplugin_lua_plugin_get_type())
    -#define GPLUGIN_LUA_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GPLUGIN_TYPE_LUA_PLUGIN, GPluginLuaPlugin))
    -#define GPLUGIN_LUA_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((obj), GPLUGIN_TYPE_LUA_PLUGIN, GPluginLuaPluginClass))
    -#define GPLUGIN_IS_LUA_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GPLUGIN_TYPE_LUA_PLUGIN))
    -#define GPLUGIN_IS_LUA_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((obj), GPLUGIN_TYPE_LUA_PLUGIN))
    -#define GPLUGIN_LUA_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GPLUGIN_TYPE_LUA_PLUGIN, GPluginLuaPluginClass))
    -
    -typedef struct _GPluginLuaPlugin GPluginLuaPlugin;
    -typedef struct _GPluginLuaPluginClass GPluginLuaPluginClass;
    -
    #include <gplugin.h>
    #include <gplugin-native.h>
    #include <lua.h>
    -struct _GPluginLuaPlugin {
    - /*< private >*/
    - GObject parent;
    -
    - gpointer reserved[4];
    -};
    -
    -struct _GPluginLuaPluginClass {
    - /*< private >*/
    - GObjectClass parent;
    -
    - gpointer reserved[4];
    -};
    -
    G_BEGIN_DECLS
    +#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);
    -GType gplugin_lua_plugin_get_type(void);
    lua_State *gplugin_lua_plugin_get_state(GPluginLuaPlugin *plugin);
    --- a/lua/meson.build Tue Jan 22 22:58:59 2019 -0600
    +++ b/lua/meson.build Mon Sep 30 01:28:39 2019 -0500
    @@ -17,7 +17,8 @@
    _LUAS = [['lua', '>=5.1.0'],
    ['lua5.1', '>=5.1.0'],
    ['luajit', '>=2.0.0'],
    - ['lua5.2', '>=5.2.0']]
    + ['lua5.2', '>=5.2.0'],
    + ['lua-5.2', '>=5.2.0']]
    LUA_FOUND = false
    foreach _LUA : _LUAS
    if not LUA_FOUND
    --- a/lua/tests/meson.build Tue Jan 22 22:58:59 2019 -0600
    +++ b/lua/tests/meson.build Mon Sep 30 01:28:39 2019 -0500
    @@ -2,7 +2,7 @@
    e = executable('test-lua-loader', 'test-lua-loader.c',
    c_args : [
    - '-DLUA_LOADER_DIR="@0@/lua"'.format(meson.build_root()),
    + '-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(
    @@ -15,7 +15,7 @@
    if get_option('moonscript-tests')
    e = executable('test-lua-moon-loader', 'test-lua-moon-loader.c',
    c_args : [
    - '-DLUA_LOADER_DIR="@0@/lua"'.format(meson.build_root()),
    + '-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(
    --- a/meson.build Tue Jan 22 22:58:59 2019 -0600
    +++ b/meson.build Mon Sep 30 01:28:39 2019 -0500
    @@ -1,8 +1,8 @@
    ###############################################################################
    # Project Info
    ###############################################################################
    -project('gplugin', 'c', version : '0.28.0',
    - meson_version : '>=0.37.0',
    +project('gplugin', 'c', version : '0.28.1',
    + meson_version : '>=0.42.0',
    default_options : ['c_std=c99'])
    parts = meson.project_version().split('-')
    @@ -77,20 +77,6 @@
    output : 'gplugin-version.sh',
    configuration : version_conf)
    -# check if we're using gcc
    -if compiler.get_id() == 'gcc' or host_machine.platform() == 'darwin'
    - add_project_arguments(
    - '-DGPLUGIN_UNUSED=__attribute__((unused))',
    - '-ggdb',
    - language : 'c'
    - )
    -else
    - add_project_arguments(
    - '-DGPLUGIN_UNUSED=',
    - language : 'c'
    - )
    -endif
    -
    toplevel_inc = include_directories('.')
    @@ -118,41 +104,12 @@
    subdir('perl')
    subdir('python')
    subdir('tcc')
    +subdir('vala')
    ###############################################################################
    # Install stuff
    ###############################################################################
    # documentation
    -install_data('ChangeLog', 'INSTALL', 'README', 'HACKING',
    +install_data('ChangeLog', 'INSTALL.md', 'README.md', 'HACKING',
    install_dir : join_paths(get_option('datadir'), 'doc', 'gplugin'))
    -###############################################################################
    -# make dist
    -###############################################################################
    -#set(ARCHIVES
    -# gplugin-${GPLUGIN_VERSION}.tar.bz2
    -# gplugin-${GPLUGIN_VERSION}.tar.gz
    -# gplugin-${GPLUGIN_VERSION}.zip
    -#)
    -
    -#set(SIGNATURES)
    -
    -#foreach(ARCHIVE ${ARCHIVES})
    -# add_custom_command(
    -# COMMAND hg archive ${ARCHIVE}
    -# OUTPUT ${ARCHIVE}
    -# DEPENDS .
    -# WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
    -# )
    -#
    -# add_custom_command(
    -# COMMAND gpg --yes -abs ${ARCHIVE}
    -# OUTPUT ${ARCHIVE}.asc
    -# DEPENDS . ${ARCHIVE}
    -# WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
    -# )
    -#
    -# list(APPEND SIGNATURES ${ARCHIVE}.asc)
    -#endforeach(ARCHIVE)
    -#
    -#add_custom_target(dist DEPENDS ${ARCHIVES} ${SIGNATURES})
    --- a/meson_options.txt Tue Jan 22 22:58:59 2019 -0600
    +++ b/meson_options.txt Mon Sep 30 01:28:39 2019 -0500
    @@ -60,3 +60,9 @@
    type : 'boolean', value : false,
    description : 'Whether or not to build the TCC plugin loader'
    )
    +
    +option(
    + 'vapi',
    + type : 'boolean', value : true,
    + description : 'Whether or not to build vapi files for gplugin'
    +)
    --- a/packaging/debian/changelog Tue Jan 22 22:58:59 2019 -0600
    +++ b/packaging/debian/changelog Mon Sep 30 01:28:39 2019 -0500
    @@ -1,8 +1,8 @@
    -gplugin (0.28) UNRELEASED; urgency=medium
    +gplugin (0.28.1) UNRELEASED; urgency=medium
    * New upstream release, see official changelog
    - -- Gary Kramlich <grim@reaperworld.com> Mon, 18 Apr 2016 22:31:45 -0500
    + -- Gary Kramlich <grim@reaperworld.com> Tue, 22 Jan 2019 23:02:37 -0600
    gplugin (0.26) unstable; urgency=medium
    --- a/packaging/debian/control Tue Jan 22 22:58:59 2019 -0600
    +++ b/packaging/debian/control Mon Sep 30 01:28:39 2019 -0500
    @@ -4,10 +4,11 @@
    Maintainer: Gary Kramlich <grim@reaperworld.com>
    Build-Depends: debhelper (>=9),
    meson (>=0.37.0), libglib2.0-dev, libgtk-3-dev,
    - xsltproc, gettext, help2man,
    + gettext, help2man,
    gobject-introspection, libgirepository1.0-dev,
    liblua5.1-0-dev, lua-lgi,
    - python3-dev, python-gi-dev, python3-gi
    + python3-dev, python-gi-dev, python3-gi,
    + valac
    Homepage: https://bitbucket.org/gplugin/gplugin
    Vcs-Browser: https://bitbucket.org/gplugin/gplugin/src
    Vcs-Hg: https://bitbucket.org/gplugin/gplugin
    --- a/packaging/debian/libgplugin-dev.install Tue Jan 22 22:58:59 2019 -0600
    +++ b/packaging/debian/libgplugin-dev.install Mon Sep 30 01:28:39 2019 -0500
    @@ -3,3 +3,6 @@
    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/vala/vapi/gplugin.deps
    +debian/tmp/usr/share/vala/vapi/gplugin.vapi
    +
    --- a/packaging/debian/libgplugin-gtk-dev.install Tue Jan 22 22:58:59 2019 -0600
    +++ b/packaging/debian/libgplugin-gtk-dev.install Mon Sep 30 01:28:39 2019 -0500
    @@ -2,3 +2,5 @@
    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/vala/vapi/gplugin-gtk.deps
    +debian/tmp/usr/share/vala/vapi/gplugin-gtk.vapi
    --- a/packaging/gplugin.spec.in Tue Jan 22 22:58:59 2019 -0600
    +++ b/packaging/gplugin.spec.in Mon Sep 30 01:28:39 2019 -0500
    @@ -22,6 +22,7 @@
    BuildRequires: lua-lgi
    BuildRequires: python3-devel
    BuildRequires: python3-gobject
    +BuildRequires: vala
    BuildRequires: /usr/lib64/pkgconfig/pygobject-3.0.pc
    %package -n libgplugin0
    @@ -43,6 +44,12 @@
    Requires: %{name}-gtk3%{?_isa} = %{version}-%{release}
    Requires: %{name}-devel%{?_isa} = %{version}-%{release}
    +%package gtk3-vala
    +Summary: A GObject based library that implements a reusable plugin system
    +Group: Development/Libraries
    +Requires: %{name}-gtk3%{?_isa} = %{version}-%{release}
    +Requires: %{name}-devel%{?_isa} = %{version}-%{release}
    +
    %package lua
    Summary: A GObject based library that implements a reusable plugin system
    Group: Development/Libraries
    @@ -51,6 +58,10 @@
    Summary: A GObject based library that implements a reusable plugin system
    Group: Development/Libraries
    +%package vala
    +Summary: A GObject based library that implements a reusable plugin system
    +Group: Development/Libraries
    +Requires: %{name}-devel%{?_isa} = %{version}-%{release}
    %description
    GPlugin is a GObject based library that implements a reusable plugin system
    @@ -110,6 +121,19 @@
    This package contains all necessary include files and libraries needed
    to develop GTK3 applications that require these.
    +%description gtk3-vala
    +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 the vapi bindings allowing GPluginGtk to be used from
    +vala.
    +
    %description lua
    GPlugin is a GObject based library that implements a reusable plugin system
    that supports loading plugins in other languages via loaders. GPlugin also
    @@ -134,24 +158,29 @@
    This package contains Python 3 loader for %{name} library.
    +%description vala
    +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 the vapi bindings allowing GPlugin to be used from vala.
    %build
    -mkdir -p build
    -pushd build
    -
    CFLAGS="%{optflags}" meson \
    --prefix=%{_prefix} \
    -Dlua=true \
    -Dpython=true \
    - ..
    + build
    -ninja %{?_smp_mflags}
    -
    +ninja -C build %{?_smp_mflags}
    %install
    -pushd build
    -
    -DESTDIR=%{buildroot} ninja install
    +DESTDIR=%{buildroot} ninja -C build install
    # Unneeded files
    rm -rf %{buildroot}%{_datadir}/doc/gplugin/
    @@ -164,10 +193,9 @@
    %postun -n gplugin-gtk3 -p /sbin/ldconfig
    -
    %files
    %defattr(-,root,root)
    -%doc README ChangeLog
    +%doc README.md ChangeLog
    %{_bindir}/gplugin-query
    %{_libdir}/gplugin/
    %{_mandir}/man1/gplugin-query.1*
    @@ -178,49 +206,63 @@
    %files devel
    %defattr(-,root,root)
    -%doc HACKING INSTALL README
    +%doc HACKING README.md
    +%{_datadir}/gir-1.0/GPlugin-0.0.gir
    +%{_datadir}/gtk-doc/html/gplugin/
    %{_includedir}/gplugin-1.0/
    +%{_libdir}/girepository-1.0/GPlugin-0.0.typelib
    %{_libdir}/libgplugin.so
    %{_libdir}/libgplugin.so.0
    +%{_libdir}/pkgconfig/gplugin-gtk.pc
    %{_libdir}/pkgconfig/gplugin.pc
    -%{_libdir}/pkgconfig/gplugin-gtk.pc
    -%{_libdir}/girepository-1.0/GPlugin-0.0.typelib
    -%{_datadir}/gtk-doc/html/gplugin/
    -%{_datadir}/gir-1.0/GPlugin-0.0.gir
    %files gtk3
    %defattr(-,root,root)
    -%doc README
    +%doc README.md
    %{_bindir}/gplugin-gtk-viewer
    %{_libdir}/libgplugin-gtk.so.0.1.0
    %{_mandir}/man1/gplugin-gtk-viewer.1*
    %files gtk3-devel
    %defattr(-,root,root)
    -%doc README
    -%{_libdir}/libgplugin-gtk.so
    -%{_libdir}/libgplugin-gtk.so.0
    -%{_libdir}/girepository-1.0/GPluginGtk-0.0.typelib
    +%dir %{_datadir}/glade/catalogs/
    +%doc README.md
    %{_datadir}/gir-1.0/GPluginGtk-0.0.gir
    %{_datadir}/glade/catalogs/gplugin-gtk.xml
    %{_datadir}/gtk-doc/html/gplugin-gtk/
    %{_libdir}/girepository-1.0/GPluginGtk-0.0.typelib
    -%{_datadir}/gir-1.0/GPluginGtk-0.0.gir
    -%{_datadir}/glade/catalogs/
    +%{_libdir}/libgplugin-gtk.so
    +%{_libdir}/libgplugin-gtk.so.0
    %files lua
    %defattr(-,root,root)
    -%doc README
    +%doc README.md
    %license COPYING
    %{_libdir}/gplugin/gplugin-lua.so
    %files python3
    %defattr(-,root,root)
    -%doc README
    +%doc README.md
    %{_libdir}/gplugin/gplugin-python.so
    +%files vala
    +%defattr(-,root,root)
    +%doc README.md
    +%license COPYING
    +%{_datadir}/vala/vapi/gplugin.vapi
    +%{_datadir}/vala/vapi/gplugin.deps
    +
    +%files gtk3-vala
    +%defattr(-,root,root)
    +%doc README.md
    +%license COPYING
    +%{_datadir}/vala/vapi/gplugin-gtk.vapi
    +%{_datadir}/vala/vapi/gplugin-gtk.deps
    %changelog
    +* Mon Aug 12 2019 Gary Kramlich <grim@reaperworld.com>
    +- Added vala
    +
    * Sun May 15 2016 Gary Kramlich <grim@reaperworld.com>
    - Updates and pulled upstream
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/packaging/mingw-cross/PKGBUILD Mon Sep 30 01:28:39 2019 -0500
    @@ -0,0 +1,46 @@
    +_realname=gplugin
    +pkgbase=mingw-w64-${_realname}-hg
    +pkgname="${MINGW_PACKAGE_PREFIX}-${_realname}-hg"
    +provides=(${MINGW_PACKAGE_PREFIX}-${_realname})
    +conflicts=(${MINGW_PACKAGE_PREFIX}-${_realname})
    +pkgver=hg
    +pkgrel=1
    +pkgdesc="GObject based plugin library"
    +arch=('any')
    +url="https://bitbucket.org/gplugin/gplugin/"
    +license=('LGPL2+')
    +makedepends=("${MINGW_PACKAGE_PREFIX}-pkg-config")
    +depends=("${MINGW_PACKAGE_PREFIX}-glib2"
    + "${MINGW_PACKAGE_PREFIX}-gtk3")
    +
    +options=(!libtool strip staticlibs)
    +
    +pkgver() {
    + printf "r%s.%s" "$(hg identify -n)" "$(hg identify -i)"
    +}
    +
    +build() {
    + meson \
    + --buildtype plain \
    + --prefix=/${MINGW_PACKAGE_PREFIX} \
    + --cross-file=${MINGW_PACKAGE_PREFIX}.txt \
    + -Ddoc=false\
    + -Dlua=false \
    + -Dpython=false \
    + -Dgobject-introspection=false \
    + -Dvapi=false \
    + -Dhelp2man=false \
    + ../
    +
    + ninja
    +}
    +
    +package() {
    + DESTDIR="${pkgdir}" ninja install
    +
    + set -x
    + install -Dm644 "../COPYING" "${pkgdir}/${MINGW_PACKAGE_PREFIX}/share/licenses/${_realname}/COPYING"
    + set +x
    +}
    +
    +
    --- a/perl/gplugin-perl-core.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/perl/gplugin-perl-core.c Mon Sep 30 01:28:39 2019 -0500
    @@ -49,9 +49,9 @@
    G_MODULE_EXPORT gboolean
    gplugin_load(GPluginNativePlugin *plugin, GError **error) {
    gplugin_perl_plugin_register(plugin);
    - gplugin_perl_plugin_loader_register(plugin);
    + gplugin_perl_loader_register(plugin);
    - gplugin_manager_register_loader(GPLUGIN_TYPE_PERL_PLUGIN_LOADER);
    + gplugin_manager_register_loader(GPLUGIN_PERL_TYPE_LOADER);
    return TRUE;
    }
    --- a/perl/gplugin-perl-loader.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/perl/gplugin-perl-loader.c Mon Sep 30 01:28:39 2019 -0500
    @@ -26,11 +26,11 @@
    #undef _
    #include <glib/gi18n.h>
    -/******************************************************************************
    - * Globals
    - *****************************************************************************/
    -static GObjectClass *parent_class = NULL;
    -static volatile GType type_real = 0;
    +struct _GPluginPerlLoader {
    + GPluginLoader parent;
    +};
    +
    +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;
    @@ -102,14 +102,16 @@
    }
    /******************************************************************************
    - * Object Stuff
    + * GObject Stuff
    *****************************************************************************/
    static void
    +gplugin_perl_loader_init(G_GNUC_UNUSED GPluginPerlLoader *loader) {
    +}
    +
    +static void
    gplugin_perl_loader_class_init(GPluginPerlLoaderClass *klass) {
    GPluginLoaderClass *loader_class = GPLUGIN_LOADER_CLASS(klass);
    - parent_class = g_type_class_peek_parent(klass);
    -
    loader_class->supported_extensions =
    gplugin_perl_loader_class_supported_extensions;
    loader_class->query = gplugin_perl_loader_query;
    @@ -121,8 +123,7 @@
    }
    static void
    -gplugin_perl_loader_class_finalize(GPluginPerlLoaderClass *klass,
    - gpointer class_data)
    +gplugin_perl_loader_class_finalize(G_GNUC_UNUSED GPluginPerlLoaderClass *klass)
    {
    /* perl uninitialization */
    gplugin_perl_loader_uninit_perl();
    @@ -132,34 +133,6 @@
    * API
    *****************************************************************************/
    void
    -gplugin_perl_plugin_loader_register(GPluginNativePlugin *plugin) {
    - if(g_once_init_enter(&type_real)) {
    - GType type = 0;
    -
    - static const GTypeInfo info = {
    - .class_size = sizeof(GPluginPerlLoaderClass),
    - .class_init = (GClassInitFunc)gplugin_perl_loader_class_init,
    - .class_finalize = (GClassFinalizeFunc)gplugin_perl_loader_class_finalize,
    - .instance_size = sizeof(GPluginPerlLoader),
    - };
    -
    - type = gplugin_native_plugin_register_type(plugin,
    - GPLUGIN_TYPE_LOADER,
    - "GPluginPerlLoader",
    - &info,
    - 0);
    -
    - g_once_init_leave(&type_real, type);
    - }
    +gplugin_perl_loader_register(GPluginNativePlugin *plugin) {
    + gplugin_perl_loader_register_type(G_TYPE_MODULE(plugin));
    }
    -
    -GType
    -gplugin_perl_plugin_loader_get_type(void) {
    - if(G_UNLIKELY(type_real == 0)) {
    - g_warning("gplugin_perl_loader_get_type was called before "
    - "the type was registered!\n");
    - }
    -
    - return type_real;
    -}
    -
    --- a/perl/gplugin-perl-loader.h Tue Jan 22 22:58:59 2019 -0600
    +++ b/perl/gplugin-perl-loader.h Mon Sep 30 01:28:39 2019 -0500
    @@ -15,44 +15,18 @@
    * License along with this library; if not, see <http://www.gnu.org/licenses/>.
    */
    -#ifndef GPLUGIN_PERL_PLUGIN_LOADER_H
    -#define GPLUGIN_PERL_PLUGIN_LOADER_H
    -
    -#define GPLUGIN_TYPE_PERL_PLUGIN_LOADER (gplugin_perl_plugin_loader_get_type())
    -#define GPLUGIN_PERL_PLUGIN_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GPLUGIN_TYPE_PERL_PLUGIN_LOADER, GPluginPerlLoader))
    -#define GPLUGIN_PERL_PLUGIN_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((obj), GPLUGIN_TYPE_PERL_PLUGIN_LOADER, GPluginPerlLoaderClass))
    -#define GPLUGIN_IS_PERL_PLUGIN_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GPLUGIN_TYPE_PERL_PLUGIN_LOADER))
    -#define GPLUGIN_IS_PERL_PLUGIN_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((obj), GPLUGIN_TYPE_PERL_PLUGIN_LOADER))
    -#define GPLUGIN_PERL_PLUGIN_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GPLUGIN_TYPE_PERL_PLUGIN_LOADER, GPluginPerlLoaderClass))
    -
    -typedef struct _GPluginPerlLoader GPluginPerlLoader;
    -typedef struct _GPluginPerlLoaderClass GPluginPerlLoaderClass;
    +#ifndef GPLUGIN_PERL_LOADER_H
    +#define GPLUGIN_PERL_LOADER_H
    #include <gplugin.h>
    #include <gplugin-native.h>
    -struct _GPluginPerlLoader {
    - GPluginLoader parent;
    -
    - void (*_gplugin_reserved_1)(void);
    - void (*_gplugin_reserved_2)(void);
    - void (*_gplugin_reserved_3)(void);
    - void (*_gplugin_reserved_4)(void);
    -};
    -
    -struct _GPluginPerlLoaderClass {
    - GPluginLoaderClass parent;
    -
    - void (*_gplugin_reserved_1)(void);
    - void (*_gplugin_reserved_2)(void);
    - void (*_gplugin_reserved_3)(void);
    - void (*_gplugin_reserved_4)(void);
    -};
    -
    G_BEGIN_DECLS
    -void gplugin_perl_plugin_loader_register(GPluginNativePlugin *plugin);
    -GType gplugin_perl_plugin_loader_get_type(void);
    +#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);
    G_END_DECLS
    --- a/perl/gplugin-perl-plugin.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/perl/gplugin-perl-plugin.c Mon Sep 30 01:28:39 2019 -0500
    @@ -26,15 +26,20 @@
    #undef _
    #include <glib/gi18n.h>
    -#define GPLUGIN_PERL_PLUGIN_GET_PRIVATE(obj) \
    - (G_TYPE_INSTANCE_GET_PRIVATE((obj), GPLUGIN_TYPE_PERL_PLUGIN, GPluginPerlPluginPrivate))
    -
    /******************************************************************************
    * Typedefs
    *****************************************************************************/
    -typedef struct {
    +struct _GPluginPerlPlugin {
    + GObject parent;
    +
    PerlInterpreter *interpreter;
    -} GPluginPerlPluginPrivate;
    +
    + /* overrides */
    + gchar *filename;
    + GPluginLoader *loader;
    + GPluginPluginInfo *info;
    + GPluginPluginState state;
    +};
    /******************************************************************************
    * Enums
    @@ -43,22 +48,31 @@
    PROP_ZERO,
    PROP_INTERPRETER,
    N_PROPERTIES,
    + /* overrides */
    + PROP_FILENAME = N_PROPERTIES,
    + PROP_LOADER,
    + PROP_INFO,
    + PROP_STATE
    };
    static GParamSpec *properties[N_PROPERTIES] = {NULL,};
    -static GObjectClass *parent_class = NULL;
    -static volatile GType type_real = 0;
    +/* I hate forward declarations... */
    +static void gplugin_perl_plugin_iface_init(GPluginPluginInterface *iface);
    +
    +G_DEFINE_DYNAMIC_TYPE_EXTENDED(
    + GPluginPerlPlugin,
    + gplugin_perl_plugin,
    + G_TYPE_OBJECT,
    + 0,
    + G_IMPLEMENT_INTERFACE(GPLUGIN_TYPE_PLUGIN, gplugin_perl_plugin_iface_init)
    +);
    /******************************************************************************
    - * Private Stuff
    + * GPluginPlugin Implementation
    *****************************************************************************/
    static void
    -gplugin_perl_plugin_set_interpreter(GPluginPerlPlugin *plugin,
    - PerlInterpreter *interpreter)
    +gplugin_perl_plugin_iface_init(G_GNUC_UNUSED GPluginPluginInterface *iface)
    {
    - GPluginPerlPluginPrivate *priv = GPLUGIN_PERL_PLUGIN_GET_PRIVATE(plugin);
    -
    - priv->interpreter = interpreter;
    }
    /******************************************************************************
    @@ -75,6 +89,21 @@
    g_value_set_pointer(value,
    gplugin_perl_plugin_get_interpreter(plugin));
    break;
    +
    + /* overrides */
    + case PROP_FILENAME:
    + g_value_set_string(value, plugin->filename);
    + break;
    + case PROP_LOADER:
    + g_value_set_object(value, plugin->loader);
    + break;
    + case PROP_INFO:
    + g_value_set_object(value, plugin->info);
    + break;
    + case PROP_STATE:
    + g_value_set_enum(value, plugin->state);
    + break;
    +
    default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
    break;
    @@ -89,9 +118,23 @@
    switch(param_id) {
    case PROP_INTERPRETER:
    - gplugin_perl_plugin_set_interpreter(plugin,
    - g_value_get_pointer(value));
    + plugin->interpreter = g_value_get_pointer(value);
    + break;
    +
    + /* overrides */
    + case PROP_FILENAME:
    + plugin->filename = g_value_dup_string(value);
    break;
    + case PROP_LOADER:
    + plugin->loader = g_value_dup_object(value);
    + break;
    + case PROP_INFO:
    + plugin->info = g_value_dup_object(value);
    + break;
    + case PROP_STATE:
    + plugin->state = g_value_get_enum(value);
    + break;
    +
    default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
    }
    @@ -99,23 +142,33 @@
    static void
    gplugin_perl_plugin_finalize(GObject *obj) {
    - GPluginPerlPluginPrivate *priv = GPLUGIN_PERL_PLUGIN_GET_PRIVATE(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);
    - perl_destruct(priv->interpreter);
    - perl_free(priv->interpreter);
    - priv->interpreter = NULL;
    + G_OBJECT_CLASS(gplugin_perl_plugin_parent_class)->finalize(obj);
    +}
    - G_OBJECT_CLASS(parent_class)->finalize(obj);
    +static void
    +gplugin_perl_plugin_init(G_GNUC_UNUSED GPluginPerlPlugin *plugin)
    +{
    +}
    +
    +static void
    +gplugin_perl_plugin_class_finalize(G_GNUC_UNUSED GPluginPerlPluginClass *klass)
    +{
    }
    static void
    gplugin_perl_plugin_class_init(GPluginPerlPluginClass *klass) {
    GObjectClass *obj_class = G_OBJECT_CLASS(klass);
    - parent_class = g_type_class_peek_parent(klass);
    -
    - g_type_class_add_private(klass, sizeof(GPluginPerlPluginPrivate));
    -
    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;
    @@ -127,50 +180,26 @@
    );
    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");
    }
    /******************************************************************************
    * API
    *****************************************************************************/
    void
    -gplugin_perl_plugin_register(GPluginNativePlugin *plugin) {
    - if(g_once_init_enter(&type_real)) {
    - GType type = 0;
    -
    - static const GTypeInfo info = {
    - .class_size = sizeof(GPluginPerlPluginClass),
    - .class_init = (GClassInitFunc)gplugin_perl_plugin_class_init,
    - .instance_size = sizeof(GPluginPerlPlugin),
    - };
    -
    - type = gplugin_native_plugin_register_type(plugin,
    - GPLUGIN_TYPE_PLUGIN,
    - "GPluginPerlPlugin",
    - &info,
    - 0);
    -
    - g_once_init_leave(&type_real, type);
    - }
    -}
    -
    -GType
    -gplugin_perl_plugin_get_type(void) {
    - if(G_UNLIKELY(type_real == 0)) {
    - g_warning("gplugin_perl_plugin_get_type was called before "
    - "the type was registered!\n");
    - }
    -
    - return type_real;
    +gplugin_perl_plugin_register(GPluginNativePlugin *native)
    +{
    + gplugin_perl_plugin_register_type(G_TYPE_MODULE(native));
    }
    PerlInterpreter *
    -gplugin_perl_plugin_get_interpreter(const GPluginPerlPlugin *plugin) {
    - GPluginPerlPluginPrivate *priv = NULL;
    -
    - g_return_val_if_fail(GPLUGIN_IS_PERL_PLUGIN(plugin), NULL);
    +gplugin_perl_plugin_get_interpreter(GPluginPerlPlugin *plugin) {
    + g_return_val_if_fail(GPLUGIN_PERL_IS_PLUGIN(plugin), NULL);
    - priv = GPLUGIN_PERL_PLUGIN_GET_PRIVATE(plugin);
    -
    - return priv->interpreter;
    + return plugin->interpreter;
    }
    -
    --- a/perl/gplugin-perl-plugin.h Tue Jan 22 22:58:59 2019 -0600
    +++ b/perl/gplugin-perl-plugin.h Mon Sep 30 01:28:39 2019 -0500
    @@ -18,16 +18,6 @@
    #ifndef GPLUGIN_PERL_PLUGIN_H
    #define GPLUGIN_PERL_PLUGIN_H
    -#define GPLUGIN_TYPE_PERL_PLUGIN (gplugin_perl_plugin_get_type())
    -#define GPLUGIN_PERL_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GPLUGIN_TYPE_PERL_PLUGIN, GPluginPerlPlugin))
    -#define GPLUGIN_PERL_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((obj), GPLUGIN_TYPE_PERL_PLUGIN, GPluginPerlPluginClass))
    -#define GPLUGIN_IS_PERL_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GPLUGIN_TYPE_PERL_PLUGIN))
    -#define GPLUGIN_IS_PERL_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((obj), GPLUGIN_TYPE_PERL_PLUGIN))
    -#define GPLUGIN_PERL_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GPLUGIN_TYPE_PERL_PLUGIN, GPluginPerlPluginClass))
    -
    -typedef struct _GPluginPerlPlugin GPluginPerlPlugin;
    -typedef struct _GPluginPerlPluginClass GPluginPerlPluginClass;
    -
    #include <gplugin.h>
    #include <gplugin-native.h>
    @@ -35,30 +25,14 @@
    #include <perl.h>
    #undef _
    -struct _GPluginPerlPlugin {
    - GPluginPlugin parent;
    -
    - void (*_gplugin_reserved_1)(void);
    - void (*_gplugin_reserved_2)(void);
    - void (*_gplugin_reserved_3)(void);
    - void (*_gplugin_reserved_4)(void);
    -};
    -
    -struct _GPluginPerlPluginClass {
    - GPluginPluginClass parent;
    -
    - void (*_gplugin_reserved_1)(void);
    - void (*_gplugin_reserved_2)(void);
    - void (*_gplugin_reserved_3)(void);
    - void (*_gplugin_reserved_4)(void);
    -};
    -
    G_BEGIN_DECLS
    -void gplugin_perl_plugin_register(GPluginNativePlugin *plugin);
    -GType gplugin_perl_plugin_get_type(void);
    +#define GPLUGIN_PERL_TYPE_PLUGIN (gplugin_perl_plugin_get_type())
    +G_DECLARE_FINAL_TYPE(GPluginPerlPlugin, gplugin_perl_plugin, GPLUGIN_PERL, PLUGIN, GObject)
    -PerlInterpreter *gplugin_perl_plugin_get_interpreter(const GPluginPerlPlugin *plugin);
    +void gplugin_perl_plugin_register(GPluginNativePlugin *native);
    +
    +PerlInterpreter *gplugin_perl_plugin_get_interpreter(GPluginPerlPlugin *plugin);
    G_END_DECLS
    --- a/plugins/gplugin-license-check.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/plugins/gplugin-license-check.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,7 +19,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    const gchar * const authors[] = {
    "Gary Kramlich <grim@reaperworld.com>",
    NULL
    @@ -38,15 +38,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/po/POTFILES Mon Sep 30 01:28:39 2019 -0500
    @@ -0,0 +1,36 @@
    +gplugin-gtk-viewer/data/window.ui
    +gplugin-gtk-viewer/gplugin-gtk-viewer-window.c
    +gplugin-gtk-viewer/gplugin-gtk-viewer.c
    +gplugin-gtk/data/plugin-info.ui
    +gplugin-gtk/gplugin-gtk-plugin-info.c
    +gplugin-gtk/gplugin-gtk-store.c
    +gplugin-gtk/gplugin-gtk-view.c
    +gplugin/gplugin-core.c
    +gplugin/gplugin-file-tree.c
    +gplugin/gplugin-loader.c
    +gplugin/gplugin-manager.c
    +gplugin/gplugin-native-loader.c
    +gplugin/gplugin-native-plugin.c
    +gplugin/gplugin-options.c
    +gplugin/gplugin-plugin-info.c
    +gplugin/gplugin-plugin.c
    +gplugin/gplugin-private.c
    +gplugin/gplugin-query.c
    +gplugin/gplugin-version.c
    +lua/gplugin-lua-core.c
    +lua/gplugin-lua-loader.c
    +lua/gplugin-lua-plugin.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
    +tcc/gplugin-tcc-core.c
    +tcc/gplugin-tcc-loader.c
    +tcc/gplugin-tcc-plugin.c
    --- a/po/meson.build Tue Jan 22 22:58:59 2019 -0600
    +++ b/po/meson.build Mon Sep 30 01:28:39 2019 -0500
    @@ -1,3 +1,3 @@
    if get_option('nls')
    -# GETTEXTIZE_TRANSLATIONS(UPDATE)
    + i18n.gettext(GETTEXT_PACKAGE)
    endif
    --- a/python/gplugin-python-core.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/python/gplugin-python-core.c Mon Sep 30 01:28:39 2019 -0500
    @@ -22,7 +22,7 @@
    #include "gplugin-python-plugin.h"
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    const gchar * const authors[] = {
    "Gary Kramlich <grim@reaperworld.com>",
    NULL
    @@ -48,19 +48,19 @@
    G_MODULE_EXPORT gboolean
    gplugin_load(GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    + G_GNUC_UNUSED GError **error)
    {
    gplugin_python_plugin_register(plugin);
    gplugin_python_loader_register(plugin);
    - gplugin_manager_register_loader(GPLUGIN_TYPE_PYTHON_LOADER);
    + gplugin_manager_register_loader(GPLUGIN_PYTHON_TYPE_LOADER);
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return FALSE;
    }
    --- a/python/gplugin-python-loader.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/python/gplugin-python-loader.c Mon Sep 30 01:28:39 2019 -0500
    @@ -15,9 +15,9 @@
    * License along with this library; if not, see <http://www.gnu.org/licenses/>.
    */
    -#include <stdlib.h>
    +#include <Python.h>
    -#include <Python.h>
    +#include <stdlib.h>
    #include "gplugin-python-loader.h"
    @@ -28,31 +28,27 @@
    #include <pygobject.h>
    -typedef struct {
    +struct _GPluginPythonLoader {
    + GPluginLoader parent;
    +
    PyThreadState *py_thread_state;
    guint gc_id;
    -} GPluginPythonLoaderPrivate;
    +};
    -G_DEFINE_DYNAMIC_TYPE_EXTENDED(
    - GPluginPythonLoader,
    - gplugin_python_loader,
    - GPLUGIN_TYPE_LOADER,
    - 0,
    - G_ADD_PRIVATE_DYNAMIC(GPluginPythonLoader)
    -);
    +G_DEFINE_DYNAMIC_TYPE(GPluginPythonLoader, gplugin_python_loader, GPLUGIN_TYPE_LOADER);
    /******************************************************************************
    * GPluginLoader Implementation
    *****************************************************************************/
    static GSList *
    -gplugin_python_loader_class_supported_extensions(GPLUGIN_UNUSED const GPluginLoaderClass *klass) {
    +gplugin_python_loader_class_supported_extensions(G_GNUC_UNUSED GPluginLoaderClass *klass) {
    return g_slist_append(NULL, "py");
    }
    static GPluginPlugin *
    -gplugin_python_loader_query(GPLUGIN_UNUSED GPluginLoader *loader,
    +gplugin_python_loader_query(GPluginLoader *loader,
    const gchar *filename,
    - GPLUGIN_UNUSED GError **error)
    + G_GNUC_UNUSED GError **error)
    {
    GPluginPlugin *plugin = NULL;
    GObject *info = NULL;
    @@ -82,6 +78,10 @@
    g_warning(_("Failed to query %s"), filename);
    PyErr_Print();
    + /* clean some stuff up */
    + g_free(module_name);
    + Py_DECREF(package_list);
    +
    pyg_gil_state_release(state);
    return NULL;
    @@ -101,6 +101,7 @@
    g_warning(_("Failed to find the gplugin_query function in %s"),
    filename);
    + Py_DECREF(module);
    pyg_gil_state_release(state);
    return NULL;
    @@ -110,6 +111,7 @@
    "function"),
    filename);
    + Py_DECREF(module);
    pyg_gil_state_release(state);
    return NULL;
    @@ -120,6 +122,7 @@
    g_warning(_("Failed to find the gplugin_load function in %s"),
    filename);
    + Py_DECREF(module);
    pyg_gil_state_release(state);
    return NULL;
    @@ -129,6 +132,7 @@
    "function"),
    filename);
    + Py_DECREF(module);
    pyg_gil_state_release(state);
    return NULL;
    @@ -139,6 +143,7 @@
    g_warning(_("Failed to find the gplugin_unload function in %s"),
    filename);
    + Py_DECREF(module);
    pyg_gil_state_release(state);
    return NULL;
    @@ -148,6 +153,7 @@
    "function"),
    filename);
    + Py_DECREF(module);
    pyg_gil_state_release(state);
    return NULL;
    @@ -163,7 +169,7 @@
    info = pygobject_get(pyinfo);
    /* now that we have everything, create the plugin */
    - plugin = g_object_new(GPLUGIN_TYPE_PYTHON_PLUGIN,
    + plugin = g_object_new(GPLUGIN_PYTHON_TYPE_PLUGIN,
    "filename", filename,
    "loader", loader,
    "module", module,
    @@ -172,6 +178,9 @@
    "unload-func", unload,
    NULL);
    + Py_DECREF(pyinfo);
    + Py_DECREF(module);
    +
    /* unlock the gil */
    pyg_gil_state_release(state);
    @@ -179,7 +188,7 @@
    }
    static gboolean
    -gplugin_python_loader_load(GPLUGIN_UNUSED GPluginLoader *loader,
    +gplugin_python_loader_load(G_GNUC_UNUSED GPluginLoader *loader,
    GPluginPlugin *plugin,
    GError **error)
    {
    @@ -193,27 +202,29 @@
    result = PyObject_CallFunctionObjArgs(load, pyplugin, NULL);
    Py_DECREF(pyplugin);
    - if(error) {
    - *error = gplugin_python_exception_to_gerror();
    - if(*error)
    - return FALSE;
    + if (PyErr_Occurred()) {
    + Py_XDECREF(result);
    +
    + if (error) {
    + *error = gplugin_python_exception_to_gerror();
    + }
    +
    + return FALSE;
    }
    ret = PyObject_IsTrue(result);
    Py_DECREF(result);
    if(!ret) {
    - if(error) {
    - *error = g_error_new(GPLUGIN_DOMAIN, 0,
    - _("Failed to load plugin"));
    - }
    + g_set_error_literal(error, GPLUGIN_DOMAIN, 0,
    + _("Failed to load plugin"));
    }
    return ret;
    }
    static gboolean
    -gplugin_python_loader_unload(GPLUGIN_UNUSED GPluginLoader *loader,
    +gplugin_python_loader_unload(G_GNUC_UNUSED GPluginLoader *loader,
    GPluginPlugin *plugin,
    GError **error)
    {
    @@ -230,7 +241,7 @@
    if(PyErr_Occurred()) {
    PyErr_Print();
    - Py_DECREF(result);
    + Py_XDECREF(result);
    return FALSE;
    }
    @@ -239,10 +250,8 @@
    Py_DECREF(result);
    if(!ret) {
    - if(error) {
    - *error = g_error_new(GPLUGIN_DOMAIN, 0,
    - _("Failed to unload plugin"));
    - }
    + g_set_error_literal(error, GPLUGIN_DOMAIN, 0,
    + _("Failed to unload plugin"));
    }
    return ret;
    @@ -259,6 +268,7 @@
    PyErr_Fetch(&type, &value, &tb);
    Py_DECREF(type);
    + Py_XDECREF(tb);
    obj = PyUnicode_AsUTF8String(value);
    Py_DECREF(value);
    @@ -281,7 +291,7 @@
    static gboolean
    gplugin_python_loader_init_gettext(void) {
    PyObject *module_dict = NULL, *install = NULL;
    - PyObject *gettext = NULL, *gettext_args = NULL;
    + PyObject *gettext = NULL, *result = NULL;
    gettext = PyImport_ImportModule("gettext");
    if(gettext == NULL) {
    @@ -292,9 +302,9 @@
    module_dict = PyModule_GetDict(gettext);
    install = PyDict_GetItemString(module_dict, "install");
    - gettext_args = Py_BuildValue("ss", GETTEXT_PACKAGE, LOCALEDIR);
    - PyObject_CallObject(install, gettext_args);
    - Py_DECREF(gettext_args);
    + result = PyObject_CallFunction(install, "ss", GETTEXT_PACKAGE, LOCALEDIR);
    + Py_XDECREF(result);
    + Py_DECREF(gettext);
    return TRUE;
    }
    @@ -353,11 +363,12 @@
    * Object Stuff
    *****************************************************************************/
    static void
    -gplugin_python_loader_init(GPluginPythonLoader *loader) {
    +gplugin_python_loader_init(G_GNUC_UNUSED GPluginPythonLoader *loader) {
    }
    static void
    -gplugin_python_loader_class_finalize(GPluginPythonLoaderClass *klass) {
    +gplugin_python_loader_class_finalize(G_GNUC_UNUSED GPluginPythonLoaderClass *klass)
    +{
    }
    static void
    --- a/python/gplugin-python-loader.h Tue Jan 22 22:58:59 2019 -0600
    +++ b/python/gplugin-python-loader.h Mon Sep 30 01:28:39 2019 -0500
    @@ -18,37 +18,15 @@
    #ifndef GPLUGIN_PYTHON_LOADER_H
    #define GPLUGIN_PYTHON_LOADER_H
    -#define GPLUGIN_TYPE_PYTHON_LOADER (gplugin_python_loader_get_type())
    -#define GPLUGIN_PYTHON_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GPLUGIN_TYPE_PYTHON_LOADER, GPluginPythonLoader))
    -#define GPLUGIN_PYTHON_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((obj), GPLUGIN_TYPE_PYTHON_LOADER, GPluginPythonLoaderClass))
    -#define GPLUGIN_IS_PYTHON_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GPLUGIN_TYPE_PYTHON_LOADER))
    -#define GPLUGIN_IS_PYTHON_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((obj), GPLUGIN_TYPE_PYTHON_LOADER))
    -#define GPLUGIN_PYTHON_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GPLUGIN_TYPE_PYTHON_LOADER, GPluginPythonLoaderClass))
    -
    -typedef struct _GPluginPythonLoader GPluginPythonLoader;
    -typedef struct _GPluginPythonLoaderClass GPluginPythonLoaderClass;
    -
    #include <gplugin.h>
    #include <gplugin-native.h>
    -struct _GPluginPythonLoader {
    - /*< private >*/
    - GPluginLoader parent;
    -
    - gpointer reserved[4];
    -};
    -
    -struct _GPluginPythonLoaderClass {
    - /*< private >*/
    - GPluginLoaderClass parent;
    -
    - gpointer reserved[4];
    -};
    -
    G_BEGIN_DECLS
    +#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);
    -GType gplugin_python_loader_get_type(void);
    G_END_DECLS
    --- a/python/gplugin-python-plugin.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/python/gplugin-python-plugin.c Mon Sep 30 01:28:39 2019 -0500
    @@ -24,7 +24,9 @@
    /******************************************************************************
    * Typedefs
    *****************************************************************************/
    -typedef struct {
    +struct _GPluginPythonPlugin {
    + GObject parent;
    +
    PyObject *module;
    PyObject *query;
    PyObject *load;
    @@ -35,7 +37,7 @@
    GPluginLoader *loader;
    GPluginPluginInfo *info;
    GPluginPluginState state;
    -} GPluginPythonPluginPrivate;
    +};
    /******************************************************************************
    * Enums
    @@ -62,7 +64,6 @@
    gplugin_python_plugin,
    G_TYPE_OBJECT,
    0,
    - G_ADD_PRIVATE_DYNAMIC(GPluginPythonPlugin)
    G_IMPLEMENT_INTERFACE(GPLUGIN_TYPE_PLUGIN, gplugin_python_plugin_iface_init)
    );
    @@ -70,101 +71,60 @@
    * GPluginPlugin Implementation
    *****************************************************************************/
    static void
    -gplugin_python_plugin_iface_init(GPluginPluginInterface *iface) {
    +gplugin_python_plugin_iface_init(G_GNUC_UNUSED GPluginPluginInterface *iface) {
    }
    /******************************************************************************
    * Private Stuff
    *****************************************************************************/
    -static PyObject *
    -gplugin_python_plugin_get_module(GPluginPythonPlugin *plugin) {
    - GPluginPythonPluginPrivate *priv = NULL;
    -
    - g_return_val_if_fail(GPLUGIN_IS_PYTHON_PLUGIN(plugin), NULL);
    -
    - priv = gplugin_python_plugin_get_instance_private(plugin);
    -
    - return priv->module;
    -}
    -
    static void
    gplugin_python_plugin_set_module(GPluginPythonPlugin *plugin,
    PyObject *module)
    {
    - GPluginPythonPluginPrivate *priv = NULL;
    -
    g_return_if_fail(GPLUGIN_IS_PLUGIN(plugin));
    g_return_if_fail(module);
    - priv = gplugin_python_plugin_get_instance_private(plugin);
    -
    - if(priv->module)
    - Py_DECREF(priv->module);
    -
    - priv->module = module;
    -
    - if(priv->module)
    - Py_INCREF(priv->module);
    + Py_XINCREF(module);
    + Py_CLEAR(plugin->module);
    + plugin->module = module;
    }
    static gpointer
    gplugin_python_plugin_get_load_func(GPluginPythonPlugin *plugin) {
    - GPluginPythonPluginPrivate *priv = NULL;
    -
    - g_return_val_if_fail(GPLUGIN_IS_PYTHON_PLUGIN(plugin), NULL);
    + g_return_val_if_fail(GPLUGIN_PYTHON_IS_PLUGIN(plugin), NULL);
    - priv = gplugin_python_plugin_get_instance_private(plugin);
    -
    - return priv->load;
    + return plugin->load;
    }
    static void
    gplugin_python_plugin_set_load_func(GPluginPythonPlugin *plugin,
    PyObject *func)
    {
    - GPluginPythonPluginPrivate *priv = NULL;
    -
    - g_return_if_fail(GPLUGIN_IS_PYTHON_PLUGIN(plugin));
    + g_return_if_fail(GPLUGIN_PYTHON_IS_PLUGIN(plugin));
    g_return_if_fail(func != NULL);
    - priv = gplugin_python_plugin_get_instance_private(plugin);
    -
    - if(priv->load)
    - Py_DECREF(priv->load);
    -
    - priv->load = func;
    - if(priv->load)
    - Py_INCREF(priv->load);
    + Py_XINCREF(func);
    + Py_CLEAR(plugin->load);
    + plugin->load = func;
    }
    static gpointer
    gplugin_python_plugin_get_unload_func(GPluginPythonPlugin *plugin) {
    - GPluginPythonPluginPrivate *priv = NULL;
    -
    - g_return_val_if_fail(GPLUGIN_IS_PYTHON_PLUGIN(plugin), NULL);
    + g_return_val_if_fail(GPLUGIN_PYTHON_IS_PLUGIN(plugin), NULL);
    - priv = gplugin_python_plugin_get_instance_private(plugin);
    -
    - return priv->unload;
    + return plugin->unload;
    }
    static void
    gplugin_python_plugin_set_unload_func(GPluginPythonPlugin *plugin,
    PyObject *func)
    {
    - GPluginPythonPluginPrivate *priv = NULL;
    -
    - g_return_if_fail(GPLUGIN_IS_PYTHON_PLUGIN(plugin));
    + g_return_if_fail(GPLUGIN_PYTHON_IS_PLUGIN(plugin));
    g_return_if_fail(func != NULL);
    - priv = gplugin_python_plugin_get_instance_private(plugin);
    -
    - if(priv->unload)
    - Py_DECREF(priv->unload);
    -
    - priv->unload = func;
    - if(priv->unload)
    - Py_INCREF(priv->unload);
    + Py_XINCREF(func);
    + Py_CLEAR(plugin->unload);
    + plugin->unload = func;
    }
    /******************************************************************************
    @@ -175,12 +135,10 @@
    GParamSpec *pspec)
    {
    GPluginPythonPlugin *plugin = GPLUGIN_PYTHON_PLUGIN(obj);
    - GPluginPythonPluginPrivate *priv = gplugin_python_plugin_get_instance_private(plugin);
    switch(param_id) {
    case PROP_MODULE:
    - g_value_set_pointer(value,
    - gplugin_python_plugin_get_module(plugin));
    + g_value_set_pointer(value, plugin->module);
    break;
    case PROP_LOAD_FUNC:
    g_value_set_pointer(value,
    @@ -193,16 +151,16 @@
    /* overrides */
    case PROP_FILENAME:
    - g_value_set_string(value, priv->filename);
    + g_value_set_string(value, plugin->filename);
    break;
    case PROP_LOADER:
    - g_value_set_object(value, priv->loader);
    + g_value_set_object(value, plugin->loader);
    break;
    case PROP_INFO:
    - g_value_set_object(value, priv->info);
    + g_value_set_object(value, plugin->info);
    break;
    case PROP_STATE:
    - g_value_set_enum(value, priv->state);
    + g_value_set_enum(value, plugin->state);
    break;
    default:
    @@ -216,7 +174,6 @@
    const GValue *value, GParamSpec *pspec)
    {
    GPluginPythonPlugin *plugin = GPLUGIN_PYTHON_PLUGIN(obj);
    - GPluginPythonPluginPrivate *priv = gplugin_python_plugin_get_instance_private(plugin);
    switch(param_id) {
    case PROP_MODULE:
    @@ -234,16 +191,16 @@
    /* overrides */
    case PROP_FILENAME:
    - priv->filename = g_strdup(g_value_get_string(value));
    + plugin->filename = g_value_dup_string(value);
    break;
    case PROP_LOADER:
    - priv->loader = g_object_ref(g_value_get_object(value));
    + plugin->loader = g_value_dup_object(value);
    break;
    case PROP_INFO:
    - priv->info = g_object_ref(g_value_get_object(value));
    + plugin->info = g_value_dup_object(value);
    break;
    case PROP_STATE:
    - priv->state = g_value_get_enum(value);
    + plugin->state = g_value_get_enum(value);
    break;
    default:
    @@ -254,28 +211,26 @@
    static void
    gplugin_python_plugin_finalize(GObject *obj) {
    - GPluginPythonPluginPrivate *priv = gplugin_python_plugin_get_instance_private(GPLUGIN_PYTHON_PLUGIN(obj));
    + GPluginPythonPlugin *plugin = GPLUGIN_PYTHON_PLUGIN(obj);
    - if(priv->module)
    - Py_DECREF(priv->module);
    - if(priv->load)
    - Py_DECREF(priv->load);
    - if(priv->unload)
    - Py_DECREF(priv->unload);
    + Py_CLEAR(plugin->module);
    + Py_CLEAR(plugin->load);
    + Py_CLEAR(plugin->unload);
    - g_free(priv->filename);
    - g_object_unref(G_OBJECT(priv->loader));
    - g_object_unref(G_OBJECT(priv->info));
    + 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);
    }
    static void
    -gplugin_python_plugin_init(GPluginPythonPlugin *plugin) {
    +gplugin_python_plugin_init(G_GNUC_UNUSED GPluginPythonPlugin *plugin) {
    }
    static void
    -gplugin_python_plugin_class_finalize(GPluginPythonPluginClass *klass) {
    +gplugin_python_plugin_class_finalize(G_GNUC_UNUSED GPluginPythonPluginClass *klass)
    +{
    }
    static void
    --- a/python/gplugin-python-plugin.h Tue Jan 22 22:58:59 2019 -0600
    +++ b/python/gplugin-python-plugin.h Mon Sep 30 01:28:39 2019 -0500
    @@ -18,37 +18,15 @@
    #ifndef GPLUGIN_PYTHON_PLUGIN_H
    #define GPLUGIN_PYTHON_PLUGIN_H
    -#define GPLUGIN_TYPE_PYTHON_PLUGIN (gplugin_python_plugin_get_type())
    -#define GPLUGIN_PYTHON_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GPLUGIN_TYPE_PYTHON_PLUGIN, GPluginPythonPlugin))
    -#define GPLUGIN_PYTHON_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((obj), GPLUGIN_TYPE_PYTHON_PLUGIN, GPluginPythonPluginClass))
    -#define GPLUGIN_IS_PYTHON_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GPLUGIN_TYPE_PYTHON_PLUGIN))
    -#define GPLUGIN_IS_PYTHON_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((obj), GPLUGIN_TYPE_PYTHON_PLUGIN))
    -#define GPLUGIN_PYTHON_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GPLUGIN_TYPE_PYTHON_PLUGIN, GPluginPythonPluginClass))
    -
    -typedef struct _GPluginPythonPlugin GPluginPythonPlugin;
    -typedef struct _GPluginPythonPluginClass GPluginPythonPluginClass;
    -
    #include <gplugin.h>
    #include <gplugin-native.h>
    -struct _GPluginPythonPlugin {
    - /*< private >*/
    - GObject parent;
    -
    - gpointer reserved[4];
    -};
    -
    -struct _GPluginPythonPluginClass {
    - /*< private >*/
    - GObjectClass parent;
    -
    - gpointer reserved[4];
    -};
    -
    G_BEGIN_DECLS
    +#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);
    -GType gplugin_python_plugin_get_type(void);
    G_END_DECLS
    --- a/python/gplugin-python-test-pygobject.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/python/gplugin-python-test-pygobject.c Mon Sep 30 01:28:39 2019 -0500
    @@ -39,8 +39,10 @@
    wargv[0] = g_new0(wchar_t, len + 1);
    len = mbstowcs(wargv[0], argv[0], len + 1);
    - if(len == (size_t)-1)
    + if(len == (size_t)-1) {
    + g_free(wargv[0]);
    return -1;
    + }
    /* setup sys.path */
    #if PY_VERSION_HEX < 0x03010300
    --- a/python/tests/meson.build Tue Jan 22 22:58:59 2019 -0600
    +++ b/python/tests/meson.build Mon Sep 30 01:28:39 2019 -0500
    @@ -3,7 +3,7 @@
    e = executable('test-python-loader', 'test-python-loader.c',
    include_directories : include_directories('.'),
    c_args : [
    - '-DPYTHON_LOADER_DIR="@0@/python"'.format(meson.build_root()),
    + '-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,
    @@ -15,7 +15,7 @@
    e = executable('test-python-utils', 'test-python-utils.c',
    include_directories : include_directories('.'),
    c_args : [
    - '-DPYTHON_LOADER_DIR="@0@/python"'.format(meson.build_root()),
    + '-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],
    --- a/python/tests/test-python-utils.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/python/tests/test-python-utils.c Mon Sep 30 01:28:39 2019 -0500
    @@ -31,12 +31,7 @@
    static void
    test_filename_to_module_NULL(void) {
    -#if GLIB_CHECK_VERSION(2,38,0)
    g_test_trap_subprocess("/loaders/python/utils/filename_to_module/NULL/subprocess", 0, 0);
    -#else
    - if(g_test_trap_fork(0, G_TEST_TRAP_SILENCE_STDERR))
    - test_filename_to_module_NULL_subprocess();
    -#endif
    g_test_trap_assert_failed();
    }
    @@ -69,10 +64,8 @@
    /* tests */
    g_test_add_func("/loaders/python/utils/filename_to_module/NULL",
    test_filename_to_module_NULL);
    -#if GLIB_CHECK_VERSION(2,38,0)
    g_test_add_func("/loaders/python/utils/filename_to_module/NULL/subprocess",
    test_filename_to_module_NULL_subprocess);
    -#endif
    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",
    --- a/scripts/bitbucket_upload Tue Jan 22 22:58:59 2019 -0600
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,70 +0,0 @@
    -#!/bin/sh
    -
    -CURL=$(which curl)
    -GREP=$(which grep)
    -AWK=$(which awk)
    -
    -OUTPUT=.bitbucket.cookies
    -
    -rm -f ${OUTPUT}
    -
    -PATH=${1}
    -FILES=${@}
    -
    -if [ -z ${PATH} ] ; then
    - echo "You must provide a repository path"
    - exit 1
    -fi
    -
    -if [ -z "${FILES}" ] ; then
    - echo "You must provide at least one file to upload"
    - exit 1
    -fi
    -
    -BASE_URI=https://bitbucket.org
    -LOGIN_URI=${BASE_URI}/account/signin/
    -UPLOAD_URI=${BASE_URI}/${PATH}/downloads
    -
    -read -e -p "bitbucket username: " BB_USERNAME
    -read -e -s -p "bitbucket password: " BB_PASSWORD
    -echo
    -echo
    -
    -# get the csrf token
    -echo -n "getting login token ... "
    -${CURL} -s -k -c ${OUTPUT} -o /dev/null ${LOGIN_URI}
    -CSRF_TOKEN=$(${GREP} csrftoken ${OUTPUT} | ${AWK} '{print $7}')
    -if [ -z ${CSRF_TOKEN} ] ; then
    - echo "failed."
    - rm -f ${OUTPUT}
    - exit 1
    -else
    - echo "done"
    -fi
    -
    -
    -echo -n "logging in ... "
    -${CURL} -s -k -c ${OUTPUT} -b ${OUTPUT} -o /dev/null -d "username=${BB_USERNAME}&password=${BB_PASSWORD}&csrfmiddlewaretoken=${CSRF_TOKEN}" --referer ${LOGIN_URI} -L ${LOGIN_URI}
    -${GREP} -q bb_session ${OUTPUT}
    -if [ $? -ne 0 ] ; then
    - echo "failed"
    - rm -f ${OUTPUT}
    - exit 1
    -else
    - echo "done"
    -fi
    -
    -for FILE in ${FILES} ; do
    - echo -n "uploading ${FILE} ... "
    - ${CURL} -s -k -c ${OUTPUT} -b ${OUTPUT} --referer ${UPLOAD_URI} -L --form csrfmiddlewaretoken=${CSRF_TOKEN} --form token= --form file=@"${FILE}" ${UPLOAD_URI}
    - if [ $? -ne 0 ] ; then
    - echo "failed"
    - rm -f ${OUTPUT}
    - exit 1
    - else
    - echo "done"
    - fi
    -done
    -
    -exit 0
    -
    --- a/scripts/makeviz.sh Tue Jan 22 22:58:59 2019 -0600
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,31 +0,0 @@
    -#!/bin/sh
    -
    -gource \
    - --seconds-per-day .1 \
    - --auto-skip-seconds .1 \
    - --file-idle-time 0 \
    - --multi-sampling \
    - --highlight-users \
    - --stop-at-end \
    - --key \
    - --title "History of GPlugin" \
    - --font-size 26 \
    - -1280x720 \
    - --max-files 0 \
    - --hide filenames,mouse,progress \
    - --output-framerate 30 \
    - -o - \
    -| ffmpeg \
    - -y \
    - -r 30 \
    - -f image2pipe \
    - -vcodec ppm \
    - -i - \
    - -vcodec libx264 \
    - -preset ultrafast \
    - -pix_fmt yuv420p \
    - -crf 1 \
    - -threads 0 \
    - -bf 0 \
    - gplugin.mp4
    -
    --- a/tcc/gplugin-tcc-core.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/tcc/gplugin-tcc-core.c Mon Sep 30 01:28:39 2019 -0500
    @@ -23,7 +23,7 @@
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    const gchar * const authors[] = {
    "Eion Robb <eion@robbmob.com>",
    NULL
    @@ -48,19 +48,19 @@
    G_MODULE_EXPORT gboolean
    gplugin_load(GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    + G_GNUC_UNUSED GError **error)
    {
    gplugin_tcc_loader_register(plugin);
    gplugin_tcc_plugin_register(plugin);
    - gplugin_manager_register_loader(gplugin_tcc_loader_get_type());
    + gplugin_manager_register_loader(GPLUGIN_TCC_TYPE_LOADER);
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return FALSE;
    }
    --- a/tcc/gplugin-tcc-loader.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/tcc/gplugin-tcc-loader.c Mon Sep 30 01:28:39 2019 -0500
    @@ -23,17 +23,17 @@
    #include <libtcc.h>
    -/******************************************************************************
    - * Globals
    - *****************************************************************************/
    -static GObjectClass *parent_class = NULL;
    -static GType type_real = 0;
    +struct _GPluginTccLoader {
    + GPluginLoader parent;
    +};
    +
    +G_DEFINE_DYNAMIC_TYPE(GPluginTccLoader, gplugin_tcc_loader, GPLUGIN_TYPE_LOADER);
    /******************************************************************************
    * GPluginLoaderInterface API
    *****************************************************************************/
    static GSList *
    -gplugin_tcc_loader_class_supported_extensions(GPLUGIN_UNUSED const GPluginLoaderClass *klass) {
    +gplugin_tcc_loader_class_supported_extensions(G_GNUC_UNUSED const GPluginLoaderClass *klass) {
    GSList *exts = NULL;
    exts = g_slist_append(exts, "c");
    @@ -58,8 +58,7 @@
    tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
    if(tcc_add_file(s, filename) == -1) {
    - if(error)
    - *error = g_error_new(GPLUGIN_DOMAIN, 0, "couldn't load file %s", filename);
    + g_set_error(error, GPLUGIN_DOMAIN, 0, "couldn't load file %s", filename);
    tcc_delete(s);
    @@ -68,8 +67,7 @@
    /* copy code into memory */
    if((memsize = tcc_relocate(s, NULL)) < 0) {
    - if(error)
    - *error = g_error_new(GPLUGIN_DOMAIN, 0, "couldn't work out how much memory is needed");
    + g_set_error(error, GPLUGIN_DOMAIN, 0, "couldn't work out how much memory is needed");
    tcc_delete(s);
    return NULL;
    @@ -77,8 +75,7 @@
    memneeded = g_malloc0(memsize);
    if(tcc_relocate(s, memneeded) < 0) {
    - if(error)
    - *error = g_error_new(GPLUGIN_DOMAIN, 0, "could not relocate plugin into memory");
    + g_set_error(error, GPLUGIN_DOMAIN, 0, "could not relocate plugin into memory");
    tcc_delete(s);
    g_free(memneeded);
    @@ -87,8 +84,7 @@
    gplugin_query = (GPluginTccPluginQueryFunc) tcc_get_symbol(s, "gplugin_query");
    if (gplugin_query == NULL) {
    - if(error)
    - *error = g_error_new(GPLUGIN_DOMAIN, 0, "no gplugin_query function found");
    + g_set_error(error, GPLUGIN_DOMAIN, 0, "no gplugin_query function found");
    tcc_delete(s);
    g_free(memneeded);
    @@ -102,7 +98,7 @@
    return NULL;
    }
    - plugin = g_object_new(GPLUGIN_TYPE_TCC_PLUGIN,
    + plugin = g_object_new(GPLUGIN_TCC_TYPE_PLUGIN,
    "filename", filename,
    "loader", loader,
    "state", s,
    @@ -114,7 +110,7 @@
    }
    static gboolean
    -gplugin_tcc_loader_load(GPLUGIN_UNUSED GPluginLoader *loader,
    +gplugin_tcc_loader_load(G_GNUC_UNUSED GPluginLoader *loader,
    GPluginPlugin *plugin,
    GError **error)
    {
    @@ -123,8 +119,7 @@
    gplugin_load = (GPluginTccPluginLoadFunc) tcc_get_symbol(s, "gplugin_load");
    if (gplugin_load == NULL) {
    - if(error)
    - *error = g_error_new(GPLUGIN_DOMAIN, 0, "no gplugin_load function found");
    + g_set_error(error, GPLUGIN_DOMAIN, 0, "no gplugin_load function found");
    return FALSE;
    }
    @@ -133,7 +128,7 @@
    }
    static gboolean
    -gplugin_tcc_loader_unload(GPLUGIN_UNUSED GPluginLoader *loader,
    +gplugin_tcc_loader_unload(G_GNUC_UNUSED GPluginLoader *loader,
    GPluginPlugin *plugin,
    GError **error)
    {
    @@ -142,8 +137,7 @@
    gplugin_unload = (GPluginTccPluginUnloadFunc) tcc_get_symbol(s, "gplugin_unload");
    if (gplugin_unload == NULL) {
    - if(error)
    - *error = g_error_new(GPLUGIN_DOMAIN, 0, "no gplugin_unload function found");
    + g_set_error(error, GPLUGIN_DOMAIN, 0, "no gplugin_unload function found");
    return FALSE;
    }
    @@ -155,11 +149,17 @@
    * GObject Stuff
    *****************************************************************************/
    static void
    +gplugin_tcc_loader_init(G_GNUC_UNUSED GPluginTccLoader *loader) {
    +}
    +
    +static void
    +gplugin_tcc_loader_class_finalize(G_GNUC_UNUSED GPluginTccLoaderClass *klass) {
    +}
    +
    +static void
    gplugin_tcc_loader_class_init(GPluginTccLoaderClass *klass) {
    GPluginLoaderClass *loader_class = GPLUGIN_LOADER_CLASS(klass);
    - parent_class = g_type_class_peek_parent(klass);
    -
    loader_class->supported_extensions =
    gplugin_tcc_loader_class_supported_extensions;
    loader_class->query = gplugin_tcc_loader_query;
    @@ -172,32 +172,5 @@
    *****************************************************************************/
    void
    gplugin_tcc_loader_register(GPluginNativePlugin *plugin) {
    - if(g_once_init_enter(&type_real)) {
    - GType type = 0;
    -
    - static const GTypeInfo info = {
    - .class_size = sizeof(GPluginTccLoaderClass),
    - .class_init = (GClassInitFunc)gplugin_tcc_loader_class_init,
    - .instance_size = sizeof(GPluginTccLoader),
    - };
    -
    - type = gplugin_native_plugin_register_type(plugin,
    - GPLUGIN_TYPE_LOADER,
    - "GPluginTccLoader",
    - &info,
    - 0);
    -
    - g_once_init_leave(&type_real, type);
    - }
    + gplugin_tcc_loader_register_type(G_TYPE_MODULE(plugin));
    }
    -
    -GType
    -gplugin_tcc_loader_get_type(void) {
    - if(G_UNLIKELY(type_real == 0)) {
    - g_warning("gplugin_tcc_loader_get_type was called before "
    - "the type was registered!\n");
    - }
    -
    - return type_real;
    -}
    -
    --- a/tcc/gplugin-tcc-loader.h Tue Jan 22 22:58:59 2019 -0600
    +++ b/tcc/gplugin-tcc-loader.h Mon Sep 30 01:28:39 2019 -0500
    @@ -17,41 +17,15 @@
    #ifndef GPLUGIN_TCC_LOADER_H
    #define GPLUGIN_TCC_LOADER_H
    -#define GPLUGIN_TYPE_TCC_LOADER (gplugin_tcc_loader_get_type())
    -#define GPLUGIN_TCC_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GPLUGIN_TYPE_TCC_LOADER, GPluginTccLoader))
    -#define GPLUGIN_TCC_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((obj), GPLUGIN_TYPE_TCC_LOADER, GPluginTccLoaderClass))
    -#define GPLUGIN_IS_TCC_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GPLUGIN_TYPE_TCC_LOADER))
    -#define GPLUGIN_IS_TCC_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((obj), GPLUGIN_TYPE_TCC_LOADER))
    -#define GPLUGIN_TCC_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GPLUGIN_TYPE_TCC_LOADER, GPluginTccLoaderClass))
    -
    -typedef struct _GPluginTccLoader GPluginTccLoader;
    -typedef struct _GPluginTccLoaderClass GPluginTccLoaderClass;
    -
    #include <gplugin.h>
    #include <gplugin-native.h>
    -struct _GPluginTccLoader {
    - GPluginLoader parent;
    -
    - void (*_gplugin_reserved_1)(void);
    - void (*_gplugin_reserved_2)(void);
    - void (*_gplugin_reserved_3)(void);
    - void (*_gplugin_reserved_4)(void);
    -};
    -
    -struct _GPluginTccLoaderClass {
    - GPluginLoaderClass parent;
    -
    - void (*_gplugin_reserved_1)(void);
    - void (*_gplugin_reserved_2)(void);
    - void (*_gplugin_reserved_3)(void);
    - void (*_gplugin_reserved_4)(void);
    -};
    -
    G_BEGIN_DECLS
    +#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);
    -GType gplugin_tcc_loader_get_type(void);
    G_END_DECLS
    --- a/tcc/gplugin-tcc-plugin.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/tcc/gplugin-tcc-plugin.c Mon Sep 30 01:28:39 2019 -0500
    @@ -19,46 +19,55 @@
    #include <libtcc.h>
    -#define GPLUGIN_TCC_PLUGIN_GET_PRIVATE(obj) \
    - (G_TYPE_INSTANCE_GET_PRIVATE((obj), GPLUGIN_TYPE_TCC_PLUGIN, GPluginTccPluginPrivate))
    -
    /******************************************************************************
    * Typedefs
    *****************************************************************************/
    -typedef struct {
    +struct _GPluginTccPlugin {
    + GObject parent;
    +
    TCCState *s;
    gpointer mem;
    -} GPluginTccPluginPrivate;
    +
    + gchar *filename;
    + GPluginLoader *loader;
    + GPluginPluginInfo *info;
    + GPluginPluginState state;
    +};
    /******************************************************************************
    * Enums
    *****************************************************************************/
    enum {
    PROP_ZERO,
    - PROP_STATE,
    + PROP_TCC_STATE,
    PROP_MEM,
    N_PROPERTIES,
    +
    + /* overrides */
    + PROP_FILENAME = N_PROPERTIES,
    + PROP_LOADER,
    + PROP_INFO,
    + PROP_STATE
    };
    static GParamSpec *properties[N_PROPERTIES] = {NULL,};
    -static GObjectClass *parent_class = NULL;
    -static GType type_real = 0;
    +/* I hate forward declarations... */
    +static void gplugin_tcc_plugin_iface_init(GPluginPluginInterface *iface);
    +
    +G_DEFINE_DYNAMIC_TYPE_EXTENDED(
    + GPluginTccPlugin,
    + gplugin_tcc_plugin,
    + G_TYPE_OBJECT,
    + 0,
    + G_IMPLEMENT_INTERFACE(GPLUGIN_TYPE_PLUGIN, gplugin_tcc_plugin_iface_init)
    +);
    /******************************************************************************
    - * Private Stuff
    + * GPluginPlugin Implementation
    *****************************************************************************/
    static void
    -gplugin_tcc_plugin_set_state(GPluginTccPlugin *plugin, TCCState *s) {
    - GPluginTccPluginPrivate *priv = GPLUGIN_TCC_PLUGIN_GET_PRIVATE(plugin);
    -
    - priv->s = s;
    -}
    -
    -static void
    -gplugin_tcc_plugin_set_memory(GPluginTccPlugin *plugin, gpointer mem) {
    - GPluginTccPluginPrivate *priv = GPLUGIN_TCC_PLUGIN_GET_PRIVATE(plugin);
    -
    - priv->mem = mem;
    +gplugin_tcc_plugin_iface_init(G_GNUC_UNUSED GPluginPluginInterface *iface)
    +{
    }
    /******************************************************************************
    @@ -71,10 +80,25 @@
    GPluginTccPlugin *plugin = GPLUGIN_TCC_PLUGIN(obj);
    switch(param_id) {
    - case PROP_STATE:
    + case PROP_TCC_STATE:
    g_value_set_pointer(value,
    gplugin_tcc_plugin_get_state(plugin));
    break;
    +
    + /* overrides */
    + case PROP_FILENAME:
    + g_value_set_string(value, plugin->filename);
    + break;
    + case PROP_LOADER:
    + g_value_set_object(value, plugin->loader);
    + break;
    + case PROP_INFO:
    + g_value_set_object(value, plugin->info);
    + break;
    + case PROP_STATE:
    + g_value_set_enum(value, plugin->state);
    + break;
    +
    default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
    break;
    @@ -88,14 +112,27 @@
    GPluginTccPlugin *plugin = GPLUGIN_TCC_PLUGIN(obj);
    switch(param_id) {
    - case PROP_STATE:
    - gplugin_tcc_plugin_set_state(plugin,
    - g_value_get_pointer(value));
    + case PROP_TCC_STATE:
    + plugin->s = g_value_get_pointer(value);
    break;
    case PROP_MEM:
    - gplugin_tcc_plugin_set_memory(plugin,
    - g_value_get_pointer(value));
    + plugin->mem = g_value_get_pointer(value);
    + break;
    +
    + /* overrides */
    + case PROP_FILENAME:
    + plugin->filename = g_value_dup_string(value);
    break;
    + case PROP_LOADER:
    + plugin->loader = g_value_dup_object(value);
    + break;
    + case PROP_INFO:
    + plugin->info = g_value_dup_object(value);
    + break;
    + case PROP_STATE:
    + plugin->state = g_value_get_enum(value);
    + break;
    +
    default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
    break;
    @@ -104,82 +141,67 @@
    static void
    gplugin_tcc_plugin_finalize(GObject *obj) {
    - GPluginTccPluginPrivate *priv = GPLUGIN_TCC_PLUGIN_GET_PRIVATE(obj);
    + GPluginTccPlugin *plugin = GPLUGIN_TCC_PLUGIN(obj);
    - if(priv->s)
    - tcc_delete(priv->s);
    + g_clear_pointer(&plugin->s, tcc_delete);
    + g_clear_pointer(&plugin->mem, g_free);
    +
    + g_clear_pointer(&plugin->filename, g_free);
    + g_clear_object(&plugin->loader);
    + g_clear_object(&plugin->info);
    - if(priv->mem)
    - g_free(priv->mem);
    + G_OBJECT_CLASS(gplugin_tcc_plugin_parent_class)->finalize(obj);
    +}
    - G_OBJECT_CLASS(parent_class)->finalize(obj);
    +static void
    +gplugin_tcc_plugin_init(G_GNUC_UNUSED GPluginTccPlugin *plugin) {
    +}
    +
    +static void
    +gplugin_tcc_plugin_class_finalize(G_GNUC_UNUSED GPluginTccPluginClass *klass) {
    }
    static void
    gplugin_tcc_plugin_class_init(GPluginTccPluginClass *klass) {
    GObjectClass *obj_class = G_OBJECT_CLASS(klass);
    - parent_class = g_type_class_peek_parent(klass);
    -
    - g_type_class_add_private(klass, sizeof(GPluginTccPluginPrivate));
    -
    obj_class->get_property = gplugin_tcc_plugin_get_property;
    obj_class->set_property = gplugin_tcc_plugin_set_property;
    obj_class->finalize = gplugin_tcc_plugin_finalize;
    - properties[PROP_STATE] = g_param_spec_pointer(
    - "state", "state",
    + 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
    );
    - properties[PROP_MEM] =g_param_spec_pointer(
    + properties[PROP_MEM] = g_param_spec_pointer(
    "memory", "memory",
    "The memory allocated for the symbol table for the plugin",
    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");
    }
    /******************************************************************************
    * API
    *****************************************************************************/
    void
    -gplugin_tcc_plugin_register(GPluginNativePlugin *plugin) {
    - if(g_once_init_enter(&type_real)) {
    - GType type = 0;
    -
    - static const GTypeInfo info = {
    - .class_size = sizeof(GPluginTccPluginClass),
    - .class_init = (GClassInitFunc)gplugin_tcc_plugin_class_init,
    - .instance_size = sizeof(GPluginTccPlugin),
    - };
    -
    - type = gplugin_native_plugin_register_type(plugin,
    - GPLUGIN_TYPE_PLUGIN,
    - "GPluginTccPlugin",
    - &info,
    - 0);
    -
    - g_once_init_leave(&type_real, type);
    - }
    -}
    -
    -GType
    -gplugin_tcc_plugin_get_type(void) {
    - if(G_UNLIKELY(type_real == 0)) {
    - g_warning("gplugin_tcc_plugin_get_type was called before "
    - "the type was registered!\n");
    - }
    -
    - return type_real;
    +gplugin_tcc_plugin_register(GPluginNativePlugin *native) {
    + gplugin_tcc_plugin_register_type(G_TYPE_MODULE(native));
    }
    TCCState *
    -gplugin_tcc_plugin_get_state(const GPluginTccPlugin *plugin) {
    - GPluginTccPluginPrivate *priv = GPLUGIN_TCC_PLUGIN_GET_PRIVATE(plugin);
    +gplugin_tcc_plugin_get_state(GPluginTccPlugin *plugin) {
    + g_return_val_if_fail(GPLUGIN_TCC_IS_PLUGIN(plugin), NULL);
    - return priv->s;
    + return plugin->s;
    }
    --- a/tcc/gplugin-tcc-plugin.h Tue Jan 22 22:58:59 2019 -0600
    +++ b/tcc/gplugin-tcc-plugin.h Mon Sep 30 01:28:39 2019 -0500
    @@ -17,40 +17,19 @@
    #ifndef GPLUGIN_TCC_PLUGIN_H
    #define GPLUGIN_TCC_PLUGIN_H
    -#define GPLUGIN_TYPE_TCC_PLUGIN (gplugin_tcc_plugin_get_type())
    -#define GPLUGIN_TCC_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GPLUGIN_TYPE_TCC_PLUGIN, GPluginTccPlugin))
    -#define GPLUGIN_TCC_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((obj), GPLUGIN_TYPE_TCC_PLUGIN, GPluginTccPluginClass))
    -#define GPLUGIN_IS_TCC_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GPLUGIN_TYPE_TCC_PLUGIN))
    -#define GPLUGIN_IS_TCC_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((obj), GPLUGIN_TYPE_TCC_PLUGIN))
    -#define GPLUGIN_TCC_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GPLUGIN_TYPE_TCC_PLUGIN, GPluginTccPluginClass))
    -
    -typedef struct _GPluginTccPlugin GPluginTccPlugin;
    -typedef struct _GPluginTccPluginClass GPluginTccPluginClass;
    -
    #include <gplugin.h>
    #include <gplugin-native.h>
    #include <libtcc.h>
    -struct _GPluginTccPlugin {
    - GPluginPlugin parent;
    -};
    -
    -struct _GPluginTccPluginClass {
    - GPluginPluginClass parent;
    -
    - void (*_gplugin_reserved_1)(void);
    - void (*_gplugin_reserved_2)(void);
    - void (*_gplugin_reserved_3)(void);
    - void (*_gplugin_reserved_4)(void);
    -};
    -
    G_BEGIN_DECLS
    -void gplugin_tcc_plugin_register(GPluginNativePlugin *plugin);
    -GType gplugin_tcc_plugin_get_type(void);
    +#define GPLUGIN_TCC_TYPE_PLUGIN (gplugin_tcc_plugin_get_type())
    +G_DECLARE_FINAL_TYPE(GPluginTccPlugin, gplugin_tcc_plugin, GPLUGIN_TCC, PLUGIN, GObject)
    -TCCState *gplugin_tcc_plugin_get_state(const GPluginTccPlugin *plugin);
    +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);
    --- a/tcc/meson.build Tue Jan 22 22:58:59 2019 -0600
    +++ b/tcc/meson.build Mon Sep 30 01:28:39 2019 -0500
    @@ -11,7 +11,7 @@
    ]
    if not compiler.has_header('libtcc.h')
    - error('LibTcc header not found')
    + error('libtcc.h not found')
    endif
    TCC = compiler.find_library('tcc')
    --- a/tcc/tests/meson.build Tue Jan 22 22:58:59 2019 -0600
    +++ b/tcc/tests/meson.build Mon Sep 30 01:28:39 2019 -0500
    @@ -2,7 +2,7 @@
    e = executable('test-tcc-loader', 'test-tcc-loader.c',
    c_args : [
    - '-DTCC_LOADER_DIR="@0@/tcc"'.format(meson.build_root()),
    + '-DTCC_LOADER_DIR="@0@"'.format(join_paths(meson.current_build_dir(), '..')),
    '-DTCC_PLUGIN_DIR="@0@/plugins"'.format(
    meson.current_source_dir()),
    ],
    --- a/tcc/tests/plugins/basic-plugin.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/tcc/tests/plugins/basic-plugin.c Mon Sep 30 01:28:39 2019 -0500
    @@ -18,7 +18,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    const gchar * const authors[] = {
    "author1",
    NULL
    @@ -40,15 +40,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/tcc/tests/plugins/dependent.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/tcc/tests/plugins/dependent.c Mon Sep 30 01:28:39 2019 -0500
    @@ -18,7 +18,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    const gchar * const dependencies[] = {
    "dependency1",
    "dependency2",
    @@ -34,15 +34,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/tcc/tests/plugins/load-exception.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/tcc/tests/plugins/load-exception.c Mon Sep 30 01:28:39 2019 -0500
    @@ -18,7 +18,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    return gplugin_plugin_info_new(
    "gplugin/native-load-exception",
    GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
    @@ -27,15 +27,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return FALSE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/tcc/tests/plugins/load-failed.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/tcc/tests/plugins/load-failed.c Mon Sep 30 01:28:39 2019 -0500
    @@ -18,7 +18,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    return gplugin_plugin_info_new(
    "gplugin/native-load-failed",
    GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
    @@ -27,16 +27,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin, GError **error) {
    - if(error)
    - *error = g_error_new(GPLUGIN_DOMAIN, 0, "expected error");
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin, GError **error) {
    + g_set_error(error, GPLUGIN_DOMAIN, 0, "expected error");
    return FALSE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    --- a/tcc/tests/plugins/unload-failed.c Tue Jan 22 22:58:59 2019 -0600
    +++ b/tcc/tests/plugins/unload-failed.c Mon Sep 30 01:28:39 2019 -0500
    @@ -18,7 +18,7 @@
    #include <gplugin-native.h>
    G_MODULE_EXPORT GPluginPluginInfo *
    -gplugin_query(GPLUGIN_UNUSED GError **error) {
    +gplugin_query(G_GNUC_UNUSED GError **error) {
    return gplugin_plugin_info_new(
    "gplugin/native-unload-failed",
    GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
    @@ -27,16 +27,15 @@
    }
    G_MODULE_EXPORT gboolean
    -gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    +gplugin_load(G_GNUC_UNUSED GPluginNativePlugin *plugin,
    + G_GNUC_UNUSED GError **error)
    {
    return TRUE;
    }
    G_MODULE_EXPORT gboolean
    -gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin, GError **error) {
    - if(error)
    - *error = g_error_new(GPLUGIN_DOMAIN, 0, "expected error");
    +gplugin_unload(G_GNUC_UNUSED GPluginNativePlugin *plugin, GError **error) {
    + g_set_error(error, GPLUGIN_DOMAIN, 0, "expected error");
    return FALSE;
    }
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/vala/meson.build Mon Sep 30 01:28:39 2019 -0500
    @@ -0,0 +1,24 @@
    +if get_option('vapi')
    + if not get_option('gobject-introspection')
    + error('Vala generation requires GObject Introspection.')
    + endif
    +
    + add_languages('vala')
    +
    + gplugin_vapi = gnome.generate_vapi('gplugin',
    + sources : gplugin_gir[0],
    + install : true,
    + gir_dirs : join_paths(meson.current_build_dir(), '..', 'gplugin'),
    + )
    +
    + if get_option('gtk3')
    + gplugin_gtk_vapi = gnome.generate_vapi('gplugin-gtk',
    + sources : gplugin_gtk_gir[0],
    + packages : [ 'gtk+-3.0' ],
    + install : true,
    + gir_dirs : join_paths(meson.current_build_dir(), '..', 'gplugin'),
    + )
    + endif
    +
    + subdir('tests')
    +endif # vala
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/vala/tests/meson.build Mon Sep 30 01:28:39 2019 -0500
    @@ -0,0 +1,14 @@
    +if get_option('vapi')
    +
    +e = executable('test-vala-loading', 'test-vala-loading.c',
    + include_directories : include_directories('.'),
    + c_args : [
    + '-DVALA_PLUGIN_DIR="@0@/plugins"'.format(meson.current_build_dir()),
    + ],
    + link_with : gplugin_loader_tests,
    + dependencies : [GLIB, GOBJECT, gplugin_dep])
    +test('Vala loading', e)
    +
    +subdir('plugins')
    +
    +endif # vapi
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/vala/tests/plugins/basic.vala Mon Sep 30 01:28:39 2019 -0500
    @@ -0,0 +1,54 @@
    +/*
    + * Copyright (C) 2011-2019 Gary Kramlich <grim@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/>.
    + */
    +using GPlugin;
    +
    +public class BasicPluginInfo : GPlugin.PluginInfo {
    + public BasicPluginInfo() {
    + string[] authors = {"author1"};
    +
    + Object(
    + id: "gplugin/vala-basic-plugin",
    + abi_version: 0x01020304,
    + name: "basic plugin",
    + authors: authors,
    + category: "test",
    + version: "version",
    + license_id: "license",
    + summary: "summary",
    + website: "website",
    + description: "description"
    + );
    + }
    +}
    +
    +public GPlugin.PluginInfo gplugin_query(out Error error) {
    + error = null;
    +
    + return new BasicPluginInfo();
    +}
    +
    +public bool gplugin_load(GPlugin.Plugin plugin, out Error error) {
    + error = null;
    +
    + return true;
    +}
    +
    +public bool gplugin_unload(GPlugin.Plugin plugin, out Error error) {
    + error = null;
    +
    + return true;
    +}
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/vala/tests/plugins/dependent.vala Mon Sep 30 01:28:39 2019 -0500
    @@ -0,0 +1,46 @@
    +/*
    + * Copyright (C) 2011-2019 Gary Kramlich <grim@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/>.
    + */
    +using GPlugin;
    +
    +public class DependentPluginInfo : GPlugin.PluginInfo {
    + public DependentPluginInfo() {
    + string[] dependencies = {"dependency1", "dependency2"};
    +
    + Object(
    + id: "gplugin/vala-dependent-plugin",
    + dependencies: dependencies
    + );
    + }
    +}
    +
    +public GPlugin.PluginInfo gplugin_query(out Error error) {
    + error = null;
    +
    + return new DependentPluginInfo();
    +}
    +
    +public bool gplugin_load(GPlugin.Plugin plugin, out Error error) {
    + error = null;
    +
    + return true;
    +}
    +
    +public bool gplugin_unload(GPlugin.Plugin plugin, out Error error) {
    + error = null;
    +
    + return false;
    +}
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/vala/tests/plugins/load-exception.vala Mon Sep 30 01:28:39 2019 -0500
    @@ -0,0 +1,43 @@
    +/*
    + * Copyright (C) 2011-2019 Gary Kramlich <grim@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/>.
    + */
    +using GPlugin;
    +
    +public class LoadExceptionPluginInfo : GPlugin.PluginInfo {
    + public LoadExceptionPluginInfo() {
    + Object(
    + id: "gplugin/vala-load-exception"
    + );
    + }
    +}
    +
    +public GPlugin.PluginInfo gplugin_query(out Error error) {
    + error = null;
    +
    + return new LoadExceptionPluginInfo();
    +}
    +
    +public bool gplugin_load(GPlugin.Plugin plugin, out Error error) {
    + error = new Error(Quark.from_string("gplugin"), 0, "explode");
    +
    + return false;
    +}
    +
    +public bool gplugin_unload(GPlugin.Plugin plugin, out Error error) {
    + error = null;
    +
    + return true;
    +}
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/vala/tests/plugins/load-failed.vala Mon Sep 30 01:28:39 2019 -0500
    @@ -0,0 +1,43 @@
    +/*
    + * Copyright (C) 2011-2019 Gary Kramlich <grim@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/>.
    + */
    +using GPlugin;
    +
    +public class LoadFailedPluginInfo : GPlugin.PluginInfo {
    + public LoadFailedPluginInfo() {
    + Object(
    + id: "gplugin/vala-load-failed"
    + );
    + }
    +}
    +
    +public GPlugin.PluginInfo gplugin_query(out Error error) {
    + error = null;
    +
    + return new LoadFailedPluginInfo();
    +}
    +
    +public bool gplugin_load(GPlugin.Plugin plugin, out Error error) {
    + error = null;
    +
    + return false;
    +}
    +
    +public bool gplugin_unload(GPlugin.Plugin plugin, out Error error) {
    + error = null;
    +
    + return true;
    +}
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/vala/tests/plugins/meson.build Mon Sep 30 01:28:39 2019 -0500
    @@ -0,0 +1,17 @@
    +if get_option('vapi')
    + shared_library('vala-basic-plugin', 'basic.vala',
    + name_prefix : '',
    + dependencies : [gplugin_dep, gplugin_vapi])
    + shared_library('vala-dependent-plugin', 'dependent.vala',
    + name_prefix : '',
    + dependencies : [gplugin_dep, gplugin_vapi])
    + shared_library('vala-load-exception', 'load-exception.vala',
    + name_prefix : '',
    + dependencies : [gplugin_dep, gplugin_vapi])
    + shared_library('vala-load-failed', 'load-failed.vala',
    + name_prefix : '',
    + dependencies : [gplugin_dep, gplugin_vapi])
    + shared_library('vala-unload-failed', 'unload-failed.vala',
    + name_prefix : '',
    + dependencies : [gplugin_dep, gplugin_vapi])
    +endif # vapi
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/vala/tests/plugins/unload-failed.vala Mon Sep 30 01:28:39 2019 -0500
    @@ -0,0 +1,43 @@
    +/*
    + * Copyright (C) 2011-2019 Gary Kramlich <grim@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/>.
    + */
    +using GPlugin;
    +
    +public class UnloadFailedPluginInfo : GPlugin.PluginInfo {
    + public UnloadFailedPluginInfo() {
    + Object(
    + id: "gplugin/vala-unload-failed"
    + );
    + }
    +}
    +
    +public GPlugin.PluginInfo gplugin_query(out Error error) {
    + error = null;
    +
    + return new UnloadFailedPluginInfo();
    +}
    +
    +public bool gplugin_load(GPlugin.Plugin plugin, out Error error) {
    + error = null;
    +
    + return true;
    +}
    +
    +public bool gplugin_unload(GPlugin.Plugin plugin, out Error error) {
    + error = null;
    +
    + return false;
    +}
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/vala/tests/test-vala-loading.c Mon Sep 30 01:28:39 2019 -0500
    @@ -0,0 +1,34 @@
    +/*
    + * Copyright (C) 2011-2019 Gary Kramlich <grim@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.h>
    +#include <gplugin.h>
    +
    +#include <gplugin/gplugin-loader-tests.h>
    +
    +/******************************************************************************
    + * Main
    + *****************************************************************************/
    +gint
    +main(gint argc, gchar **argv) {
    + g_test_init(&argc, &argv, NULL);
    +
    + gplugin_loader_tests_main(NULL, VALA_PLUGIN_DIR, "vala");
    +
    + return g_test_run();
    +}
    +
    --- a/xsl/gtester-junit.xsl Tue Jan 22 22:58:59 2019 -0600
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,94 +0,0 @@
    -<?xml version="1.0" encoding="utf-8"?>
    -<!--
    - Copyright (C) 2011-2017 Gary Kramlich <grim@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/>.
    --->
    -<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    - <xsl:output method="xml" cdata-section-elements="system-out system-err failure" indent="yes"/>
    -
    - <!-- basename template, keeps removing text before '/' until there isn't any -->
    - <xsl:template name="basename">
    - <xsl:param name="path"/>
    -
    - <xsl:choose>
    - <xsl:when test="contains($path, '/')">
    - <xsl:call-template name="basename">
    - <xsl:with-param name="path" select="substring-after($path, '/')"/>
    - </xsl:call-template>
    - </xsl:when>
    - <xsl:otherwise>
    - <xsl:value-of select="$path"/>
    - </xsl:otherwise>
    - </xsl:choose>
    - </xsl:template>
    -
    - <!-- match the gtester root tag -->
    - <xsl:template match="/gtester">
    - <xsl:element name="testsuite">
    - <!-- add the number of tests as the test attribute -->
    - <xsl:attribute name="tests">
    - <xsl:value-of select="count(//testcase)"/>
    - </xsl:attribute>
    -
    - <!-- sum up all durations and add it as the time attribute -->
    - <xsl:attribute name="time">
    - <xsl:value-of select="sum(//testbinary/duration)"/>
    - </xsl:attribute>
    -
    - <!-- add the number of failures as the failures attribute -->
    - <xsl:attribute name="failures">
    - <xsl:value-of select="count(//testcase/status[@result='failed'])"/>
    - </xsl:attribute>
    -
    - <xsl:apply-templates/>
    -
    - <!-- now create the system-out and system-err elements -->
    - <xsl:element name="system-out">
    - <xsl:apply-templates select="//message"/>
    - </xsl:element>
    -
    - <xsl:element name="system-err">
    - <xsl:apply-templates select="//error"/>
    - </xsl:element>
    - </xsl:element>
    - </xsl:template>
    -
    - <!-- match the testcases -->
    - <xsl:template match="/gtester/testbinary/testcase">
    - <xsl:element name="testcase">
    - <xsl:attribute name="time">
    - <xsl:value-of select="./duration/text()"/>
    - </xsl:attribute>
    - <xsl:attribute name="name">
    - <xsl:variable name="exec">
    - <xsl:call-template name="basename">
    - <xsl:with-param name="path" select="../@path"/>
    - </xsl:call-template>
    - </xsl:variable>
    - <xsl:value-of select="concat($exec, translate(@path, '/-', '.'))"/>
    - </xsl:attribute>
    -
    - <xsl:if test="./status[@result='failed']">
    - <xsl:element name="failure">
    - <xsl:value-of select="error"/>
    - </xsl:element>
    - </xsl:if>
    - </xsl:element>
    - </xsl:template>
    -
    - <!-- ignore all other cdata -->
    - <xsl:template match="text()"/>
    -</xsl:stylesheet>
    -