gplugin/gplugin

Merging version 0.28

2019-01-22, Gary Kramlich
741a484ae91c
Merging version 0.28
  • +4 -2
    .hgignore
  • +0 -231
    CMakeLists.txt
  • +10 -0
    COPYRIGHT
  • +11 -0
    ChangeLog
  • +1 -1
    HACKING
  • +28 -0
    HACKING.OSX
  • +7 -13
    INSTALL
  • +0 -138
    cmake/Compatibility/CMakeParseArguments.cmake
  • +0 -233
    cmake/Modules/GObjectIntrospection.cmake
  • +0 -190
    cmake/Modules/Gettextize.cmake
  • +0 -14
    cmake/Modules/PkgConfigVariable.cmake
  • +0 -74
    cmake/Modules/help2man.cmake
  • +0 -8
    cmake/Toolchains/cygwin-mingw.cmake
  • +163 -0
    convey.yml
  • +6 -0
    gplugin-gtk-viewer/data/gplugin-gtk-viewer.gresource.xml
  • +65 -0
    gplugin-gtk-viewer/data/window.ui
  • +48 -0
    gplugin-gtk-viewer/gplugin-gtk-viewer-window.c
  • +59 -0
    gplugin-gtk-viewer/gplugin-gtk-viewer-window.h
  • +215 -0
    gplugin-gtk-viewer/gplugin-gtk-viewer.c
  • +29 -0
    gplugin-gtk-viewer/meson.build
  • +0 -145
    gplugin-gtk/CMakeLists.txt
  • +6 -0
    gplugin-gtk/data/gplugin-gtk.gresource.xml
  • +540 -0
    gplugin-gtk/data/plugin-info.ui
  • +108 -109
    gplugin-gtk/gplugin-gtk-plugin-info.c
  • +5 -13
    gplugin-gtk/gplugin-gtk-plugin-info.h
  • +0 -397
    gplugin-gtk/gplugin-gtk-plugin-info.ui
  • +25 -17
    gplugin-gtk/gplugin-gtk-store.c
  • +2 -10
    gplugin-gtk/gplugin-gtk-store.h
  • +42 -18
    gplugin-gtk/gplugin-gtk-view.c
  • +3 -11
    gplugin-gtk/gplugin-gtk-view.h
  • +0 -215
    gplugin-gtk/gplugin-gtk-viewer.c
  • +0 -13
    gplugin-gtk/gplugin-gtk.pc.in
  • +36 -0
    gplugin-gtk/gplugin-gtk.xml.in
  • +144 -0
    gplugin-gtk/meson.build
  • +50 -0
    gplugin-gtk/reference/gplugin-gtk-docs.xml
  • +39 -0
    gplugin-gtk/reference/meson.build
  • +1 -0
    gplugin-gtk/reference/version.xml.in
  • +1 -0
    gplugin-version.sh.in
  • +8 -0
    gplugin.sublime-project
  • +0 -292
    gplugin/CMakeLists.txt
  • +27 -1
    gplugin/gplugin-core.c
  • +0 -2
    gplugin/gplugin-core.h
  • +9 -1
    gplugin/gplugin-enums.c.tmpl
  • +1 -1
    gplugin/gplugin-enums.h.tmpl
  • +33 -23
    gplugin/gplugin-loader.c
  • +2 -10
    gplugin/gplugin-loader.h
  • +105 -19
    gplugin/gplugin-manager.c
  • +2 -2
    gplugin/gplugin-manager.h
  • +23 -41
    gplugin/gplugin-native-loader.c
  • +3 -6
    gplugin/gplugin-native-loader.h
  • +106 -516
    gplugin/gplugin-native-plugin.c
  • +6 -20
    gplugin/gplugin-native-plugin.h
  • +0 -2
    gplugin/gplugin-native-private.h
  • +13 -0
    gplugin/gplugin-options.c
  • +0 -2
    gplugin/gplugin-options.h
  • +252 -229
    gplugin/gplugin-plugin-info.c
  • +18 -20
    gplugin/gplugin-plugin-info.h
  • +73 -216
    gplugin/gplugin-plugin.c
  • +13 -20
    gplugin/gplugin-plugin.h
  • +1 -5
    gplugin/gplugin-private.h
  • +1 -1
    gplugin/gplugin-query.c
  • +0 -7
    gplugin/gplugin-uninstalled.pc.in
  • +54 -0
    gplugin/gplugin-version.c
  • +5 -6
    gplugin/gplugin-version.h.in
  • +0 -13
    gplugin/gplugin.pc.in
  • +283 -0
    gplugin/meson.build
  • +59 -0
    gplugin/reference/gplugin-docs.xml
  • +45 -0
    gplugin/reference/meson.build
  • +1 -0
    gplugin/reference/version.xml.in
  • +0 -155
    gplugin/tests/CMakeLists.txt
  • +0 -2
    gplugin/tests/bad-plugins/CMakeLists.txt
  • +3 -0
    gplugin/tests/bad-plugins/meson.build
  • +0 -2
    gplugin/tests/bind-local/CMakeLists.txt
  • +3 -0
    gplugin/tests/bind-local/meson.build
  • +0 -3
    gplugin/tests/dynamic-type/CMakeLists.txt
  • +10 -32
    gplugin/tests/dynamic-type/dynamic-type-provider.c
  • +8 -0
    gplugin/tests/dynamic-type/meson.build
  • +0 -3
    gplugin/tests/id-collision/CMakeLists.txt
  • +7 -0
    gplugin/tests/id-collision/meson.build
  • +0 -2
    gplugin/tests/load-on-query-fail/CMakeLists.txt
  • +3 -0
    gplugin/tests/load-on-query-fail/meson.build
  • +0 -2
    gplugin/tests/load-on-query-pass/CMakeLists.txt
  • +3 -0
    gplugin/tests/load-on-query-pass/meson.build
  • +140 -0
    gplugin/tests/meson.build
  • +0 -6
    gplugin/tests/plugins/CMakeLists.txt
  • +23 -0
    gplugin/tests/plugins/meson.build
  • +9 -0
    gplugin/tests/test-core.c
  • +1 -3
    gplugin/tests/test-option-group.c
  • +1 -1
    gplugin/tests/test-unresolved-symbol.c
  • +41 -50
    gplugin/tests/test-versioned-dependencies.c
  • +0 -1
    gplugin/tests/unresolved-symbol/CMakeLists.txt
  • +4 -0
    gplugin/tests/unresolved-symbol/meson.build
  • +2 -0
    gplugin/tests/unresolved-symbol/unresolved-symbol.c
  • +0 -12
    gplugin/tests/versioned-dependencies/CMakeLists.txt
  • +43 -0
    gplugin/tests/versioned-dependencies/meson.build
  • +0 -90
    lua/CMakeLists.txt
  • +11 -36
    lua/gplugin-lua-loader.c
  • +4 -8
    lua/gplugin-lua-loader.h
  • +96 -61
    lua/gplugin-lua-plugin.c
  • +9 -8
    lua/gplugin-lua-plugin.h
  • +29 -1
    lua/gplugin-lua-test-lgi.c
  • +52 -0
    lua/meson.build
  • +0 -58
    lua/tests/CMakeLists.txt
  • +1 -0
    lua/tests/lua-plugins/basic.lua
  • +29 -0
    lua/tests/meson.build
  • +158 -0
    meson.build
  • +62 -0
    meson_options.txt
  • +1 -1
    packaging/debian/changelog
  • +1 -0
    packaging/debian/clean
  • +18 -7
    packaging/debian/control
  • +2 -2
    packaging/debian/copyright
  • +2 -3
    packaging/debian/gir1.2-gplugin-0.0.install
  • +5 -6
    packaging/debian/libgplugin-dev.install
  • +2 -2
    packaging/debian/libgplugin-gtk-bin.install
  • +2 -3
    packaging/debian/libgplugin-gtk-dev.install
  • +1 -2
    packaging/debian/libgplugin-gtk0.install
  • +0 -11
    packaging/debian/libgplugin-gtk0.postinst
  • +0 -11
    packaging/debian/libgplugin-gtk0.postrm
  • +1 -0
    packaging/debian/libgplugin-gtk0.triggers
  • +1 -2
    packaging/debian/libgplugin-lua.install
  • +1 -2
    packaging/debian/libgplugin-python.install
  • +2 -0
    packaging/debian/libgplugin0-bin.install
  • +1 -4
    packaging/debian/libgplugin0.install
  • +0 -7
    packaging/debian/libgplugin0.postinst
  • +1 -0
    packaging/debian/libgplugin0.triggers
  • +29 -1
    packaging/debian/rules
  • +228 -0
    packaging/gplugin.spec.in
  • +4 -0
    packaging/meson.build
  • +0 -54
    perl/CMakeLists.txt
  • +2 -2
    perl/gplugin-perl-loader.c
  • +15 -15
    perl/gplugin-perl-plugin.c
  • +37 -0
    perl/meson.build
  • +0 -9
    plugins/CMakeLists.txt
  • +6 -0
    plugins/meson.build
  • +0 -4
    po/CMakeLists.txt
  • +3 -0
    po/meson.build
  • +0 -110
    python/CMakeLists.txt
  • +20 -57
    python/gplugin-python-loader.c
  • +5 -9
    python/gplugin-python-loader.h
  • +109 -64
    python/gplugin-python-plugin.c
  • +8 -7
    python/gplugin-python-plugin.h
  • +57 -0
    python/meson.build
  • +0 -65
    python/tests/CMakeLists.txt
  • +26 -0
    python/tests/meson.build
  • +67 -0
    tcc/gplugin-tcc-core.c
  • +203 -0
    tcc/gplugin-tcc-loader.c
  • +59 -0
    tcc/gplugin-tcc-loader.h
  • +185 -0
    tcc/gplugin-tcc-plugin.c
  • +62 -0
    tcc/gplugin-tcc-plugin.h
  • +28 -0
    tcc/meson.build
  • +13 -0
    tcc/tests/meson.build
  • +55 -0
    tcc/tests/plugins/basic-plugin.c
  • +49 -0
    tcc/tests/plugins/dependent.c
  • +42 -0
    tcc/tests/plugins/load-exception.c
  • +43 -0
    tcc/tests/plugins/load-failed.c
  • +43 -0
    tcc/tests/plugins/unload-failed.c
  • +31 -0
    tcc/tests/test-tcc-loader.c
  • +2 -2
    xsl/gtester-junit.xsl
  • --- a/.hgignore Mon Apr 18 22:32:13 2016 -0500
    +++ b/.hgignore Tue Jan 22 22:50:20 2019 -0600
    @@ -1,17 +1,19 @@
    syntax: glob
    .*.swp
    -*.cookies
    *.debhelper
    *.orig
    *.pyc
    +*.ui~
    +\#*.ui\#
    syntax: regexp
    +^artifacts\/
    ^build.*\/
    ^packaging\/debian\/tmp\/
    ^packaging\/debian\/(.+\.)?(substvars|debhelper\.log)$
    +^packaging\/debian\/build.*\/
    ^packaging\/debian\/libgplugin0?(-.+)?\/
    ^packaging\/debian\/gir1.2-gplugin-0.0\/
    ^packaging\/debian\/files$
    ^obj-x86_64-linux-gnu\/
    ^debian\/?$
    -.+\.sublime-workspace
    --- a/CMakeLists.txt Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,231 +0,0 @@
    -###############################################################################
    -# CMake Initialization
    -###############################################################################
    -set(CMAKE_LEGACY_CYGWIN_WIN32 0)
    -
    -cmake_minimum_required(VERSION 2.8.0)
    -
    -list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules)
    -
    -if(${CMAKE_VERSION} VERSION_LESS "2.8.3")
    - list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Compatibility)
    -endif(${CMAKE_VERSION} VERSION_LESS "2.8.3")
    -
    -if(${CMAKE_VERSION} VERSION_GREATER "3.0.0")
    - # allow reading of the LOCATION property
    - cmake_policy(SET CMP0026 OLD)
    -
    - # don't force target names to match a pattern
    - cmake_policy(SET CMP0037 OLD)
    -endif(${CMAKE_VERSION} VERSION_GREATER "3.0.0")
    -
    -###############################################################################
    -# Project Info
    -###############################################################################
    -project(gplugin C)
    -
    -set(GPLUGIN_MAJOR_VERSION 0)
    -set(GPLUGIN_MINOR_VERSION 27)
    -set(GPLUGIN_MICRO_VERSION 0)
    -set(GPLUGIN_EXTRA_VERSION)
    -
    -set(GPLUGIN_VERSION ${GPLUGIN_MAJOR_VERSION}.${GPLUGIN_MINOR_VERSION}.${GPLUGIN_MICRO_VERSION}${GPLUGIN_EXTRA_VERSION})
    -
    -set(LOCALE_DIR ${CMAKE_INSTALL_PREFIX}/locale)
    -add_definitions(-DLOCALEDIR="${LOCALE_DIR}")
    -
    -###############################################################################
    -# Options
    -###############################################################################
    -option(
    - BUILD_GIR
    - "Whether or not to build a GObject Introspection type library"
    - "On"
    -)
    -
    -option(
    - NLS
    - "Install translation files"
    - "On"
    -)
    -
    -option(
    - TESTING_ENABLED
    - "Whether or not to run unit tests while compiling"
    - "On"
    -)
    -
    -option(
    - BUILD_HELP2MAN
    - "Whether or not to build man pages from --help output"
    - "on"
    -)
    -
    -###############################################################################
    -# Dependencies
    -###############################################################################
    -if(APPLE)
    - # homebrew stuff
    - set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/local/lib/pkgconfig:/opt/X11/lib/pkgconfig")
    -
    - # look for homebrew, if it's installed theres so more mucking we need to do
    - find_program(BREW
    - NAMES brew
    - DOC "brew executable"
    - )
    - if(BREW)
    - execute_process(
    - COMMAND ${BREW} --prefix libffi
    - OUTPUT_VARIABLE FFI_PREFIX
    - OUTPUT_STRIP_TRAILING_WHITESPACE
    - )
    - if(FFI_PREFIX)
    - set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:${FFI_PREFIX}/lib/pkgconfig")
    - endif(FFI_PREFIX)
    -
    - execute_process(
    - COMMAND ${BREW} --prefix cairo
    - OUTPUT_VARIABLE CAIRO_PREFIX
    - OUTPUT_STRIP_TRAILING_WHITESPACE
    - )
    -
    - if(CAIRO_PREFIX)
    - set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:${CAIRO_PREFIX}/lib/pkgconfig")
    - endif(CAIRO_PREFIX)
    - endif(BREW)
    -
    - # fink and macports
    - set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/sw/lib/pkgconfig:/opt/local/lib/pkgconfig")
    -endif(APPLE)
    -
    -include(GNUInstallDirs)
    -include(FindPkgConfig)
    -include(PkgConfigVariable)
    -
    -if(BUILD_HELP2MAN)
    - include(help2man)
    -endif(BUILD_HELP2MAN)
    -
    -pkg_check_modules(GLIB REQUIRED glib-2.0>=2.34.0 gobject-2.0)
    -
    -# we separate gmodule out so our test aren't linked to it
    -pkg_check_modules(GMODULE REQUIRED gmodule-2.0)
    -
    -pkg_config_variable(glib-2.0 glib_genmarshal GLIB_GENMARSHAL)
    -pkg_config_variable(glib-2.0 glib_mkenums GLIB_MKENUMS)
    -
    -if(TESTING_ENABLED)
    - find_program(GTESTER
    - NAMES gtester
    - DOC "gtester executable"
    - )
    - mark_as_advanced(GTESTER)
    -
    - find_program(XSLTPROC
    - NAMES xsltproc
    - DOC "xsltproc executable"
    - )
    - mark_as_advanced(XSLTPROC)
    -endif(TESTING_ENABLED)
    -
    -###############################################################################
    -# NLS
    -###############################################################################
    -set(GETTEXT_PACKAGE gplugin)
    -
    -add_definitions(-DGETTEXT_PACKAGE="${GETTEXT_PACKAGE}")
    -
    -if(NLS)
    - include(Gettextize)
    -endif(NLS)
    -
    -###############################################################################
    -# Build Info
    -###############################################################################
    -add_definitions(
    - -std=c99
    - -g -g3
    - -O2
    - -DPREFIX="${CMAKE_INSTALL_PREFIX}"
    - -DLIBDIR="${CMAKE_INSTALL_LIBDIR}"
    - -DGPLUGIN_WEBSITE="http://bitbucket.org/gplugin/main"
    - -Wall
    - -Werror=format-security
    - -Wformat
    - -Wextra
    -)
    -
    -# check if we're using gcc
    -if(CMAKE_COMPILER_IS_GNUCC)
    - add_definitions(
    - -DGPLUGIN_UNUSED=__attribute__\(\(unused\)\)
    - -ggdb
    - )
    -else(CMAKE_COMPILER_IS_GNUCC)
    - add_definitions(
    - -DGPLUGIN_UNUSED=
    - )
    -endif(CMAKE_COMPILER_IS_GNUCC)
    -
    -include_directories(
    - ${CMAKE_SOURCE_DIR}
    - ${CMAKE_BINARY_DIR} # for built headers/sources
    - ${CMAKE_BINARY_DIR}/gplugin # for gplugin.h
    - ${GLIB_INCLUDE_DIRS}
    - ${GMODULE_INCLUDE_DIRS}
    -)
    -
    -link_directories(
    - ${GLIB_LIBRARY_DIRS}
    - ${GMODULE_LIBRARY_DIRS}
    -)
    -
    -###############################################################################
    -# Subdirectories
    -###############################################################################
    -add_subdirectory(gplugin)
    -add_subdirectory(gplugin-gtk)
    -add_subdirectory(plugins)
    -add_subdirectory(po)
    -
    -add_subdirectory(lua)
    -add_subdirectory(perl)
    -add_subdirectory(python)
    -
    -###############################################################################
    -# Install stuff
    -###############################################################################
    -# documentation
    -install(FILES ChangeLog INSTALL README HACKING DESTINATION ${CMAKE_INSTALL_DOCDIR})
    -
    -###############################################################################
    -# 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})
    -
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/COPYRIGHT Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,10 @@
    +The following individuals have contributed to this project.
    +
    +Ankit Vani <a@nevitus.org>
    +EionRobb
    +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>
    +Richard Laager <rlaager@pidgin.im>
    --- a/ChangeLog Mon Apr 18 22:32:13 2016 -0500
    +++ b/ChangeLog Tue Jan 22 22:50:20 2019 -0600
    @@ -1,3 +1,14 @@
    +0.28.0: 2019/01/22
    + * Fixed building on OSX with homebrew
    + * Added an RPM spec file
    + * Changed the build system to meson. See INSTALL for instructions.
    + * Added gplugin_plugin_get_dependent_plugins. (fixes #8)
    + * Remove ability to disable unit testing.
    + * Bumped the glib requirement to 2.40.0
    + * Added gtk-doc
    + * Added a Glade catalog for gplugin-gtk
    + * Added GPluginGtk-0.0.gir
    +
    0.27.0: 2016/04/18
    * Bumped the glib requirement to 2.34.0
    * Fix some error reporting with the native loader
    --- a/HACKING Mon Apr 18 22:32:13 2016 -0500
    +++ b/HACKING Tue Jan 22 22:50:20 2019 -0600
    @@ -7,7 +7,7 @@
    fixes. When a release is deemed done, it's merged back into develop and into
    default. hgflow takes care of all of this for us.
    -To add a feature please fork https://bitbucket.org/gplugin/main. Then clone
    +To add a feature please fork https://bitbucket.org/gplugin/gplugin. Then clone
    your fork. Once you have your fork cloned and hgflow setup and installed, type
    hg flow feature start $NAME_OF_YOUR_FEATURE$
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/HACKING.OSX Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,28 @@
    +There are a few notes about building on OSX.
    +
    +First off, building has *ONLY* been tested against homebrew. If you want to
    +support fink or macports, please let me know and I will merge your pull
    +request.
    +
    +Lua
    +===
    +
    +For the Lua loader to work, you need to install lgi from luarocks either
    +systemwide or to a virtual environment created by LuaDist, vert, or something
    +along those lines.
    +
    +When you're building lgi against homebrew you'll have to set the
    +PKG_CONFIG_PATH environment variable since homebrew does not install libffi
    +systemwide. This is easily done via:
    +
    + export PKG_CONFIG_PATH=$(brew --prefix libffi)/lib/pkgconfig
    +
    +and then running "luarocks install lgi"
    +
    +PYTHON
    +======
    +
    +If you're using homebrew, you need to install pygobject3 with
    +
    + brew install pygobject3 --with-python3
    +
    --- a/INSTALL Mon Apr 18 22:32:13 2016 -0500
    +++ b/INSTALL Tue Jan 22 22:50:20 2019 -0600
    @@ -1,9 +1,9 @@
    Dependencies
    ============
    GPlugin depends on the following at a bare minimum:
    - glib-2.0 >= 2.20.0
    + glib-2.0 >= 2.34.0
    gobject-introspection, libgirepository1.0-dev
    - cmake >= 2.8
    + meson >= 0.37.0
    gettext
    help2man
    a C compiler
    @@ -19,23 +19,17 @@
    Building
    ========
    -GPlugin uses CMake (http://www.cmake.org) as its build system. As such
    +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.
    -While it is not required, it is highly recommended that you use a separate
    -build dir. As such, these instructions use a separate build directory.
    +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:
    - mkdir build
    + meson build
    cd build
    - cmake ..
    - make
    - sudo make install
    + 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 a CMake user interface. For example, if you
    -have the CMake curses gui installed, you can do this by running "ccmake .."
    -from the build directory.
    -
    +you can do so at any time by using mesonconf in the build directory.
    --- a/cmake/Compatibility/CMakeParseArguments.cmake Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,138 +0,0 @@
    -# CMAKE_PARSE_ARGUMENTS(<prefix> <options> <one_value_keywords> <multi_value_keywords> args...)
    -#
    -# CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions for
    -# parsing the arguments given to that macro or function.
    -# It processes the arguments and defines a set of variables which hold the
    -# values of the respective options.
    -#
    -# The <options> argument contains all options for the respective macro,
    -# i.e. keywords which can be used when calling the macro without any value
    -# following, like e.g. the OPTIONAL keyword of the install() command.
    -#
    -# The <one_value_keywords> argument contains all keywords for this macro
    -# which are followed by one value, like e.g. DESTINATION keyword of the
    -# install() command.
    -#
    -# The <multi_value_keywords> argument contains all keywords for this macro
    -# which can be followed by more than one value, like e.g. the TARGETS or
    -# FILES keywords of the install() command.
    -#
    -# When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the
    -# keywords listed in <options>, <one_value_keywords> and
    -# <multi_value_keywords> a variable composed of the given <prefix>
    -# followed by "_" and the name of the respective keyword.
    -# These variables will then hold the respective value from the argument list.
    -# For the <options> keywords this will be TRUE or FALSE.
    -#
    -# All remaining arguments are collected in a variable
    -# <prefix>_UNPARSED_ARGUMENTS, this can be checked afterwards to see whether
    -# your macro was called with unrecognized parameters.
    -#
    -# As an example here a my_install() macro, which takes similar arguments as the
    -# real install() command:
    -#
    -# function(MY_INSTALL)
    -# set(options OPTIONAL FAST)
    -# set(oneValueArgs DESTINATION RENAME)
    -# set(multiValueArgs TARGETS CONFIGURATIONS)
    -# cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
    -# ...
    -#
    -# Assume my_install() has been called like this:
    -# my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub)
    -#
    -# After the cmake_parse_arguments() call the macro will have set the following
    -# variables:
    -# MY_INSTALL_OPTIONAL = TRUE
    -# MY_INSTALL_FAST = FALSE (this option was not used when calling my_install()
    -# MY_INSTALL_DESTINATION = "bin"
    -# MY_INSTALL_RENAME = "" (was not used)
    -# MY_INSTALL_TARGETS = "foo;bar"
    -# MY_INSTALL_CONFIGURATIONS = "" (was not used)
    -# MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL"
    -#
    -# You can the continue and process these variables.
    -#
    -# Keywords terminate lists of values, e.g. if directly after a one_value_keyword
    -# another recognized keyword follows, this is interpreted as the beginning of
    -# the new option.
    -# E.g. my_install(TARGETS foo DESTINATION OPTIONAL) would result in
    -# MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION would
    -# be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor.
    -
    -#=============================================================================
    -# Copyright 2010 Alexander Neundorf <neundorf@kde.org>
    -#
    -# Distributed under the OSI-approved BSD License (the "License");
    -# see accompanying file Copyright.txt for details.
    -#
    -# This software is distributed WITHOUT ANY WARRANTY; without even the
    -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    -# See the License for more information.
    -#=============================================================================
    -# (To distribute this file outside of CMake, substitute the full
    -# License text for the above reference.)
    -
    -
    -if(__CMAKE_PARSE_ARGUMENTS_INCLUDED)
    - return()
    -endif()
    -set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE)
    -
    -
    -function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames)
    - # first set all result variables to empty/FALSE
    - foreach(arg_name ${_singleArgNames} ${_multiArgNames})
    - set(${prefix}_${arg_name})
    - endforeach()
    -
    - foreach(option ${_optionNames})
    - set(${prefix}_${option} FALSE)
    - endforeach()
    -
    - set(${prefix}_UNPARSED_ARGUMENTS)
    -
    - set(insideValues FALSE)
    - set(currentArgName)
    -
    - # now iterate over all arguments and fill the result variables
    - foreach(currentArg ${ARGN})
    - list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword
    - list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword
    - list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword
    -
    - if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1)
    - if(insideValues)
    - if("${insideValues}" STREQUAL "SINGLE")
    - set(${prefix}_${currentArgName} ${currentArg})
    - set(insideValues FALSE)
    - elseif("${insideValues}" STREQUAL "MULTI")
    - list(APPEND ${prefix}_${currentArgName} ${currentArg})
    - endif()
    - else()
    - list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg})
    - endif()
    - else()
    - if(NOT ${optionIndex} EQUAL -1)
    - set(${prefix}_${currentArg} TRUE)
    - set(insideValues FALSE)
    - elseif(NOT ${singleArgIndex} EQUAL -1)
    - set(currentArgName ${currentArg})
    - set(${prefix}_${currentArgName})
    - set(insideValues "SINGLE")
    - elseif(NOT ${multiArgIndex} EQUAL -1)
    - set(currentArgName ${currentArg})
    - set(${prefix}_${currentArgName})
    - set(insideValues "MULTI")
    - endif()
    - endif()
    -
    - endforeach()
    -
    - # propagate the result variables to the caller:
    - foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames})
    - set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE)
    - endforeach()
    - set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE)
    -
    -endfunction()
    --- a/cmake/Modules/GObjectIntrospection.cmake Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,233 +0,0 @@
    -include(CMakeParseArguments)
    -include(FindPkgConfig)
    -
    -set(_PKG_CONFIG_MODULE "gobject-introspection-1.0")
    -
    -pkg_check_modules(GOBJECT_INTROSPECTION REQUIRED ${_PKG_CONFIG_MODULE})
    -
    -###############################################################################
    -# Helpers
    -###############################################################################
    -# this macro will run "pkg-config --variable=VARIABLE ${_PKG_CONFIG_MODULE}"
    -# and store the result in OUTPUT_VARIABLE
    -macro(_pkg_config_variable VARIABLE OUTPUT_VARIABLE)
    - execute_process(
    - COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=${VARIABLE} ${_PKG_CONFIG_MODULE}
    - OUTPUT_VARIABLE ${OUTPUT_VARIABLE}
    - OUTPUT_STRIP_TRAILING_WHITESPACE
    - )
    -endmacro(_pkg_config_variable)
    -
    -# this macro will prefix every item in _list with _prefix and return it in
    -# _newlist.
    -macro(_gir_list_prefix _newlist _list _prefix)
    - set(${_newlist})
    - foreach(_item IN LISTS ${_list})
    - list(APPEND ${_newlist} ${_prefix}${_item})
    - endforeach(_item)
    -endmacro(_gir_list_prefix)
    -
    -###############################################################################
    -# use the pkg-config to grab a bunch of variables from the
    -# gobject-introspection.pc file
    -###############################################################################
    -_pkg_config_variable(g_ir_scanner GIR_SCANNER)
    -_pkg_config_variable(g_ir_compiler GIR_COMPILER)
    -
    -# CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT is only set when the variable is
    -# actually set, so we need to create another variable to track that.
    -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
    - set(_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX} CACHE INTERNAL
    - "holds the default install path if cmake set it")
    - mark_as_advanced(_INSTALL_PREFIX)
    -endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
    -
    -# check if cmake_install_prefix was specified, if so build our paths using that
    -if(_INSTALL_PREFIX)
    - _pkg_config_variable(girdir GIR_GIRDIR)
    - _pkg_config_variable(typelibdir GIR_TYPELIBDIR)
    -else(_INSTALL_PREFIX)
    - set(GIR_GIRDIR "${CMAKE_INSTALL_FULL_DATAROOTDIR}/gir-1.0")
    - set(GIR_TYPELIBDIR "${CMAKE_INSTALL_FULL_LIBDIR}/girepository-1.0")
    -endif(_INSTALL_PREFIX)
    -
    -###############################################################################
    -# The main function
    -###############################################################################
    -function(gobject_introspection _FIRST_ARG)
    - set(options QUIET VERBOSE)
    - set(oneValueArgs
    - FILENAME
    - FORMAT
    - LIBRARY
    - NAMESPACE
    - NSVERSION
    - PROGRAM
    - PROGRAM_ARG
    - )
    - set(multiValueArgs
    - BUILT_SOURCES
    - CFLAGS
    - COMPILER_ARGS
    - HEADERS
    - IDENTIFIER_PREFIXES
    - PACKAGES
    - SCANNER_ARGS
    - SOURCES
    - SYMBOL_PREFIXES
    - )
    -
    - CMAKE_PARSE_ARGUMENTS(GIR "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN})
    -
    - if(ADD_GIR_UNPARSED_ARGUMENTS)
    - message(FATAL_ERROR "Unknown keys given to ADD_GIR_INTROSPECTION(): \"${ADD_GIR_UNPARSED_ARGUMENTS}\"")
    - endif(ADD_GIR_UNPARSED_ARGUMENTS)
    -
    - ###########################################################################
    - # make sure that the user set some variables...
    - ###########################################################################
    - if(NOT GIR_FILENAME)
    - message(FATAL_ERROR "No gir filename given")
    - endif(NOT GIR_FILENAME)
    -
    - if(NOT GIR_NAMESPACE)
    - # the caller didn't give us a namespace, try to grab it from the filename
    - string(REGEX REPLACE "([^-]+)-.*" "\\1" GIR_NAMESPACE "${GIR_FILENAME}")
    - if(NOT GIR_NAMESPACE)
    - message(FATAL_ERROR "No namespace given and couldn't find one in FILENAME")
    - endif(NOT GIR_NAMESPACE)
    - endif(NOT GIR_NAMESPACE)
    -
    - if(NOT GIR_NSVERSION)
    - # the caller didn't give us a namespace version, try to grab it from the filemenu
    - string(REGEX REPLACE ".*-([^-]+).gir" "\\1" GIR_NSVERSION "${GIR_FILENAME}")
    - if(NOT GIR_NSVERSION)
    - message(FATAL_ERROR "No namespace version given and couldn't find one in FILENAME")
    - endif(NOT GIR_NSVERSION)
    - endif(NOT GIR_NSVERSION)
    -
    - if(NOT GIR_CFLAGS)
    - get_directory_property(GIR_CFLAGS INCLUDE_DIRECTORIES)
    - _gir_list_prefix(GIR_REAL_CFLAGS GIR_CFLAGS "-I")
    - endif(NOT GIR_CFLAGS)
    -
    - ###########################################################################
    - # Fix up some of our arguments
    - ###########################################################################
    - if(GIR_VERBOSE)
    - set(GIR_VERBOSE "--verbose")
    - else(GIR_VERBOSE)
    - set(GIR_VERBOSE "")
    - endif(GIR_VERBOSE)
    -
    - if(GIR_QUIET)
    - set(GIR_QUIET "--quiet")
    - else(GIR_QUIET)
    - set(GIR_QUIET "")
    - endif(GIR_QUIET)
    -
    - if(GIR_FORMAT)
    - set(GIR_FORMAT "--format=${GIR_FORMAT}")
    - endif(GIR_FORMAT)
    -
    - # if library is set, we need to prepend --library= on to it
    - if(GIR_LIBRARY)
    - set(GIR_REAL_LIBRARY "--library=${GIR_LIBRARY}")
    - endif(GIR_LIBRARY)
    -
    - # if program has been set, we prepend --program= on to it
    - if(GIR_PROGRAM)
    - set(GIR_PROGRAM "--program=${GIR_PROGRAM}")
    - endif(GIR_PROGRAM)
    -
    - # if program_arg has been set, we prepend --program-arg= on to it
    - if(GIR_PROGRAM_ARG)
    - set(GIR_PROGRAM_ARG "--program-arg=${GIR_PROGRAM_ARG}")
    - endif(GIR_PROGRAM_ARG)
    -
    - ###########################################################################
    - # Clean up any of the multivalue items that all need to be prefixed
    - ###########################################################################
    -
    - # if the user specified IDENTIFIER_PREFIXES we need to prefix each with --identifier-prefix
    - if(GIR_IDENTIFIER_PREFIXES)
    - _gir_list_prefix(GIR_REAL_IDENTIFIER_PREFIXES GIR_IDENTIFIER_PREFIXES "--identifier-prefix=")
    - endif(GIR_IDENTIFIER_PREFIXES)
    -
    - # if the user specified SYMBOL_PREFIXES we need to prefix each with --symbol-prefix=
    - if(GIR_SYMBOL_PREFIXES)
    - _gir_list_prefix(GIR_REAL_SYMBOL_PREFIXES GIR_SYMBOL_PREFIXES "--symbol-prefix=")
    - endif(GIR_SYMBOL_PREFIXES)
    -
    - # if the user specified PACKAGES we need to prefix each with --pkg
    - if(GIR_PACKAGES)
    - _gir_list_prefix(GIR_REAL_PACKAGES GIR_PACKAGES "--pkg=")
    - endif(GIR_PACKAGES)
    -
    - # if the user specified BUILT_SOURCES, we need to get their paths since
    - # they could be in CMAKE_CURRENT_BUILD_DIR
    - if(GIR_BUILT_SOURCES)
    - set(GIR_REAL_BUILT_SOURCES)
    -
    - foreach(ITEM ${GIR_BUILT_SOURCES})
    - get_source_file_property(LOCATION ${ITEM} LOCATION)
    - list(APPEND GIR_REAL_BUILT_SOURCES "${LOCATION}")
    - endforeach(ITEM)
    - endif(GIR_BUILT_SOURCES)
    -
    - ###########################################################################
    - # Add the custom commands
    - ###########################################################################
    - set(ENV{CFLAGS} ${GIR_REAL_CFLAGS})
    - add_custom_command(
    - OUTPUT ${GIR_FILENAME}
    - COMMAND ${GIR_SCANNER} ${GIR_SCANNER_ARGS}
    - --namespace=${GIR_NAMESPACE}
    - --nsversion=${GIR_NSVERSION}
    - ${GIR_REAL_CFLAGS}
    - ${GIR_FORMAT}
    - ${GIR_REAL_LIBRARY}
    - ${GIR_PROGRAM} ${GIR_PROGRAM_ARGS}
    - ${GIR_QUIET} ${GIR_VERBOSE}
    - ${GIR_REAL_IDENTIFIER_PREFIXES}
    - ${GIR_REAL_SYMBOL_PREFIXES}
    - ${GIR_REAL_PACKAGES}
    - --no-libtool
    - -L${CMAKE_CURRENT_BINARY_DIR}
    - --output=${CMAKE_CURRENT_BINARY_DIR}/${GIR_FILENAME}
    - ${GIR_SOURCES}
    - ${GIR_REAL_BUILT_SOURCES}
    - DEPENDS ${GIR_LIBRARY}
    - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    - VERBATIM
    - )
    -
    - add_custom_target("gir ${GIR_FILENAME}" ALL DEPENDS ${GIR_LIBRARY} ${GIR_FILENAME})
    -
    - install(
    - FILES ${CMAKE_CURRENT_BINARY_DIR}/${GIR_FILENAME}
    - DESTINATION ${GIR_GIRDIR}
    - )
    -
    - # create the name of the typelib
    - string(REPLACE ".gir" ".typelib" GIR_TYPELIB "${GIR_FILENAME}")
    -
    - add_custom_command(
    - COMMAND ${GIR_COMPILER} ${GIR_COMPILER_ARGS}
    - ${CMAKE_CURRENT_BINARY_DIR}/${GIR_FILENAME}
    - --output=${CMAKE_CURRENT_BINARY_DIR}/${GIR_TYPELIB}
    - OUTPUT ${GIR_TYPELIB}
    - DEPENDS ${GIR_FILENAME}
    - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
    - )
    -
    - add_custom_target("typelib ${GIR_TYPELIB}" ALL DEPENDS ${GIR_LIBRARY} ${GIR_FILENAME} ${GIR_TYPELIB})
    - install(
    - FILES ${CMAKE_CURRENT_BINARY_DIR}/${GIR_TYPELIB}
    - DESTINATION ${GIR_TYPELIBDIR}
    - )
    -
    - string(TOUPPER ${GIR_LIBRARY} GIR_TARGET)
    - set(${GIR_TARGET}_GIR_TARGETS "gir ${GIR_FILENAME}" "typelib ${GIR_TYPELIB}" PARENT_SCOPE)
    -endfunction(gobject_introspection)
    -
    --- a/cmake/Modules/Gettextize.cmake Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,190 +0,0 @@
    -include(CMakeParseArguments)
    -
    -###############################################################################
    -# homebrew hackery
    -###############################################################################
    -# homebrew's gettext is keyonly, so we need to append it's path
    -if(APPLE)
    - find_program(BREW brew)
    - if(BREW)
    - execute_process(COMMAND ${BREW} --prefix gettext
    - OUTPUT_VARIABLE GETTEXT_PREFIX
    - OUTPUT_STRIP_TRAILING_WHITESPACE)
    - if(GETTEXT_PREFIX)
    - set(GETTEXT_PATH "${GETTEXT_PREFIX}/bin")
    - endif(GETTEXT_PREFIX)
    - endif(BREW)
    -endif(APPLE)
    -
    -###############################################################################
    -# Dependencies
    -###############################################################################
    -find_program(XGETTEXT_EXECUTABLE xgettext ${GETTEXT_PATH})
    -if(NOT XGETTEXT_EXECUTABLE)
    - message(FATAL_ERROR "Failed to find xgettext")
    -endif(NOT XGETTEXT_EXECUTABLE)
    -
    -find_program(GETTEXT_MSGFMT_EXECUTABLE msgfmt ${GETTEXT_PATH})
    -if(NOT GETTEXT_MSGFMT_EXECUTABLE)
    - message(FATAL_ERROR "Failed to find msgfmt")
    -endif(NOT GETTEXT_MSGFMT_EXECUTABLE)
    -
    -find_program(GETTEXT_MSGMERGE_EXECUTABLE msgmerge ${GETTEXT_PATH})
    -if(NOT GETTEXT_MSGMERGE_EXECUTABLE)
    - message(FATAL_ERROR "Failed to find msgmerge")
    -endif(NOT GETTEXT_MSGMERGE_EXECUTABLE)
    -
    -set(DEFAULT_XGETTEXT_OPTIONS
    - --package-name=${PROJECT_NAME}
    - --package-version=${VERSION}
    -)
    -
    -if(NOT DEFINED LOCALE_DIR)
    - set(LOCALE_DIR ${CMAKE_INSTALL_PREFIX}/share/locale/)
    - message(AUTHOR_WARNING "LOCALE_DIR is not set, using ${LOCALE_DIR}")
    -endif(NOT DEFINED LOCALE_DIR)
    -
    -if(NOT DEFINED GETTEXT_PACKAGE)
    - set(GETTEXT_PACKAGE ${PROJECT_NAME})
    - message(AUTHOR_WARNING "GETTEXT_PACKAGE is not set, using ${GETTEXT_PACKAGE}")
    -endif(NOT DEFINED GETTEXT_PACKAGE)
    -
    -###############################################################################
    -# Functions
    -###############################################################################
    -function(GETTEXTIZE_POT_FILE _FIRST_ARG)
    - set(options SORT NO_DEFAULT_KEYWORDS NO_ESCAPE NO_COMMENTS)
    - set(oneValueArgs FILENAME LANGUAGES)
    - set(multiValueArgs SOURCES BUILT_SOURCES KEYWORDS)
    -
    - cmake_parse_arguments(
    - POT "${options}" "${oneValueArgs}" "${multiValueArgs}"
    - ${_FIRST_ARG} ${ARGN}
    - )
    -
    - if(POT_UNPARSED_ARGUMENTS)
    - message(FATAL_ERROR "Unknown keys given to pot_file(): "
    - "\"${POT_UNPARSED_ARGUMENTS}\"")
    - endif(POT_UNPARSED_ARGUMENTS)
    -
    - if(NOT POT_FILENAME)
    - set(POT_FILENAME ${GETTEXT_PACKAGE}.pot)
    - message(AUTHOR_WARNING "No filename specified, using ${POT_FILENAME}")
    - endif(NOT POT_FILENAME)
    -
    - if(NOT POT_SOURCES)
    - message(FATAL_ERROR "No sources specified")
    - endif(NOT POT_SOURCES)
    -
    - if(NOT POT_NO_ESCAPE)
    - set(POT_ESCAPE --escape)
    - endif(NOT POT_NO_ESCAPE)
    -
    - if(POT_COMMENTS)
    - set(POT_COMMENTS "--add-comments=${POT_COMMENTS}")
    - endif(POT_COMMENTS)
    -
    - if(POT_SORT)
    - set(POT_SORT -s)
    - endif(POT_SORT)
    -
    - # handle keywords
    - if(NOT POT_NO_DEFAULT_KEYWORDS)
    - list(INSERT POT_KEYWORDS 0 _ N_ C_:1c,2 NC_:1c,2)
    - endif(NOT POT_NO_DEFAULT_KEYWORDS)
    -
    - if(POT_KEYWORDS)
    - set(_keywords)
    -
    - foreach(_kw ${POT_KEYWORDS})
    - list(APPEND _keywords "--keyword=${_kw}")
    - endforeach(_kw)
    - set(POT_KEYWORDS ${_keywords})
    - endif(POT_KEYWORDS)
    -
    - # handle languages
    - if(POT_LANGUAGES)
    - set(_languages)
    -
    - foreach(_lang in ${POT_LANGUAGES})
    - list(APPEND _languages "--language=${_lang}")
    - endforeach(_lang)
    - set(POT_LANGUAGES ${_languages})
    - endif(POT_LANGUAGES)
    -
    - # now tweak the sources
    - set(POT_REAL_BUILT_SOURCES)
    - if(POT_BUILT_SOURCES)
    - foreach(_item ${POT_BUILT_SOURCES})
    - get_source_file_property(_location ${_item} LOCATION)
    - list(APPEND POT_REAL_BUILT_SOURCES "${_location}")
    - endforeach(_item)
    - endif(POT_BUILT_SOURCES)
    -
    - add_custom_command(
    - OUTPUT ${POT_FILENAME}
    - COMMAND ${XGETTEXT_EXECUTABLE}
    - ${POT_SORT} ${POT_KEYWORDS} ${POT_LANGUAGES} ${POT_ESCAPE}
    - ${POT_COMMENTS}
    - -o ${CMAKE_CURRENT_BINARY_DIR}/${POT_FILENAME}
    - ${POT_SOURCES} ${POT_REAL_BUILT_SOURCES}
    - DEPENDS ${POT_SOURCES} ${POT_BUILT_SOURCES}
    - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    - VERBATIM
    - )
    -
    - add_custom_target("${POT_FILENAME} potfile" ALL DEPENDS ${POT_FILENAME})
    -endfunction(GETTEXTIZE_POT_FILE)
    -
    -function(GETTEXTIZE_TRANSLATIONS)
    - set(options UPDATE)
    - set(oneValueArgs)
    - set(multiValueArgs)
    -
    - CMAKE_PARSE_ARGUMENTS(
    - PO "${options}" "${oneValueArgs}" "${multiValueArgs}"
    - ${ARGV1} ${ARGN}
    - )
    -
    - if(PO_UNPARSED_ARGUMENTS)
    - message(
    - FATAL_ERROR "Unknown keys given to GETTEXTIZE_TRANSLATIONS(): "
    - "\"${PO_UNPARSED_ARGUMENTS}\""
    - )
    - endif(PO_UNPARSED_ARGUMENTS)
    -
    - file(GLOB _pos *.po)
    - set(_gmos)
    -
    - foreach(_po ${_pos})
    - set(_update)
    - if(PO_UPDATE)
    - set(_update COMMAND ${GETTEXT_MSGMERGE_EXECUTABLE} --quiet --update --backup=none -s ${_po} ${_po})
    - endif(PO_UPDATE)
    -
    - get_filename_component(_base ${_po} NAME_WE)
    -
    - set(_install_dir ${LOCALE_DIR}/${_base}/LC_MESSAGES/)
    - set(_install_file ${GETTEXT_DOMAIN}.mo)
    -
    - set(_gmo ${_base}.gmo)
    - list(APPEND _gmos ${_gmo})
    -
    - add_custom_command(
    - OUTPUT ${_gmo}
    - ${_update}
    - COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} -o ${_gmo} ${_po}
    - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
    - DEPENDS ${_po}
    - )
    -
    - install(
    - FILES ${CMAKE_CURRENT_BINARY_DIR}/${_gmo}
    - DESTINATION ${_install_dir}
    - RENAME ${_install_file}
    - )
    - endforeach(_po)
    -
    - add_custom_target("translations" ALL DEPENDS ${_gmos})
    -endfunction(GETTEXTIZE_TRANSLATIONS)
    -
    --- a/cmake/Modules/PkgConfigVariable.cmake Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,14 +0,0 @@
    -include(FindPkgConfig)
    -
    -macro(pkg_config_variable MODULE VARIABLE OUTPUT_VARIABLE)
    - set(_output)
    -
    - execute_process(
    - COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=${VARIABLE} ${MODULE}
    - OUTPUT_VARIABLE _output
    - OUTPUT_STRIP_TRAILING_WHITESPACE
    - )
    -
    - set(${OUTPUT_VARIABLE} ${_output} CACHE FILEPATH "${MODULE} ${VARIABLE}")
    -endmacro(pkg_config_variable)
    -
    --- a/cmake/Modules/help2man.cmake Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,74 +0,0 @@
    -include(CMakeParseArguments)
    -include(FindPkgConfig)
    -
    -find_program(HELP2MAN
    - NAMES help2man
    - DOC "help2man executable"
    -)
    -
    -if(NOT HELP2MAN)
    - message(FATAL_ERROR "failed to find help2man")
    -endif(NOT HELP2MAN)
    -
    -function(help2man _FIRST_ARG)
    - set(oneValueArgs TARGET OUTPUT SECTION NAME HELP_OPTION VERSION_OPTION)
    -
    - CMAKE_PARSE_ARGUMENTS(_HELP2MAN "" "${oneValueArgs}" "" ${_FIRST_ARG} ${ARGN})
    -
    - if(ADD__HELP2MAN_UNPARSED_ARGUMENTS)
    - message(FATAL_ERROR "Unknown keys given to help2man(): \"${ADD__HELP2MAN_UNPARSED_ARGUMENTS}\"")
    - endif(ADD__HELP2MAN_UNPARSED_ARGUMENTS)
    -
    - # validate arguments
    - if(NOT _HELP2MAN_TARGET)
    - message(FATAL_ERROR "No target specified")
    - endif(NOT _HELP2MAN_TARGET)
    -
    - if(NOT _HELP2MAN_OUTPUT)
    - message(FATAL_ERROR "No output specified")
    - endif(NOT _HELP2MAN_OUTPUT)
    -
    - if(NOT _HELP2MAN_SECTION)
    - set(_HELP2MAN_SECTION 1)
    - endif(NOT _HELP2MAN_SECTION)
    -
    - # additional options
    - set(_HELP2MAN_OPTIONS)
    - if(_HELP2MAN_NAME)
    - set(_HELP2MAN_OPTIONS ${_HELP2MAN_OPTIONS} -n "${_HELP2MAN_NAME}")
    - endif(_HELP2MAN_NAME)
    -
    - if(_HELP2MAN_HELP_OPTION)
    - set(_HELP2MAN_OPTIONS ${_HELP2MAN_OPTIONS} -h "${_HELP2MAN_HELP_OPTION}")
    - endif(_HELP2MAN_HELP_OPTION)
    -
    - if(_HELP2MAN_VERSION_OPTION)
    - set(_HELP2MAN_OPTIONS ${_HELP2MAN_OPTIONS} -v "${_HELP2MAN_VERSION_OPTION}")
    - endif(_HELP2MAN_VERSION_OPTION)
    -
    - # now find the executable
    - get_target_property(_HELP2MAN_EXEC ${_HELP2MAN_TARGET} RUNTIME_OUTPUT_NAME)
    - if(NOT _HELP2MAN_EXEC)
    - get_target_property(_HELP2MAN_EXEC ${_HELP2MAN_TARGET} LOCATION)
    - endif(NOT _HELP2MAN_EXEC)
    -
    - add_custom_target(${_HELP2MAN_OUTPUT} ALL
    - COMMAND ${HELP2MAN}
    - -s ${_HELP2MAN_SECTION}
    - -o ${_HELP2MAN_OUTPUT}
    - --no-info --no-discard-stderr
    - ${_HELP2MAN_OPTIONS}
    - ${_HELP2MAN_EXEC}
    - DEPENDS ${_HELP2MAN_TARGET}
    - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
    - )
    -
    - set(_HELP2MAN_DIR share/man/)
    - if(CMAKE_SYSTEM_NAME MATCHES .*BSD.*)
    - set(_HELP2MAN_DIR man/)
    - endif(CMAKE_SYSTEM_NAME MATCHES .*BSD.*)
    -
    - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${_HELP2MAN_OUTPUT} DESTINATION ${_HELP2MAN_DIR}man${_HELP2MAN_SECTION})
    -endfunction(help2man)
    -
    -
    --- a/cmake/Toolchains/cygwin-mingw.cmake Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,8 +0,0 @@
    -set(CMAKE_SYSTEM_NAME Windows)
    -
    -set(CMAKE_C_COMPILER i686-pc-mingw32-gcc)
    -set(CMAKE_CXX_COMPILER i686-pc-mingw32-g++)
    -set(CMAKE_RC_COMPILER i686-pc-mingw32-windres)
    -
    -set(CMAKE_FIND_ROOT_PATH /usr/i686-pc-mingw32)
    -
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/convey.yml Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,163 @@
    +environment:
    + - PACKAGECLOUD_REPO=experimental
    + - ARCH=amd64
    + - BUILD_NUMBER
    +
    +tasks:
    + clean:
    + type: convey/clean
    + files:
    + - alpine-edge-amd64
    + - debian-buster-amd64
    + - debian-stretch-amd64
    + - fedora-28-amd64
    + - fedora-29-amd64
    + - opensuse-tumbleweed-amd64
    + - pvs-studio
    + - scanbuild
    + - ubuntu-xenial-amd64
    + - ubuntu-bionic-amd64
    +
    + import:
    + type: docker/import
    + files: .:.
    +
    + import-artifacts:
    + type: docker/import
    + files: ${DISTRO}-${VERSION}-${ARCH}
    +
    + build:
    + type: docker/run
    + image: gplugin/builders:${DISTRO}-${VERSION}-${ARCH}
    +
    + export:
    + type: docker/export
    + files: ${DISTRO}-${VERSION}-${ARCH}
    +
    + package-cloud:
    + type: docker/run
    + image: rwgrim/package_cloud:latest
    + environment:
    + - PACKAGECLOUD_TOKEN
    + command: push --yes --verbose pidgin/${PACKAGECLOUD_REPO}/${DISTRO}/${VERSION} ${PATTERN}
    + workdir: ${CONVEY_WORKSPACE}/${DISTRO}-${VERSION}-${ARCH}
    +
    + publish-deb:
    + type: convey/extend
    + task: package-cloud
    + environment: [PATTERN=*.deb]
    +
    + publish-debsrc:
    + type: convey/extend
    + task: package-cloud
    + environment: [PATTERN=*.dsc]
    +
    + publish-rpm:
    + type: convey/extend
    + 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:
    + - tasks: clean
    +
    + alpine-edge-amd64:
    + environment: [DISTRO=alpine, VERSION=edge]
    + 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]
    + stages:
    + - tasks: [import, build, export]
    + fedora-29-amd64:
    + environment: [DISTRO=fedora, VERSION=29]
    + stages:
    + - tasks: [import, build, export]
    +
    + opensuse-tumbleweed-amd64:
    + environment: [DISTRO=opensuse, VERSION=tumbleweed]
    + stages:
    + - tasks: [import, build, export]
    +
    + pvs-studio:
    + stages:
    + - tasks: [import, pvs-studio, pvs-studio-export]
    +
    + scanbuild:
    + stages:
    + - tasks: [import, scanbuild, scanbuild-export]
    +
    + ubuntu-bionic-amd64:
    + environment: [DISTRO=ubuntu, VERSION=bionic]
    + stages:
    + - tasks: [import, build, export]
    +
    + 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=fedora
    + - VERSION=28
    + tasks: [import-artifacts, publish-rpm]
    + - environment:
    + - DISTRO=fedora
    + - VERSION=29
    + tasks: [import-artifacts, publish-rpm]
    + - environment:
    + - DISTRO=ubuntu
    + - VERSION=bionic
    + tasks: [import-artifacts, publish-deb, publish-debsrc]
    +
    +meta-plans:
    + alpine:
    + plans:
    + - alpine-edge-amd64
    + debian:
    + plans:
    + - debian-stretch-amd64
    + - debian-buster-amd64
    + fedora:
    + plans:
    + - fedora-28-amd64
    + - fedora-29-amd64
    + opensuse:
    + plans:
    + - opensuse-tumbleweed-amd64
    + ubuntu:
    + plans:
    + - ubuntu-bionic-amd64
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk-viewer/data/gplugin-gtk-viewer.gresource.xml Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,6 @@
    +<?xml version="1.0" encoding="UTF-8"?>
    +<gresources>
    + <gresource prefix="/org/bitbucket/gplugin/gplugin/viewer/">
    + <file compressed="true">window.ui</file>
    + </gresource>
    +</gresources>
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk-viewer/data/window.ui Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,65 @@
    +<?xml version="1.0" encoding="UTF-8"?>
    +<!-- Generated with glade 3.22.1 -->
    +<interface>
    + <requires lib="gtk+" version="3.20"/>
    + <requires lib="gplugin-gtk" version="0.28"/>
    + <template class="viewer" parent="GtkWindow">
    + <property name="can_focus">False</property>
    + <property name="border_width">12</property>
    + <property name="title" translatable="yes">GPlugin Viewer</property>
    + <child>
    + <placeholder/>
    + </child>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">12</property>
    + <child>
    + <object class="GtkScrolledWindow">
    + <property name="visible">True</property>
    + <property name="can_focus">True</property>
    + <property name="hscrollbar_policy">never</property>
    + <property name="shadow_type">in</property>
    + <child>
    + <object class="GPluginGtkView" id="view">
    + <property name="visible">True</property>
    + <property name="can_focus">True</property>
    + <property name="headers_visible">False</property>
    + <property name="headers_clickable">False</property>
    + <child internal-child="selection">
    + <object class="GtkTreeSelection"/>
    + </child>
    + </object>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">True</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GPluginGtkPluginInfo" id="info">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label_xalign">0</property>
    + <property name="shadow_type">none</property>
    + <child type="label">
    + <object class="GtkLabel">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">__glade_unnamed_5</property>
    + </object>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">True</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + </child>
    + </template>
    +</interface>
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk-viewer/gplugin-gtk-viewer-window.c Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,48 @@
    +/*
    + * talkatu
    + * Copyright (C) 2017-2018 Gary Kramlich <grim@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 <gtk/gtk.h>
    +
    +#include "gplugin-gtk-viewer-window.h"
    +
    +G_DEFINE_TYPE(GPluginGtkViewerWindow, gplugin_gtk_viewer_window, GTK_TYPE_WINDOW)
    +
    +/******************************************************************************
    + * GObject Stuff
    + *****************************************************************************/
    +static void
    +gplugin_gtk_viewer_window_init(GPluginGtkViewerWindow *window) {
    + gtk_widget_init_template(GTK_WIDGET(window));
    +}
    +
    +static void
    +gplugin_gtk_viewer_window_class_init(GPluginGtkViewerWindowClass *klass) {
    + gtk_widget_class_set_template_from_resource(
    + GTK_WIDGET_CLASS(klass),
    + "/org/bitbucket/gplugin/gplugin/viewer/window.ui"
    + );
    +}
    +
    +/******************************************************************************
    + * Public API
    + *****************************************************************************/
    +GtkWidget *gplugin_gtk_viewer_window_new(void) {
    + return GTK_WIDGET(g_object_new(
    + GPLUGIN_GTK_TYPE_VIEWER_WINDOW,
    + NULL
    + ));
    +}
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk-viewer/gplugin-gtk-viewer-window.h Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,59 @@
    +/*
    + * talkatu
    + * Copyright (C) 2017-2018 Gary Kramlich <grim@reaperworld.com>
    + *
    + * This library is free software; you can redistribute it and/or
    + * modify it under the terms of the GNU Lesser General Public
    + * License as published by the Free Software Foundation; either
    + * version 2 of the License, or (at your option) any later version.
    + *
    + * This library is distributed in the hope that it will be useful,
    + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    + * Lesser General Public License for more details.
    + *
    + * You should have received a copy of the GNU Lesser General Public
    + * License along with this library; if not, see <http://www.gnu.org/licenses/>.
    + */
    +
    +#ifndef GPLUGIN_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];
    +};
    +
    +G_BEGIN_DECLS
    +
    +GType gplugin_gtk_viewer_window_get_type(void);
    +
    +GtkWidget *gplugin_gtk_viewer_window_new(void);
    +
    +G_END_DECLS
    +
    +#endif /* GPLUGIN_GTK_VIEWER_WINDOW_H */
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk-viewer/gplugin-gtk-viewer.c Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,215 @@
    +/*
    + * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
    + *
    + * This library is free software; you can redistribute it and/or
    + * modify it under the terms of the GNU Lesser General Public
    + * License as published by the Free Software Foundation; either
    + * version 2 of the License, or (at your option) any later version.
    + *
    + * This library is distributed in the hope that it will be useful,
    + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    + * Lesser General Public License for more details.
    + *
    + * You should have received a copy of the GNU Lesser General Public
    + * License along with this library; if not, see <http://www.gnu.org/licenses/>.
    + */
    +
    +#include <stdio.h>
    +#include <stdlib.h>
    +
    +#include <gtk/gtk.h>
    +
    +#include <gplugin/gplugin.h>
    +#include <gplugin-gtk/gplugin-gtk.h>
    +
    +/******************************************************************************
    + * Globals
    + *****************************************************************************/
    +static gboolean show_internal = FALSE;
    +static gboolean add_default_paths = TRUE, version_only = FALSE;
    +static gchar **paths = NULL;
    +
    +/******************************************************************************
    + * Callbacks
    + *****************************************************************************/
    +static gboolean
    +window_closed_cb(GPLUGIN_UNUSED GtkWidget *w,
    + GPLUGIN_UNUSED GdkEvent *e,
    + GPLUGIN_UNUSED gpointer d)
    +{
    + gtk_main_quit();
    +
    + return FALSE;
    +}
    +
    +static void
    +selection_changed_cb(GtkTreeSelection *sel, gpointer data) {
    + GPluginGtkPluginInfo *info = GPLUGIN_GTK_PLUGIN_INFO(data);
    + GPluginPlugin *plugin = NULL;
    + GtkTreeModel *model = NULL;
    + GtkTreeIter iter;
    +
    + if(gtk_tree_selection_get_selected(sel, &model, &iter)) {
    + gtk_tree_model_get(model, &iter,
    + GPLUGIN_GTK_STORE_PLUGIN_COLUMN, &plugin,
    + -1);
    + }
    +
    + gplugin_gtk_plugin_info_set_plugin(info, plugin);
    +}
    +
    +/******************************************************************************
    + * Helpers
    + *****************************************************************************/
    +static gboolean
    +internal_cb(GPLUGIN_UNUSED const gchar *n,
    + GPLUGIN_UNUSED const gchar *v,
    + GPLUGIN_UNUSED gpointer d,
    + GPLUGIN_UNUSED GError **e)
    +{
    + show_internal = TRUE;
    +
    + return TRUE;
    +}
    +
    +static gboolean
    +no_default_cb(GPLUGIN_UNUSED const gchar *n,
    + GPLUGIN_UNUSED const gchar *v,
    + GPLUGIN_UNUSED gpointer d,
    + GPLUGIN_UNUSED GError **e)
    +{
    + add_default_paths = FALSE;
    +
    + return TRUE;
    +}
    +
    +static gboolean
    +version_cb(GPLUGIN_UNUSED const gchar *n,
    + GPLUGIN_UNUSED const gchar *v,
    + GPLUGIN_UNUSED gpointer d,
    + GPLUGIN_UNUSED GError **e)
    +{
    + version_only = TRUE;
    +
    + printf("gplugin-gtk-viewer %s\n", GPLUGIN_VERSION);
    +
    + return TRUE;
    +}
    +
    +static GtkWidget *
    +create_window(void) {
    + GtkWidget *window = NULL, *grid = NULL, *sw = NULL;
    + GtkWidget *view = NULL, *info = NULL;
    + GtkTreeSelection *sel = NULL;
    +
    + window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    + gtk_window_set_title(GTK_WINDOW(window), "GPlugin Viewer");
    + gtk_container_set_border_width(GTK_CONTAINER(window), 12);
    + g_signal_connect(G_OBJECT(window), "delete-event",
    + G_CALLBACK(window_closed_cb), NULL);
    +
    + grid = gtk_grid_new();
    + gtk_grid_set_row_homogeneous(GTK_GRID(grid), TRUE);
    + gtk_grid_set_column_spacing(GTK_GRID(grid), 12);
    + gtk_container_add(GTK_CONTAINER(window), grid);
    +
    + sw = gtk_scrolled_window_new(NULL, NULL);
    + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
    + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
    + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
    + GTK_SHADOW_IN);
    + gtk_grid_attach(GTK_GRID(grid), sw, 0, 0, 1, 1);
    +
    + view = gplugin_gtk_view_new();
    + gplugin_gtk_view_set_show_internal(GPLUGIN_GTK_VIEW(view), show_internal);
    + gtk_container_add(GTK_CONTAINER(sw), view);
    +
    + info = gplugin_gtk_plugin_info_new();
    + gtk_grid_attach(GTK_GRID(grid), info, 1, 0, 1, 1);
    +
    + sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
    + g_signal_connect(G_OBJECT(sel), "changed",
    + G_CALLBACK(selection_changed_cb), info);
    +
    + return window;
    +}
    +
    +/******************************************************************************
    + * Main Stuff
    + *****************************************************************************/
    +static GOptionEntry entries[] = {
    + {
    + "internal", 'i', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
    + internal_cb, "Show internal plugins",
    + NULL,
    + }, {
    + "no-default-paths", 'D', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
    + no_default_cb, "Do not search the default plugin paths",
    + NULL,
    + }, {
    + "path", 'p', 0, G_OPTION_ARG_STRING_ARRAY,
    + &paths, "Additional paths to look for plugins",
    + "PATH",
    + }, {
    + "version", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
    + version_cb, "Display the version and exit",
    + NULL,
    + }, {
    + NULL, 0, 0, 0, NULL, NULL, NULL,
    + },
    +};
    +
    +gint
    +main(gint argc, gchar **argv) {
    + GError *error = NULL;
    + GOptionContext *ctx = NULL;
    + GtkWidget *window = NULL;
    +
    + ctx = g_option_context_new("");
    + g_option_context_add_main_entries(ctx, entries, NULL);
    + g_option_context_add_group(ctx, gtk_get_option_group(TRUE));
    + g_option_context_parse(ctx, &argc, &argv, &error);
    + g_option_context_free(ctx);
    +
    + if(error) {
    + fprintf(stderr, "%s\n", error->message);
    +
    + g_error_free(error);
    +
    + gplugin_uninit();
    +
    + return EXIT_FAILURE;
    + }
    +
    + if(version_only) {
    + return 0;
    + }
    +
    + gtk_init(&argc, &argv);
    +
    + gplugin_init();
    +
    + if(add_default_paths)
    + gplugin_manager_add_default_paths();
    +
    + if(paths) {
    + gint i;
    +
    + for(i = 0; paths[i]; i++)
    + gplugin_manager_prepend_path(paths[i]);
    + }
    +
    + gplugin_manager_refresh();
    +
    + /* now create and show the window */
    + window = create_window();
    + gtk_widget_show_all(window);
    +
    + gtk_main();
    +
    + gplugin_uninit();
    +
    + return 0;
    +}
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk-viewer/meson.build Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,29 @@
    +if get_option('gtk3')
    +
    +gplugin_gtk_viewer_resources = gnome.compile_resources(
    + 'gplugin-gtk-viewer-resources',
    + 'data/gplugin-gtk-viewer.gresource.xml',
    + c_name: 'gplugin_gtk_viewer',
    + source_dir: 'data')
    +
    +gplugin_gtk_viewer = executable('gplugin-gtk-viewer',
    + 'gplugin-gtk-viewer.c',
    + 'gplugin-gtk-viewer-window.c',
    + 'gplugin-gtk-viewer-window.h',
    + dependencies : [gplugin_dep, gplugin_gtk_dep],
    + install : true
    +)
    +
    +if get_option('help2man')
    + gplugin_gtk_viewer_man = custom_target('gplugin-gtk-viewer.1',
    + command : [help2man,
    + '--name=View installed plugins', '--section=1',
    + '--help-option=--help-all', '--no-info',
    + '--output', '@OUTPUT@',
    + gplugin_gtk_viewer],
    + output : 'gplugin-gtk-viewer.1',
    + install : true,
    + install_dir : join_paths(get_option('mandir'), 'man1'))
    +endif
    +
    +endif
    --- a/gplugin-gtk/CMakeLists.txt Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,145 +0,0 @@
    -option(
    - BUILD_GTK3
    - "Whether or not to build the gtk3 library"
    - "On"
    -)
    -
    -if(BUILD_GTK3)
    -
    -###############################################################################
    -# Build Info
    -###############################################################################
    -pkg_check_modules(GTK3 REQUIRED gtk+-3.0>=3.0.0)
    -
    -set(GPLUGIN_GTK_LD_CURRENT 0)
    -set(GPLUGIN_GTK_LD_REVISION 1)
    -set(GPLUGIN_GTK_LD_AGE 0)
    -set(GPLUGIN_GTK_LD_VERSION ${GPLUGIN_GTK_LD_CURRENT}.${GPLUGIN_GTK_LD_REVISION}.${GPLUGIN_GTK_LD_AGE})
    -
    -add_definitions(
    - -DGPLUGIN_GTK_COMPILATION
    - -DG_LOG_DOMAIN="GPluginGtk"
    -)
    -
    -link_directories(
    - ${GTK3_LIBRARY_DIRS}
    -)
    -
    -include_directories(
    - ${GTK3_INCLUDE_DIRS}
    -)
    -
    -include_directories(
    - ${CHAKE_CURRENT_SOURCE_DIR}
    -)
    -
    -set(GPLUGIN_GTK_SOURCES
    - gplugin-gtk-plugin-info.c
    - gplugin-gtk-store.c
    - gplugin-gtk-view.c
    -)
    -
    -set(GPLUGIN_GTK_HEADERS
    - gplugin-gtk-plugin-info.h
    - gplugin-gtk-store.h
    - gplugin-gtk-view.h
    -)
    -
    -set(GPLUGIN_GTK_PRIVATE_SOURCES
    -)
    -
    -set(GPLUGIN_GTK_PRIVATE_HEADERS
    -)
    -
    -set(GPLUGIN_GTK_BUILT_SOURCES
    -)
    -
    -set(GPLUGIN_GTK_BUILT_HEADERS
    -)
    -
    -###############################################################################
    -# Configure Files
    -###############################################################################
    -set(GPLUGIN_GTK_H_INCLUDES "")
    -
    -foreach(HEADER ${GPLUGIN_GTK_HEADERS} ${GPLUGIN_GTK_BUILT_HEADERS})
    - set(GPLUGIN_GTK_H_INCLUDES "${GPLUGIN_GTK_H_INCLUDES}\n#include <gplugin-gtk/${HEADER}>")
    -endforeach(HEADER)
    -
    -configure_file(gplugin-gtk.h.in gplugin-gtk.h @ONLY)
    -
    -configure_file(gplugin-gtk.pc.in gplugin-gtk.pc @ONLY)
    -install(
    - FILES ${CMAKE_CURRENT_BINARY_DIR}/gplugin-gtk.pc
    - DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
    -)
    -
    -###############################################################################
    -# Library Target
    -###############################################################################
    -add_library(gplugin-gtk SHARED
    - ${GPLUGIN_GTK_SOURCES}
    - ${GPLUGIN_GTK_HEADERS}
    - ${GPLUGIN_GTK_PRIVATE_SOURCES}
    - ${GPLUGIN_GTK_PRIVATE_HEADERS}
    - ${GPLUGIN_GTK_BUILT_SOURCES}
    - ${GPLUGIN_GTK_BUILT_HEADERS}
    -)
    -
    -set_target_properties(gplugin-gtk PROPERTIES
    - SOVERSION ${GPLUGIN_GTK_LD_CURRENT}
    - VERSION ${GPLUGIN_GTK_LD_VERSION}
    -)
    -
    -target_link_libraries(gplugin-gtk
    - ${GTK3_LIBRARIES}
    - gplugin
    -)
    -
    -install(TARGETS gplugin-gtk DESTINATION ${CMAKE_INSTALL_LIBDIR})
    -
    -# install the single include into the main directory
    -install(
    - FILES ${CMAKE_CURRENT_BINARY_DIR}/gplugin-gtk.h
    - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/gplugin-1.0
    -)
    -
    -# install the normal includes into the gplugin-gtk subdirectory
    -foreach(HEADER ${GPLUGIN_GTK_HEADERS})
    - install(
    - FILES ${CMAKE_CURRENT_SOURCE_DIR}/${HEADER}
    - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/gplugin-1.0/gplugin-gtk
    - )
    -endforeach(HEADER)
    -
    -# install the GtkBuilder files
    -install(
    - FILES gplugin-gtk-plugin-info.ui
    - DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/gplugin/gplugin-gtk/
    -)
    -
    -###############################################################################
    -# Application Target
    -###############################################################################
    -add_executable(gplugin-gtk-viewer
    - gplugin-gtk-viewer.c
    -)
    -
    -target_link_libraries(gplugin-gtk-viewer
    - gplugin-gtk
    - gplugin
    -)
    -
    -if(BUILD_HELP2MAN)
    - help2man(
    - TARGET gplugin-gtk-viewer
    - OUTPUT gplugin-gtk-viewer.1
    - SECTION 1
    - NAME "View installed plugins"
    - HELP_OPTION --help-all
    - )
    -endif(BUILD_HELP2MAN)
    -
    -install(TARGETS gplugin-gtk-viewer RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
    -
    -endif(BUILD_GTK3)
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk/data/gplugin-gtk.gresource.xml Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,6 @@
    +<?xml version="1.0" encoding="UTF-8"?>
    +<gresources>
    + <gresource prefix="/org/bitbucket/gplugin/gplugin-gtk/">
    + <file compressed="true">plugin-info.ui</file>
    + </gresource>
    +</gresources>
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk/data/plugin-info.ui Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,540 @@
    +<?xml version="1.0" encoding="UTF-8"?>
    +<!-- Generated with glade 3.22.1 -->
    +<interface>
    + <requires lib="gtk+" version="3.10"/>
    + <template class="GPluginGtkPluginInfo" parent="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="orientation">vertical</property>
    + <child>
    + <object class="GtkLabel" id="name">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + <attributes>
    + <attribute name="weight" value="bold"/>
    + <attribute name="scale" value="2"/>
    + </attributes>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">6</property>
    + <child>
    + <object class="GtkLabel" id="version_label">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">Version</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkLabel" id="version">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">6</property>
    + <child>
    + <object class="GtkLabel" id="authors_label">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">Authors</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkBox" id="authors_box">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="orientation">vertical</property>
    + <child>
    + <placeholder/>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">2</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">6</property>
    + <child>
    + <object class="GtkLabel" id="website_label">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">Website</property>
    + <property name="use_underline">True</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkLabel" id="website">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="use_markup">True</property>
    + <property name="track_visited_links">False</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">3</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">6</property>
    + <child>
    + <object class="GtkLabel" id="summary_label">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">Summary</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkLabel" id="summary">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">4</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">6</property>
    + <child>
    + <object class="GtkLabel" id="description_label">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">Description</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkLabel" id="description">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="wrap">True</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">True</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">5</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">6</property>
    + <child>
    + <object class="GtkLabel" id="dependencies_label">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">Dependencies</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkLabel" id="dependencies">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">6</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkExpander">
    + <property name="visible">True</property>
    + <property name="can_focus">True</property>
    + <property name="label_fill">True</property>
    + <signal name="activate" handler="gplugin_gtk_plugin_info_expander_activate" object="GPluginGtkPluginInfo" swapped="no"/>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="orientation">vertical</property>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">6</property>
    + <child>
    + <object class="GtkLabel" id="id_label">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">ID</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkLabel" id="id">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">6</property>
    + <child>
    + <object class="GtkLabel" id="filename_label">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">Filename</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkLabel" id="filename">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">6</property>
    + <child>
    + <object class="GtkLabel" id="abi_version_label">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">ABI Version</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkLabel" id="abi_version">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">2</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">6</property>
    + <child>
    + <object class="GtkLabel" id="loader_label">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">Loader</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkLabel" id="loader">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">3</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">6</property>
    + <child>
    + <object class="GtkLabel" id="internal_label">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">Internal</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkLabel" id="internal">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">4</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">6</property>
    + <child>
    + <object class="GtkLabel" id="load_on_query_label">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">Load on Query</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkLabel" id="load_on_query">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">5</property>
    + </packing>
    + </child>
    + </object>
    + </child>
    + <child type="label">
    + <object class="GtkLabel" id="expander">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">More</property>
    + </object>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">True</property>
    + <property name="fill">True</property>
    + <property name="position">7</property>
    + </packing>
    + </child>
    + </template>
    + <object class="GtkSizeGroup" id="size_group">
    + <widgets>
    + <widget name="version_label"/>
    + <widget name="authors_label"/>
    + <widget name="website_label"/>
    + <widget name="summary_label"/>
    + <widget name="description_label"/>
    + <widget name="dependencies_label"/>
    + <widget name="id_label"/>
    + <widget name="filename_label"/>
    + <widget name="abi_version_label"/>
    + <widget name="loader_label"/>
    + <widget name="internal_label"/>
    + <widget name="load_on_query_label"/>
    + </widgets>
    + </object>
    +</interface>
    --- a/gplugin-gtk/gplugin-gtk-plugin-info.c Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin-gtk/gplugin-gtk-plugin-info.c Tue Jan 22 22:50:20 2019 -0600
    @@ -19,15 +19,34 @@
    #include <gplugin/gplugin.h>
    -#define GPLUGIN_GTK_PLUGIN_INFO_GET_PRIVATE(obj) \
    - (G_TYPE_INSTANCE_GET_PRIVATE((obj), GPLUGIN_GTK_TYPE_PLUGIN_INFO, GPluginGtkPluginInfoPrivate))
    +/**
    + * SECTION:gplugin-gtk-plugin-info
    + * @Title: Plugin Info Gtk+ Widgets
    + * @Short_description: Gtk+ Widgets for plugins
    + *
    + * #GPluginGtkPluginInfo is a Gtk+ widget that shows information about plugins.
    + */
    /******************************************************************************
    * Structs
    *****************************************************************************/
    typedef struct {
    GPluginPlugin *plugin;
    - GtkBuilder *builder;
    +
    + GtkWidget *name;
    + GtkWidget *version;
    + GtkWidget *authors_box;
    + GtkWidget *website;
    + GtkWidget *summary;
    + GtkWidget *description;
    + GtkWidget *dependencies;
    + GtkWidget *expander;
    + GtkWidget *id;
    + GtkWidget *filename;
    + GtkWidget *abi_version;
    + GtkWidget *loader;
    + GtkWidget *internal;
    + GtkWidget *load_on_query;
    } GPluginGtkPluginInfoPrivate;
    /*****************************************************************************s
    @@ -38,13 +57,16 @@
    PROP_PLUGIN,
    N_PROPERTIES,
    };
    +static GParamSpec *properties[N_PROPERTIES] = {NULL,};
    +
    +G_DEFINE_TYPE_WITH_PRIVATE(GPluginGtkPluginInfo, gplugin_gtk_plugin_info, GTK_TYPE_BOX);
    /******************************************************************************
    * Callbacks
    *****************************************************************************/
    static void
    -_gplugin_gtk_plugin_info_expander_activate_cb(GtkExpander *expander,
    - GPLUGIN_UNUSED gpointer data)
    +gplugin_gtk_plugin_info_expander_activate(GtkExpander *expander,
    + GPLUGIN_UNUSED gpointer data)
    {
    if(gtk_expander_get_expanded(expander))
    gtk_expander_set_label(expander, "More");
    @@ -59,22 +81,19 @@
    _gplugin_gtk_plugin_info_refresh(GPluginGtkPluginInfoPrivate *priv,
    GPluginPlugin *plugin)
    {
    - GtkWidget *authors_grid = NULL, *widget = NULL;
    + GtkWidget *widget = NULL;
    GList *children = NULL, *iter = NULL;
    gchar *markup = NULL;
    gchar *name = NULL, *version = NULL, *website = NULL;
    - gchar *description = NULL, *id = NULL, *abi_version = NULL;
    + gchar *summary = NULL, *description = NULL, *id = NULL, *abi_version = NULL;
    gchar *loader = NULL;
    gchar **authors = NULL;
    guint32 abi_version_uint;
    gboolean loq = FALSE, internal = FALSE;
    const gchar *filename = NULL;
    - authors_grid = GTK_WIDGET(gtk_builder_get_object(priv->builder,
    - "authors_grid"));
    -
    - /* remove all the children from the authors grid */
    - children = gtk_container_get_children(GTK_CONTAINER(authors_grid));
    + /* remove all the children from the authors box */
    + children = gtk_container_get_children(GTK_CONTAINER(priv->authors_box));
    for(iter = children; iter; iter = iter->next)
    gtk_widget_destroy(GTK_WIDGET(iter->data));
    g_list_free(children);
    @@ -95,6 +114,7 @@
    g_object_get(G_OBJECT(plugin_info),
    "abi_version", &abi_version_uint,
    "authors", &authors,
    + "summary", &summary,
    "description", &description,
    "id", &id,
    "internal", &internal,
    @@ -125,13 +145,24 @@
    g_object_unref(G_OBJECT(plugin_info));
    }
    - /* set the name */
    - widget = GTK_WIDGET(gtk_builder_get_object(priv->builder, "name"));
    - gtk_label_set_markup(GTK_LABEL(widget), (name) ? name : "Unnamed");
    + 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");
    - /* set the version */
    - widget = GTK_WIDGET(gtk_builder_get_object(priv->builder, "version"));
    - gtk_label_set_text(GTK_LABEL(widget), (version) ? version : "");
    + g_free(description);
    + g_free(id);
    + g_free(name);
    + g_free(version);
    + g_free(website);
    + g_free(loader);
    /* set the authors */
    if(authors) {
    @@ -141,59 +172,16 @@
    widget = gtk_label_new(authors[i]);
    gtk_widget_set_halign(widget, GTK_ALIGN_START);
    gtk_widget_set_valign(widget, GTK_ALIGN_START);
    - gtk_grid_attach(GTK_GRID(authors_grid), widget, 0, i, 1, 1);
    + gtk_box_pack_start(GTK_BOX(priv->authors_box), widget, TRUE, TRUE, 0);
    gtk_widget_show(widget);
    }
    }
    -
    - /* set the website */
    - widget = GTK_WIDGET(gtk_builder_get_object(priv->builder, "website"));
    - gtk_label_set_markup(GTK_LABEL(widget), (website) ? website : "");
    -
    - /* set the description */
    - widget = GTK_WIDGET(gtk_builder_get_object(priv->builder, "description"));
    - gtk_label_set_text(GTK_LABEL(widget), (description) ? description : "");
    -
    - /* set the plugin id */
    - widget = GTK_WIDGET(gtk_builder_get_object(priv->builder, "id"));
    - gtk_label_set_text(GTK_LABEL(widget), (id) ? id : "");
    -
    - /* set the filename */
    - widget = GTK_WIDGET(gtk_builder_get_object(priv->builder, "filename"));
    - gtk_label_set_text(GTK_LABEL(widget), (filename) ? filename : "");
    -
    - /* set the abi_version */
    - widget = GTK_WIDGET(gtk_builder_get_object(priv->builder, "abi_version"));
    - gtk_label_set_text(GTK_LABEL(widget), (abi_version) ? abi_version : "");
    -
    - /* set the loader */
    - widget = GTK_WIDGET(gtk_builder_get_object(priv->builder, "loader"));
    - gtk_label_set_text(GTK_LABEL(widget), (loader) ? loader : "Unknown");
    -
    - /* set the internal */
    - widget = GTK_WIDGET(gtk_builder_get_object(priv->builder, "internal"));
    - gtk_label_set_text(GTK_LABEL(widget), (internal) ? "Yes" : "No");
    -
    - /* set the load on query label */
    - widget = GTK_WIDGET(gtk_builder_get_object(priv->builder,
    - "load_on_query"));
    - gtk_label_set_text(GTK_LABEL(widget), (loq) ? "Yes" : "No");
    -
    - /* cleanup */
    g_strfreev(authors);
    - g_free(description);
    - g_free(id);
    - g_free(name);
    - g_free(version);
    - g_free(website);
    - g_free(loader);
    }
    /******************************************************************************
    * GObject Stuff
    *****************************************************************************/
    -G_DEFINE_TYPE(GPluginGtkPluginInfo, gplugin_gtk_plugin_info, GTK_TYPE_FRAME);
    -
    static void
    gplugin_gtk_plugin_info_set_property(GObject *obj, guint prop_id,
    const GValue *value, GParamSpec *pspec)
    @@ -228,67 +216,77 @@
    }
    static void
    -gplugin_gtk_plugin_info_constructed(GObject *obj) {
    - GPluginGtkPluginInfoPrivate *priv = NULL;
    - GtkWidget *widget = NULL;
    - GError *error = NULL;
    - gchar *filename = NULL;
    -
    - G_OBJECT_CLASS(gplugin_gtk_plugin_info_parent_class)->constructed(obj);
    -
    - priv = GPLUGIN_GTK_PLUGIN_INFO_GET_PRIVATE(obj);
    +gplugin_gtk_plugin_info_finalize(GObject *obj) {
    + GPluginGtkPluginInfoPrivate *priv = gplugin_gtk_plugin_info_get_instance_private(GPLUGIN_GTK_PLUGIN_INFO(obj));
    - /* load the ui from the GtkBuilder file */
    - priv->builder = gtk_builder_new();
    - filename = g_build_filename(PREFIX, "share", "gplugin", "gplugin-gtk",
    - "gplugin-gtk-plugin-info.ui", NULL);
    - gtk_builder_add_from_file(priv->builder, filename, &error);
    - if(error) {
    - g_warning("%s", error->message);
    - g_error_free(error);
    + if(priv->plugin != NULL) {
    + g_object_unref(priv->plugin);
    }
    - g_free(filename);
    - widget = GTK_WIDGET(gtk_builder_get_object(priv->builder, "plugin_info"));
    - gtk_container_add(GTK_CONTAINER(obj), widget);
    -
    - /* add a callback for the expander */
    - widget = GTK_WIDGET(gtk_builder_get_object(priv->builder,
    - "more_expander"));
    - g_signal_connect(G_OBJECT(widget), "activate",
    - G_CALLBACK(_gplugin_gtk_plugin_info_expander_activate_cb),
    - NULL);
    + G_OBJECT_CLASS(gplugin_gtk_plugin_info_parent_class)->finalize(obj);
    }
    static void
    -gplugin_gtk_plugin_info_init(GPLUGIN_UNUSED GPluginGtkPluginInfo *info) {
    +gplugin_gtk_plugin_info_init(GPluginGtkPluginInfo *info) {
    + gtk_widget_init_template(GTK_WIDGET(info));
    }
    static void
    gplugin_gtk_plugin_info_class_init(GPluginGtkPluginInfoClass *klass) {
    + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
    GObjectClass *obj_class = G_OBJECT_CLASS(klass);
    - g_type_class_add_private(obj_class, sizeof(GPluginGtkPluginInfoPrivate));
    -
    obj_class->get_property = gplugin_gtk_plugin_info_get_property;
    obj_class->set_property = gplugin_gtk_plugin_info_set_property;
    - obj_class->constructed = gplugin_gtk_plugin_info_constructed;
    + obj_class->finalize = gplugin_gtk_plugin_info_finalize;
    /* properties */
    + properties[PROP_PLUGIN] = g_param_spec_object(
    + "plugin", "plugin",
    + "The GPluginPlugin who's info should be displayed",
    + G_TYPE_OBJECT,
    + G_PARAM_READWRITE | G_PARAM_CONSTRUCT
    + );
    +
    + /* template stuff */
    + gtk_widget_class_set_template_from_resource(
    + widget_class,
    + "/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_callback(widget_class, gplugin_gtk_plugin_info_expander_activate);
    }
    /******************************************************************************
    * API
    *****************************************************************************/
    +
    +/**
    + * gplugin_gtk_plugin_info_new:
    + *
    + * Create a new GPluginGtkView which can be used to display info about a
    + * #GPluginPlugin.
    + *
    + * Returns: (transfer full): The new #GPluginGtkView widget.
    + */
    GtkWidget *
    gplugin_gtk_plugin_info_new(void) {
    - GObject *ret = NULL;
    -
    - ret = g_object_new(GPLUGIN_GTK_TYPE_PLUGIN_INFO,
    - "shadow-type", GTK_SHADOW_NONE,
    - NULL);
    -
    - return GTK_WIDGET(ret);
    + return GTK_WIDGET(g_object_new(GPLUGIN_GTK_TYPE_PLUGIN_INFO, NULL));
    }
    /**
    @@ -308,15 +306,17 @@
    g_return_if_fail(GPLUGIN_GTK_IS_PLUGIN_INFO(info));
    - priv = GPLUGIN_GTK_PLUGIN_INFO_GET_PRIVATE(info);
    + priv = gplugin_gtk_plugin_info_get_instance_private(info);
    - if(GPLUGIN_IS_PLUGIN(priv->plugin))
    + if(GPLUGIN_IS_PLUGIN(priv->plugin)) {
    g_object_unref(G_OBJECT(priv->plugin));
    + }
    - if(GPLUGIN_IS_PLUGIN(plugin))
    - priv->plugin = g_object_ref(G_OBJECT(plugin));
    - else
    + if(GPLUGIN_IS_PLUGIN(plugin)) {
    + priv->plugin = GPLUGIN_PLUGIN(g_object_ref(G_OBJECT(plugin)));
    + } else {
    priv->plugin = NULL;
    + }
    _gplugin_gtk_plugin_info_refresh(priv, plugin);
    }
    @@ -331,13 +331,12 @@
    * displayed.
    */
    GPluginPlugin *
    -gplugin_gtk_plugin_info_get_plugin(const GPluginGtkPluginInfo *info) {
    +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_PRIVATE(info);
    + priv = gplugin_gtk_plugin_info_get_instance_private(info);
    - return (priv->plugin) ? g_object_ref(G_OBJECT(priv->plugin)) : NULL;
    + return (priv->plugin) ? GPLUGIN_PLUGIN(g_object_ref(G_OBJECT(priv->plugin))) : NULL;
    }
    -
    --- a/gplugin-gtk/gplugin-gtk-plugin-info.h Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin-gtk/gplugin-gtk-plugin-info.h Tue Jan 22 22:50:20 2019 -0600
    @@ -15,11 +15,9 @@
    * License along with this library; if not, see <http://www.gnu.org/licenses/>.
    */
    -#ifndef __GI_SCANNER__ /* hide this bit from g-ir-scanner */
    #if !defined(GPLUGIN_GTK_GLOBAL_HEADER_INSIDE) && !defined(GPLUGIN_GTK_COMPILATION)
    #error "only <gplugin/gplugin-gtk.h> may be included directly"
    #endif
    -#endif /* __GI_SCANNER__ */
    #ifndef GPLUGIN_GTK_PLUGIN_INFO_H
    #define GPLUGIN_GTK_PLUGIN_INFO_H
    @@ -31,8 +29,8 @@
    #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;
    +typedef struct _GPluginGtkPluginInfo GPluginGtkPluginInfo;
    +typedef struct _GPluginGtkPluginInfoClass GPluginGtkPluginInfoClass;
    #include <glib.h>
    #include <glib-object.h>
    @@ -44,19 +42,13 @@
    struct _GPluginGtkPluginInfo {
    GtkFrame parent;
    - void (*_gplugin_reserved1)(void);
    - void (*_gplugin_reserved2)(void);
    - void (*_gplugin_reserved3)(void);
    - void (*_gplugin_reserved4)(void);
    + gpointer reserved[4];
    };
    struct _GPluginGtkPluginInfoClass {
    GtkFrameClass parent;
    - void (*_gplugin_reserved1)(void);
    - void (*_gplugin_reserved2)(void);
    - void (*_gplugin_reserved3)(void);
    - void (*_gplugin_reserved4)(void);
    + gpointer reserved[4];
    };
    G_BEGIN_DECLS
    @@ -66,7 +58,7 @@
    GtkWidget *gplugin_gtk_plugin_info_new(void);
    void gplugin_gtk_plugin_info_set_plugin(GPluginGtkPluginInfo *info, GPluginPlugin *plugin);
    -GPluginPlugin *gplugin_gtk_plugin_info_get_plugin(const GPluginGtkPluginInfo *info);
    +GPluginPlugin *gplugin_gtk_plugin_info_get_plugin(GPluginGtkPluginInfo *info);
    G_END_DECLS
    --- a/gplugin-gtk/gplugin-gtk-plugin-info.ui Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,397 +0,0 @@
    -<?xml version="1.0" encoding="UTF-8"?>
    -<interface>
    - <!-- interface-requires gtk+ 3.0 -->
    - <object class="GtkGrid" id="plugin_info">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <child>
    - <object class="GtkLabel" id="name">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - <property name="use_markup">True</property>
    - </object>
    - <packing>
    - <property name="left_attach">0</property>
    - <property name="top_attach">0</property>
    - <property name="width">2</property>
    - <property name="height">1</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="version_label">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - <property name="label" translatable="yes">Version</property>
    - </object>
    - <packing>
    - <property name="left_attach">0</property>
    - <property name="top_attach">1</property>
    - <property name="width">1</property>
    - <property name="height">1</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="authors_label">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - <property name="label" translatable="yes">Authors </property>
    - </object>
    - <packing>
    - <property name="left_attach">0</property>
    - <property name="top_attach">2</property>
    - <property name="width">1</property>
    - <property name="height">1</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="version">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="hexpand">True</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="left_attach">1</property>
    - <property name="top_attach">1</property>
    - <property name="width">1</property>
    - <property name="height">1</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkGrid" id="authors_grid">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="hexpand">True</property>
    - <child>
    - <placeholder/>
    - </child>
    - </object>
    - <packing>
    - <property name="left_attach">1</property>
    - <property name="top_attach">2</property>
    - <property name="width">1</property>
    - <property name="height">1</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="website_label">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - <property name="label" translatable="yes">Website</property>
    - </object>
    - <packing>
    - <property name="left_attach">0</property>
    - <property name="top_attach">3</property>
    - <property name="width">1</property>
    - <property name="height">1</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="website">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="hexpand">True</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - <property name="use_markup">True</property>
    - <property name="track_visited_links">False</property>
    - </object>
    - <packing>
    - <property name="left_attach">1</property>
    - <property name="top_attach">3</property>
    - <property name="width">1</property>
    - <property name="height">1</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="description_label">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - <property name="label" translatable="yes">Description</property>
    - </object>
    - <packing>
    - <property name="left_attach">0</property>
    - <property name="top_attach">4</property>
    - <property name="width">1</property>
    - <property name="height">1</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="description">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="hexpand">True</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - <property name="wrap">True</property>
    - </object>
    - <packing>
    - <property name="left_attach">1</property>
    - <property name="top_attach">4</property>
    - <property name="width">1</property>
    - <property name="height">1</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkExpander" id="more_expander">
    - <property name="visible">True</property>
    - <property name="can_focus">True</property>
    - <child>
    - <object class="GtkGrid" id="more_grid">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <child>
    - <object class="GtkLabel" id="id_label">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - <property name="label" translatable="yes">Plugin ID</property>
    - </object>
    - <packing>
    - <property name="left_attach">0</property>
    - <property name="top_attach">0</property>
    - <property name="width">1</property>
    - <property name="height">1</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="id">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="hexpand">True</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="left_attach">1</property>
    - <property name="top_attach">0</property>
    - <property name="width">1</property>
    - <property name="height">1</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="filename_label">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - <property name="label" translatable="yes">Filename</property>
    - </object>
    - <packing>
    - <property name="left_attach">0</property>
    - <property name="top_attach">1</property>
    - <property name="width">1</property>
    - <property name="height">1</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="filename">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="hexpand">True</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="left_attach">1</property>
    - <property name="top_attach">1</property>
    - <property name="width">1</property>
    - <property name="height">1</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="abi_version_label">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - <property name="label" translatable="yes">ABI Version</property>
    - </object>
    - <packing>
    - <property name="left_attach">0</property>
    - <property name="top_attach">2</property>
    - <property name="width">1</property>
    - <property name="height">1</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="abi_version">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="hexpand">True</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="left_attach">1</property>
    - <property name="top_attach">2</property>
    - <property name="width">1</property>
    - <property name="height">1</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="loader_label">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - <property name="label" translatable="yes">Loader</property>
    - </object>
    - <packing>
    - <property name="left_attach">0</property>
    - <property name="top_attach">3</property>
    - <property name="width">1</property>
    - <property name="height">1</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="loader">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="hexpand">True</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="left_attach">1</property>
    - <property name="top_attach">3</property>
    - <property name="width">1</property>
    - <property name="height">1</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="load_on_query_label">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - <property name="label" translatable="yes">Load on Query</property>
    - </object>
    - <packing>
    - <property name="left_attach">0</property>
    - <property name="top_attach">5</property>
    - <property name="width">1</property>
    - <property name="height">1</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="load_on_query">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="hexpand">True</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="left_attach">1</property>
    - <property name="top_attach">5</property>
    - <property name="width">1</property>
    - <property name="height">1</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="internal_label">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - <property name="label" translatable="yes">Internal</property>
    - </object>
    - <packing>
    - <property name="left_attach">0</property>
    - <property name="top_attach">4</property>
    - <property name="width">1</property>
    - <property name="height">1</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="internal">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="hexpand">True</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="left_attach">1</property>
    - <property name="top_attach">4</property>
    - <property name="width">1</property>
    - <property name="height">1</property>
    - </packing>
    - </child>
    - </object>
    - </child>
    - <child type="label">
    - <object class="GtkLabel" id="expander_label">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="label" translatable="yes">More</property>
    - </object>
    - </child>
    - </object>
    - <packing>
    - <property name="left_attach">0</property>
    - <property name="top_attach">6</property>
    - <property name="width">2</property>
    - <property name="height">1</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="dependencies_label">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - <property name="label" translatable="yes">Dependencies </property>
    - </object>
    - <packing>
    - <property name="left_attach">0</property>
    - <property name="top_attach">5</property>
    - <property name="width">1</property>
    - <property name="height">1</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="dependencies">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="hexpand">True</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="left_attach">1</property>
    - <property name="top_attach">5</property>
    - <property name="width">1</property>
    - <property name="height">1</property>
    - </packing>
    - </child>
    - </object>
    - <object class="GtkSizeGroup" id="plugin_info_sizegroup">
    - <widgets>
    - <widget name="version_label"/>
    - <widget name="authors_label"/>
    - <widget name="website_label"/>
    - <widget name="description_label"/>
    - <widget name="id_label"/>
    - <widget name="filename_label"/>
    - <widget name="abi_version_label"/>
    - <widget name="loader_label"/>
    - <widget name="load_on_query_label"/>
    - <widget name="internal_label"/>
    - <widget name="dependencies_label"/>
    - </widgets>
    - </object>
    -</interface>
    --- a/gplugin-gtk/gplugin-gtk-store.c Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin-gtk/gplugin-gtk-store.c Tue Jan 22 22:50:20 2019 -0600
    @@ -19,19 +19,15 @@
    #include <gplugin-gtk/gplugin-gtk-store.h>
    -#define GPLUGIN_GTK_STORE_GET_PRIVATE(obj) \
    - (G_TYPE_INSTANCE_GET_PRIVATE((obj), GPLUGIN_GTK_TYPE_STORE, GPluginGtkStorePrivate))
    +/**
    + * SECTION:gplugin-gtk-store
    + * @Title: GtkTreeModelStore for gplugins
    + * @Short_description: A store for plugins
    + *
    + * #GPluginGtkStore is a GtkTreeModel populated with gplugins.
    + */
    -/******************************************************************************
    - * Structs
    - *****************************************************************************/
    -typedef struct {
    - gboolean dummy;
    -} GPluginGtkStorePrivate;
    -
    -/******************************************************************************
    - * Enums
    - *****************************************************************************/
    +G_DEFINE_TYPE(GPluginGtkStore, gplugin_gtk_store, GTK_TYPE_LIST_STORE);
    /******************************************************************************
    * Globals
    @@ -91,8 +87,6 @@
    /******************************************************************************
    * GObject Stuff
    *****************************************************************************/
    -G_DEFINE_TYPE(GPluginGtkStore, gplugin_gtk_store, GTK_TYPE_LIST_STORE);
    -
    static void
    gplugin_gtk_store_constructed(GObject *obj) {
    GList *l, *ids = NULL;
    @@ -124,21 +118,35 @@
    gplugin_gtk_store_class_init(GPluginGtkStoreClass *klass) {
    GObjectClass *obj_class = G_OBJECT_CLASS(klass);
    - g_type_class_add_private(obj_class, sizeof(GPluginGtkStorePrivate));
    -
    obj_class->constructed = gplugin_gtk_store_constructed;
    obj_class->dispose = gplugin_gtk_store_dispose;
    -
    }
    /******************************************************************************
    * API
    *****************************************************************************/
    +
    +/**
    + * gplugin_gtk_store_new:
    + *
    + * Create a new GPluginGtkStore which is a prepopulated #GtkTreeStore.
    + *
    + * Returns: (transfer full): A new GtkTreeModel prepopulated with all of the
    + * gplugins.
    + */
    GPluginGtkStore *
    gplugin_gtk_store_new(void) {
    return GPLUGIN_GTK_STORE(g_object_new(GPLUGIN_GTK_TYPE_STORE, NULL));
    }
    +/**
    + * gplugin_gtk_get_store_column_types:
    + *
    + * Returns the columns that #GPluginGtkStore's will use.
    + *
    + * Returns: (transfer none): A list of #GTypes for the columes that the store
    + * will use.
    + */
    const GType *
    gplugin_gtk_get_store_column_types(void) {
    return column_types;
    --- a/gplugin-gtk/gplugin-gtk-store.h Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin-gtk/gplugin-gtk-store.h Tue Jan 22 22:50:20 2019 -0600
    @@ -15,11 +15,9 @@
    * License along with this library; if not, see <http://www.gnu.org/licenses/>.
    */
    -#ifndef __GI_SCANNER__ /* hide this bit from g-ir-scanner */
    #if !defined(GPLUGIN_GTK_GLOBAL_HEADER_INSIDE) && !defined(GPLUGIN_GTK_COMPILATION)
    #error "only <gplugin/gplugin-gtk.h> may be included directly"
    #endif
    -#endif /* __GI_SCANNER__ */
    #ifndef GPLUGIN_GTK_STORE_H
    #define GPLUGIN_GTK_STORE_H
    @@ -42,19 +40,13 @@
    struct _GPluginGtkStore {
    GtkListStore parent;
    - void (*_gplugin_reserved1)(void);
    - void (*_gplugin_reserved2)(void);
    - void (*_gplugin_reserved3)(void);
    - void (*_gplugin_reserved4)(void);
    + gpointer reserved[4];
    };
    struct _GPluginGtkStoreClass {
    GtkListStoreClass parent;
    - void (*_gplugin_reserved1)(void);
    - void (*_gplugin_reserved2)(void);
    - void (*_gplugin_reserved3)(void);
    - void (*_gplugin_reserved4)(void);
    + gpointer reserved[4];
    };
    typedef enum {
    --- a/gplugin-gtk/gplugin-gtk-view.c Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin-gtk/gplugin-gtk-view.c Tue Jan 22 22:50:20 2019 -0600
    @@ -18,8 +18,13 @@
    #include <gplugin-gtk/gplugin-gtk-view.h>
    #include <gplugin-gtk/gplugin-gtk-store.h>
    -#define GPLUGIN_GTK_VIEW_GET_PRIVATE(obj) \
    - (G_TYPE_INSTANCE_GET_PRIVATE((obj), GPLUGIN_GTK_TYPE_VIEW, GPluginGtkViewPrivate))
    +/**
    + * SECTION:gplugin-gtk-view
    + * @Title: Gtk+ View for gplugins
    + * @Short_description: A view for plugins
    + *
    + * #GPluginGtkView is a display widget for a list of GPlugins.
    + */
    /******************************************************************************
    * Structs
    @@ -36,15 +41,12 @@
    PROP_SHOW_INTERNAL,
    N_PROPERTIES,
    };
    -
    -/******************************************************************************
    - * Globals
    - *****************************************************************************/
    +static GParamSpec *properties[N_PROPERTIES] = {NULL,};
    /******************************************************************************
    * GObject Stuff
    *****************************************************************************/
    -G_DEFINE_TYPE(GPluginGtkView, gplugin_gtk_view, GTK_TYPE_TREE_VIEW);
    +G_DEFINE_TYPE_WITH_PRIVATE(GPluginGtkView, gplugin_gtk_view, GTK_TYPE_TREE_VIEW);
    static void
    gplugin_gtk_view_set_property(GObject *obj, guint prop_id, const GValue *value,
    @@ -128,8 +130,6 @@
    gplugin_gtk_view_class_init(GPluginGtkViewClass *klass) {
    GObjectClass *obj_class = G_OBJECT_CLASS(klass);
    - g_type_class_add_private(obj_class, sizeof(GPluginGtkViewPrivate));
    -
    obj_class->get_property = gplugin_gtk_view_get_property;
    obj_class->set_property = gplugin_gtk_view_set_property;
    obj_class->constructed = gplugin_gtk_view_constructed;
    @@ -142,17 +142,27 @@
    *
    * Whether or not to show internal plugins.
    */
    - g_object_class_install_property(obj_class, PROP_SHOW_INTERNAL,
    - g_param_spec_boolean("show-internal",
    - "show-internal",
    - "Whether or not to show internal plugins",
    - FALSE,
    - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
    + properties[PROP_SHOW_INTERNAL] = g_param_spec_boolean(
    + "show-internal", "show-internal",
    + "Whether or not to show internal plugins",
    + FALSE,
    + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS
    + );
    +
    + g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
    }
    /******************************************************************************
    * API
    *****************************************************************************/
    +
    +/**
    + * gplugin_gtk_view_new:
    + *
    + * Creates a new GPluginGtkView.
    + *
    + * Returns: (transfer full): The new view.
    + */
    GtkWidget *
    gplugin_gtk_view_new(void) {
    GObject *ret = NULL;
    @@ -165,6 +175,14 @@
    return GTK_WIDGET(ret);
    }
    +/**
    + * gplugin_gtk_view_set_show_internal:
    + * @view: The #GPluginGtkView instance
    + * @show_internal: Whether or not to show internal plugins.
    + *
    + * This function will toggle whether or not the widget will show internal
    + * plugins.
    + */
    void
    gplugin_gtk_view_set_show_internal(GPluginGtkView *view,
    gboolean show_internal)
    @@ -173,20 +191,26 @@
    g_return_if_fail(GPLUGIN_GTK_IS_VIEW(view));
    - priv = GPLUGIN_GTK_VIEW_GET_PRIVATE(view);
    + priv = gplugin_gtk_view_get_instance_private(view);
    priv->show_internal = show_internal;
    g_object_notify(G_OBJECT(view), "show-internal");
    }
    +/**
    + * gplugin_gtk_view_get_show_internal:
    + * @view: The #GPluginGtkView instance
    + *
    + * Returns whether or not @view is showing internal plugins.
    + */
    gboolean
    -gplugin_gtk_view_get_show_internal(const GPluginGtkView *view) {
    +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_PRIVATE(view);
    + priv = gplugin_gtk_view_get_instance_private(view);
    return priv->show_internal;
    }
    --- a/gplugin-gtk/gplugin-gtk-view.h Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin-gtk/gplugin-gtk-view.h Tue Jan 22 22:50:20 2019 -0600
    @@ -15,11 +15,9 @@
    * License along with this library; if not, see <http://www.gnu.org/licenses/>.
    */
    -#ifndef __GI_SCANNER__ /* hide this bit from g-ir-scanner */
    #if !defined(GPLUGIN_GTK_GLOBAL_HEADER_INSIDE) && !defined(GPLUGIN_GTK_COMPILATION)
    #error "only <gplugin/gplugin-gtk.h> may be included directly"
    #endif
    -#endif /* __GI_SCANNER__ */
    #ifndef GPLUGIN_GTK_VIEW_H
    #define GPLUGIN_GTK_VIEW_H
    @@ -42,19 +40,13 @@
    struct _GPluginGtkView {
    GtkTreeView parent;
    - void (*_gplugin_reserved1)(void);
    - void (*_gplugin_reserved2)(void);
    - void (*_gplugin_reserved3)(void);
    - void (*_gplugin_reserved4)(void);
    + gpointer reserved[4];
    };
    struct _GPluginGtkViewClass {
    GtkTreeViewClass parent;
    - void (*_gplugin_reserved1)(void);
    - void (*_gplugin_reserved2)(void);
    - void (*_gplugin_reserved3)(void);
    - void (*_gplugin_reserved4)(void);
    + gpointer reserved[4];
    };
    G_BEGIN_DECLS
    @@ -64,7 +56,7 @@
    GtkWidget *gplugin_gtk_view_new(void);
    void gplugin_gtk_view_set_show_internal(GPluginGtkView *view, gboolean show_internal);
    -gboolean gplugin_gtk_view_get_show_internal(const GPluginGtkView *view);
    +gboolean gplugin_gtk_view_get_show_internal(GPluginGtkView *view);
    G_END_DECLS
    --- a/gplugin-gtk/gplugin-gtk-viewer.c Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,215 +0,0 @@
    -/*
    - * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
    - *
    - * This library is free software; you can redistribute it and/or
    - * modify it under the terms of the GNU Lesser General Public
    - * License as published by the Free Software Foundation; either
    - * version 2 of the License, or (at your option) any later version.
    - *
    - * This library is distributed in the hope that it will be useful,
    - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    - * Lesser General Public License for more details.
    - *
    - * You should have received a copy of the GNU Lesser General Public
    - * License along with this library; if not, see <http://www.gnu.org/licenses/>.
    - */
    -
    -#include <stdio.h>
    -#include <stdlib.h>
    -
    -#include <gtk/gtk.h>
    -
    -#include <gplugin/gplugin.h>
    -#include <gplugin-gtk/gplugin-gtk.h>
    -
    -/******************************************************************************
    - * Globals
    - *****************************************************************************/
    -static gboolean show_internal = FALSE;
    -static gboolean add_default_paths = TRUE, version_only = FALSE;
    -static gchar **paths = NULL;
    -
    -/******************************************************************************
    - * Callbacks
    - *****************************************************************************/
    -static gboolean
    -window_closed_cb(GPLUGIN_UNUSED GtkWidget *w,
    - GPLUGIN_UNUSED GdkEvent *e,
    - GPLUGIN_UNUSED gpointer d)
    -{
    - gtk_main_quit();
    -
    - return FALSE;
    -}
    -
    -static void
    -selection_changed_cb(GtkTreeSelection *sel, gpointer data) {
    - GPluginGtkPluginInfo *info = GPLUGIN_GTK_PLUGIN_INFO(data);
    - GPluginPlugin *plugin = NULL;
    - GtkTreeModel *model = NULL;
    - GtkTreeIter iter;
    -
    - if(gtk_tree_selection_get_selected(sel, &model, &iter)) {
    - gtk_tree_model_get(model, &iter,
    - GPLUGIN_GTK_STORE_PLUGIN_COLUMN, &plugin,
    - -1);
    - }
    -
    - gplugin_gtk_plugin_info_set_plugin(info, plugin);
    -}
    -
    -/******************************************************************************
    - * Helpers
    - *****************************************************************************/
    -static gboolean
    -internal_cb(GPLUGIN_UNUSED const gchar *n,
    - GPLUGIN_UNUSED const gchar *v,
    - GPLUGIN_UNUSED gpointer d,
    - GPLUGIN_UNUSED GError **e)
    -{
    - show_internal = TRUE;
    -
    - return TRUE;
    -}
    -
    -static gboolean
    -no_default_cb(GPLUGIN_UNUSED const gchar *n,
    - GPLUGIN_UNUSED const gchar *v,
    - GPLUGIN_UNUSED gpointer d,
    - GPLUGIN_UNUSED GError **e)
    -{
    - add_default_paths = FALSE;
    -
    - return TRUE;
    -}
    -
    -static gboolean
    -version_cb(GPLUGIN_UNUSED const gchar *n,
    - GPLUGIN_UNUSED const gchar *v,
    - GPLUGIN_UNUSED gpointer d,
    - GPLUGIN_UNUSED GError **e)
    -{
    - version_only = TRUE;
    -
    - printf("gplugin-gtk-viewer %s\n", GPLUGIN_VERSION);
    -
    - return TRUE;
    -}
    -
    -static GtkWidget *
    -create_window(void) {
    - GtkWidget *window = NULL, *grid = NULL, *sw = NULL;
    - GtkWidget *view = NULL, *info = NULL;
    - GtkTreeSelection *sel = NULL;
    -
    - window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    - gtk_window_set_title(GTK_WINDOW(window), "GPlugin Viewer");
    - gtk_container_set_border_width(GTK_CONTAINER(window), 12);
    - g_signal_connect(G_OBJECT(window), "delete-event",
    - G_CALLBACK(window_closed_cb), NULL);
    -
    - grid = gtk_grid_new();
    - gtk_grid_set_row_homogeneous(GTK_GRID(grid), TRUE);
    - gtk_grid_set_column_spacing(GTK_GRID(grid), 12);
    - gtk_container_add(GTK_CONTAINER(window), grid);
    -
    - sw = gtk_scrolled_window_new(NULL, NULL);
    - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
    - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
    - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
    - GTK_SHADOW_IN);
    - gtk_grid_attach(GTK_GRID(grid), sw, 0, 0, 1, 1);
    -
    - view = gplugin_gtk_view_new();
    - gplugin_gtk_view_set_show_internal(GPLUGIN_GTK_VIEW(view), show_internal);
    - gtk_container_add(GTK_CONTAINER(sw), view);
    -
    - info = gplugin_gtk_plugin_info_new();
    - gtk_grid_attach(GTK_GRID(grid), info, 1, 0, 1, 1);
    -
    - sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
    - g_signal_connect(G_OBJECT(sel), "changed",
    - G_CALLBACK(selection_changed_cb), info);
    -
    - return window;
    -}
    -
    -/******************************************************************************
    - * Main Stuff
    - *****************************************************************************/
    -static GOptionEntry entries[] = {
    - {
    - "internal", 'i', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
    - internal_cb, "Show internal plugins",
    - NULL,
    - }, {
    - "no-default-paths", 'D', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
    - no_default_cb, "Do not search the default plugin paths",
    - NULL,
    - }, {
    - "path", 'p', 0, G_OPTION_ARG_STRING_ARRAY,
    - &paths, "Additional paths to look for plugins",
    - "PATH",
    - }, {
    - "version", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
    - version_cb, "Display the version and exit",
    - NULL,
    - }, {
    - NULL, 0, 0, 0, NULL, NULL, NULL,
    - },
    -};
    -
    -gint
    -main(gint argc, gchar **argv) {
    - GError *error = NULL;
    - GOptionContext *ctx = NULL;
    - GtkWidget *window = NULL;
    -
    - gtk_init(&argc, &argv);
    -
    - gplugin_init();
    -
    - ctx = g_option_context_new("");
    - g_option_context_add_main_entries(ctx, entries, NULL);
    - g_option_context_add_group(ctx, gtk_get_option_group(TRUE));
    - g_option_context_parse(ctx, &argc, &argv, &error);
    - g_option_context_free(ctx);
    -
    - if(error) {
    - fprintf(stderr, "%s\n", error->message);
    -
    - g_error_free(error);
    -
    - gplugin_uninit();
    -
    - return EXIT_FAILURE;
    - }
    -
    - if(version_only) {
    - return 0;
    - }
    -
    - if(add_default_paths)
    - gplugin_manager_add_default_paths();
    -
    - if(paths) {
    - gint i;
    -
    - for(i = 0; paths[i]; i++)
    - gplugin_manager_prepend_path(paths[i]);
    - }
    -
    - gplugin_manager_refresh();
    -
    - /* now create and show the window */
    - window = create_window();
    - gtk_widget_show_all(window);
    -
    - gtk_main();
    -
    - gplugin_uninit();
    -
    - return 0;
    -}
    -
    --- a/gplugin-gtk/gplugin-gtk.pc.in Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,13 +0,0 @@
    -prefix=@CMAKE_INSTALL_PREFIX@
    -libdir=${prefix}/lib
    -includedir=${prefix}/include/gplugin-1.0/
    -
    -plugindir=${libdir}
    -
    -Name: libgplugin-gtk
    -Description: Gtk+ widgets for GPlugin
    -Version: @GPLUGIN_VERSION@
    -Requires: glib-2.0 gobject-2.0 gmodule-2.0 gplugin
    -Libs: -L${libdir} -lgplugin-gtk
    -Cflags: -I${includedir}
    -
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk/gplugin-gtk.xml.in Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,36 @@
    +<?xml version="1.0" encoding="UTF-8"?>
    +<glade-catalog name="gplugin-gtk"
    + version="@GPLUGIN_VERSION@"
    + library="gplugin-gtk"
    + domain="gplugin"
    + depends="gtk+"
    + book="GPlugin">
    + <glade-widget-classes>
    + <!-- the get-type-function's are needed due to gplugin's weirdo namespace.
    + Without them, Glade is going to look for g_plugin_*_get_type and not
    + gplugin_*_get_type.
    + -->
    + <glade-widget-class
    + name="GPluginGtkPluginInfo"
    + generic-name="plugininfo"
    + title="Plugin Info"
    + get-type-function="gplugin_gtk_plugin_info_get_type"/>
    + <glade-widget-class
    + name="GPluginGtkView"
    + generic-name="pluginview"
    + title="Plugin View"
    + get-type-function="gplugin_gtk_view_get_type"/>
    + <glade-widget-class
    + name="GPluginGtkStore"
    + generic-name="pluginstore"
    + title="Plugin Store"
    + get-type-function="gplugin_gtk_store_get_type"
    + toplevel="True"/>
    + </glade-widget-classes>
    +
    + <glade-widget-group name="gplugin-gtk" title="GPlugin Gtk+ Widgets">
    + <glade-widget-class-ref name="GPluginGtkPluginInfo"/>
    + <glade-widget-class-ref name="GPluginGtkView"/>
    + <glade-widget-class-ref name="GPluginGtkStore"/>
    + </glade-widget-group>
    +</glade-catalog>
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk/meson.build Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,144 @@
    +if get_option('gtk3')
    +
    +###############################################################################
    +# Build Info
    +###############################################################################
    +GTK3 = dependency('gtk+-3.0', version : '>=3.0.0')
    +
    +GPLUGIN_GTK_LIBRARY_VERSION = '0.1.0'
    +
    +GPLUGIN_GTK_SOURCES = [
    + 'gplugin-gtk-plugin-info.c',
    + 'gplugin-gtk-store.c',
    + 'gplugin-gtk-view.c',
    +]
    +
    +GPLUGIN_GTK_HEADERS = [
    + 'gplugin-gtk-plugin-info.h',
    + 'gplugin-gtk-store.h',
    + 'gplugin-gtk-view.h',
    +]
    +
    +GPLUGIN_GTK_PRIVATE_SOURCES = [
    +]
    +
    +GPLUGIN_GTK_PRIVATE_HEADERS = [
    +]
    +
    +GPLUGIN_GTK_PUBLIC_BUILT_SOURCES = [
    +]
    +
    +GPLUGIN_GTK_PUBLIC_BUILT_HEADERS = [
    +]
    +
    +###############################################################################
    +# Configure Files
    +###############################################################################
    +GPLUGIN_GTK_H_INCLUDES = ''
    +
    +foreach header : GPLUGIN_GTK_HEADERS
    + GPLUGIN_GTK_H_INCLUDES = '@0@\n#include <gplugin-gtk/@1@>'.format(
    + GPLUGIN_GTK_H_INCLUDES,
    + header)
    +endforeach
    +
    +conf = configuration_data()
    +conf.set('GPLUGIN_GTK_H_INCLUDES', GPLUGIN_GTK_H_INCLUDES)
    +gplugin_gtk_h = configure_file(
    + input : 'gplugin-gtk.h.in',
    + output : 'gplugin-gtk.h',
    + configuration : conf,
    + install : true,
    + install_dir : join_paths(get_option('includedir'), 'gplugin-1.0'))
    +
    +gplugin_gtk_xml = configure_file(
    + input : 'gplugin-gtk.xml.in',
    + output: 'gplugin-gtk.xml',
    + configuration : version_conf,
    + install: true,
    + install_dir : join_paths(get_option('datadir'), 'glade', 'catalogs'),
    +)
    +
    +###############################################################################
    +# Resource Target
    +###############################################################################
    +gplugin_gtk_resources = gnome.compile_resources(
    + 'gplugin-gtk-resources',
    + 'data/gplugin-gtk.gresource.xml',
    + c_name: 'gplugin_gtk',
    + source_dir: 'data')
    +
    +###############################################################################
    +# Library Target
    +###############################################################################
    +gplugin_gtk = shared_library('gplugin-gtk',
    + GPLUGIN_GTK_SOURCES,
    + GPLUGIN_GTK_HEADERS,
    + GPLUGIN_GTK_PRIVATE_SOURCES,
    + GPLUGIN_GTK_PRIVATE_HEADERS,
    + GPLUGIN_GTK_PUBLIC_BUILT_SOURCES,
    + GPLUGIN_GTK_PUBLIC_BUILT_HEADERS,
    + gplugin_gtk_resources,
    + c_args : ['-DGPLUGIN_GTK_COMPILATION', '-DG_LOG_DOMAIN="GPluginGtk"'],
    + include_directories : toplevel_inc,
    + dependencies : [gplugin_dep, GTK3],
    + version : GPLUGIN_GTK_LIBRARY_VERSION,
    + install : true
    +)
    +
    +gplugin_gtk_inc = include_directories('.')
    +
    +gplugin_gtk_dep = declare_dependency(
    + include_directories: [toplevel_inc, gplugin_gtk_inc],
    + link_with : [gplugin, gplugin_gtk],
    + sources : GPLUGIN_GTK_PUBLIC_BUILT_HEADERS, # Ensure they're built before use.
    + dependencies : [GLIB, GOBJECT, GTK3],
    +)
    +
    +pkgconfig.generate(
    + name : 'libgplugin-gtk',
    + description : 'Gtk+ widgets for GPlugin',
    + version : meson.project_version(),
    + filebase : 'gplugin-gtk',
    + subdirs : 'gplugin-1.0',
    + libraries : gplugin_gtk,
    + requires : ['glib-2.0', 'gobject-2.0', 'gmodule-2.0', 'gplugin'],
    + variables : [
    + 'plugindir=${libdir}',
    + ],
    +)
    +
    +###############################################################################
    +# GObject Introspection
    +###############################################################################
    +if get_option('gobject-introspection')
    + gplugin_gtk_gir = gnome.generate_gir(
    + gplugin_gtk,
    + sources : GPLUGIN_GTK_SOURCES + GPLUGIN_GTK_HEADERS +
    + GPLUGIN_GTK_PUBLIC_BUILT_SOURCES +
    + GPLUGIN_GTK_PUBLIC_BUILT_HEADERS,
    + includes : [gplugin_gir[0], 'Gtk-3.0'],
    + namespace : 'GPluginGtk',
    + symbol_prefix : 'gplugin_gtk',
    + nsversion : '@0@.0'.format(GPLUGIN_MAJOR_VERSION),
    + install : true,
    + extra_args : ['--quiet', '-DGPLUGIN_GTK_COMPILATION'])
    +endif
    +
    +###############################################################################
    +# Install Stuff
    +###############################################################################
    +# install the normal includes into the gplugin-gtk subdirectory
    +install_headers(
    + GPLUGIN_GTK_HEADERS,
    + subdir : 'gplugin-1.0/gplugin-gtk'
    +)
    +
    +###############################################################################
    +# subdirectories
    +###############################################################################
    +if ENABLE_DOC
    + subdir('reference')
    +endif
    +
    +endif # gtk3
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk/reference/gplugin-gtk-docs.xml Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,50 @@
    +<?xml version="1.0"?>
    +<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
    + "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
    +
    +<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
    +<!ENTITY version SYSTEM "version.xml">
    +]>
    +<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
    + <bookinfo>
    + <title>GPlugin Gtk+ Reference Manual</title>
    + <abstract>
    + <title>GPlugin Gtk+ &version;</title>
    + <para>
    + GPlugin Gtk+ is a GObject based library that implements a reusable plugin system that
    + supports loading plugins in other languages
    + via loaders. GPlugin also implements
    + dependencies among the plugins.
    + </para>
    + </abstract>
    + </bookinfo>
    +
    + <part id="object-hierarchy">
    + <title>Object Hierarchy</title>
    +
    + <xi:include href="xml/tree_index.sgml"/>
    + </part>
    +
    + <part id="API">
    + <title>API Reference</title>
    +
    + <xi:include href="xml/gplugin-gtk-plugin-info.xml"/>
    + <xi:include href="xml/gplugin-gtk-store.xml"/>
    + <xi:include href="xml/gplugin-gtk-view.xml"/>
    + </part>
    +
    + <index id="api-index-full">
    + <title>Index</title>
    + <xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
    + </index>
    + <index id="api-index-deprecated" role="deprecated">
    + <title>Index of deprecated symbols</title>
    + <xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
    + </index>
    +<!-- <index id="api-index-2.11.0" role="2.11.0">
    + <title>Index of new symbols in 2.11.0</title>
    + <xi:include href="xml/api-index-2.11.0.xml"><xi:fallback /></xi:include>
    + </index>
    + -->
    + <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
    +</book>
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk/reference/meson.build Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,39 @@
    +DOC_MODULE = 'gplugin-gtk'
    +
    +# Header files or dirs to ignore when scanning. Use base file/dir names
    +ignore_hfiles = [
    + 'gplugin-gtk.h',
    +]
    +ignore_hfiles += GPLUGIN_GTK_PRIVATE_HEADERS
    +
    +# Extra options to supply to gtkdoc-scan.
    +scan_args = [
    + '--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),
    +]
    +
    +gplugin_gtk_version_xml = configure_file(
    + input : 'version.xml.in',
    + output : 'version.xml',
    + configuration : version_conf)
    +
    +content_files = [
    +]
    +
    +gnome.gtkdoc(DOC_MODULE,
    + main_xml : DOC_MODULE + '-docs.xml',
    + src_dir : gplugin_gtk_inc,
    + dependencies : gplugin_gtk_dep,
    + 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-gtk/reference/version.xml.in Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,1 @@
    +@GPLUGIN_VERSION@
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-version.sh.in Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,1 @@
    +export GPLUGIN_VERSION=@GPLUGIN_MAJOR_VERSION@.@GPLUGIN_MINOR_VERSION@.@GPLUGIN_MICRO_VERSION@
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin.sublime-project Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,8 @@
    +{
    + "folders":
    + [
    + {
    + "path": "."
    + }
    + ]
    +}
    --- a/gplugin/CMakeLists.txt Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,292 +0,0 @@
    -###############################################################################
    -# Library
    -###############################################################################
    -
    -set(GPLUGIN_LD_CURRENT 0)
    -set(GPLUGIN_LD_REVISION 1)
    -set(GPLUGIN_LD_AGE 0)
    -set(GPLUGIN_LD_VERSION ${GPLUGIN_LD_CURRENT}.${GPLUGIN_LD_REVISION}.${GPLUGIN_LD_AGE})
    -
    -add_definitions(
    - -DGPLUGIN_COMPILATION
    - -DG_LOG_DOMAIN="GPlugin"
    - -DGI_TYPELIB_PATH="${CMAKE_CURRENT_BINARY_DIR}"
    -)
    -
    -set(GPLUGIN_HEADERS
    - gplugin-core.h
    - gplugin-loader.h
    - gplugin-manager.h
    - gplugin-options.h
    - gplugin-plugin.h
    - gplugin-plugin-info.h
    -)
    -
    -set(GPLUGIN_SOURCES
    - gplugin-core.c
    - gplugin-plugin.c
    - gplugin-loader.c
    - gplugin-manager.c
    - gplugin-options.c
    - gplugin-plugin-info.c
    - gplugin-private.c
    - gplugin-version.c
    -)
    -
    -set(GPLUGIN_PUBLIC_BUILT_HEADERS
    - gplugin-enums.h
    - gplugin-version.h
    -)
    -
    -set(GPLUGIN_PUBLIC_BUILT_SOURCES
    - gplugin-enums.c
    -)
    -
    -set(GPLUGIN_PRIVATE_HEADERS
    - gplugin-file-tree.h
    -)
    -
    -set(GPLUGIN_PRIVATE_SOURCES
    - gplugin-file-tree.c
    -)
    -
    -set(GPLUGIN_PRIVATE_BUILT_HEADERS
    - gplugin-marshallers.h
    -)
    -
    -set(GPLUGIN_PRIVATE_BUILT_SOURCES
    - gplugin-marshallers.c
    -)
    -
    -set(GPLUGIN_NATIVE_HEADERS
    - gplugin-native-plugin.h
    - gplugin-native-loader.h
    -)
    -
    -set(GPLUGIN_NATIVE_SOURCES
    - gplugin-native-plugin.c
    - gplugin-native-loader.c
    -)
    -
    -##############################################################################
    -# Helper Variables
    -###############################################################################
    -# don't add gplugin.h to this, EVER!
    -list(APPEND PUBLIC_HEADERS
    - ${GPLUGIN_HEADERS} ${GPLUGIN_PUBLIC_BUILT_HEADERS}
    -)
    -list(SORT PUBLIC_HEADERS)
    -
    -list(APPEND PRIVATE_HEADERS
    - ${GPLUGIN_PRIVATE_HEADERS}
    - ${GPLUGIN_PRIVATE_BUILT_HEADERS}
    - gplugin-private.h
    - gplugin-native-private.h
    -)
    -
    -###############################################################################
    -# Configure Files
    -###############################################################################
    -configure_file(gplugin-version.h.in gplugin-version.h @ONLY)
    -configure_file(gplugin.pc.in ${CMAKE_CURRENT_BINARY_DIR}/gplugin.pc @ONLY)
    -configure_file(gplugin-uninstalled.pc.in
    - ${CMAKE_CURRENT_BINARY_DIR}/gplugin-uninstalled.pc
    - @ONLY)
    -
    -
    -# build gplugin.h
    -set(GPLUGIN_H_INCLUDES "")
    -
    -foreach(HEADER ${PUBLIC_HEADERS})
    - set(GPLUGIN_H_INCLUDES "${GPLUGIN_H_INCLUDES}\n#include <gplugin/${HEADER}>")
    -endforeach(HEADER)
    -
    -configure_file(gplugin.h.in gplugin.h @ONLY)
    -
    -# build gplugin-native.h
    -set(GPLUGIN_NATIVE_H_INCLUDES "")
    -foreach(HEADER ${GPLUGIN_NATIVE_HEADERS})
    - set(GPLUGIN_NATIVE_H_INCLUDES "${GPLUGIN_NATIVE_H_INCLUDES}\n#include <gplugin/${HEADER}>")
    -endforeach(HEADER)
    -
    -configure_file(gplugin-native.h.in gplugin-native.h @ONLY)
    -
    -###############################################################################
    -# gplugin-enum.[ch] generation
    -###############################################################################
    -set(ENUM_HEADERS
    - gplugin-plugin.h
    -)
    -
    -add_custom_command(
    - OUTPUT gplugin-enums.h
    - DEPENDS ${ENUM_HEADERS} gplugin-enums.h.tmpl
    - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    - COMMAND ${GLIB_MKENUMS} --template gplugin-enums.h.tmpl
    - --identifier-prefix GPlugin ${ENUM_HEADERS} >
    - ${CMAKE_CURRENT_BINARY_DIR}/gplugin-enums.h
    -)
    -
    -add_custom_command(
    - OUTPUT gplugin-enums.c
    - DEPENDS ${ENUM_HEADERS} gplugin-enums.c.tmpl gplugin-enums.h
    - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    - COMMAND ${GLIB_MKENUMS} --template gplugin-enums.c.tmpl
    - --identifier-prefix GPlugin ${ENUM_HEADERS} >
    - ${CMAKE_CURRENT_BINARY_DIR}/gplugin-enums.c
    -)
    -
    -###############################################################################
    -# gplugin-marshallers.[ch] generation
    -###############################################################################
    -add_custom_command(
    - OUTPUT gplugin-marshallers.h
    - DEPENDS gplugin-marshallers.list
    - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    - COMMAND ${GLIB_GENMARSHAL} --header --prefix=gplugin_marshal gplugin-marshallers.list
    - > ${CMAKE_CURRENT_BINARY_DIR}/gplugin-marshallers.h
    -)
    -
    -add_custom_command(
    - OUTPUT gplugin-marshallers.c
    - DEPENDS gplugin-marshallers.list
    - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    - COMMAND ${GLIB_GENMARSHAL} --body --prefix=gplugin_marshal gplugin-marshallers.list
    - > ${CMAKE_CURRENT_BINARY_DIR}/gplugin-marshallers.c
    -)
    -
    -###############################################################################
    -# Library target
    -###############################################################################
    -add_library(gplugin SHARED
    - ${GPLUGIN_SOURCES}
    - ${GPLUGIN_NATIVE_SOURCES}
    - ${GPLUGIN_PUBLIC_BUILT_SOURCES}
    - ${GPLUGIN_PRIVATE_SOURCES}
    - ${GPLUGIN_PRIVATE_BUILT_SOURCES}
    - ${GPLUGIN_NATIVE_HEADERS}
    - ${PUBLIC_HEADERS}
    - ${PRIVATE_HEADERS}
    - gplugin.h
    - gplugin-native.h
    -)
    -
    -set_target_properties(gplugin PROPERTIES
    - SOVERSION ${GPLUGIN_LD_CURRENT}
    - VERSION ${GPLUGIN_LD_VERSION}
    -)
    -
    -target_link_libraries(gplugin
    - ${GLIB_LIBRARIES}
    - ${GMODULE_LIBRARIES}
    -)
    -
    -# nls
    -if(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(NLS)
    -
    -###############################################################################
    -# gplugin-query executable
    -###############################################################################
    -add_executable(gplugin-query gplugin-query.c)
    -target_link_libraries(gplugin-query ${GLIB_LIBRARIES} gplugin)
    -
    -if(BUILD_HELP2MAN)
    - help2man(
    - TARGET gplugin-query
    - OUTPUT gplugin-query.1
    - SECTION 1
    - NAME "Query installed plugins"
    - HELP_OPTION --help-all
    - )
    -endif(BUILD_HELP2MAN)
    -
    -###############################################################################
    -# loader-tests static library
    -###############################################################################
    -add_library(gplugin-loader-tests STATIC
    - gplugin-loader-tests.c
    - gplugin-loader-tests.h
    -)
    -
    -target_link_libraries(gplugin-loader-tests gplugin)
    -
    -###############################################################################
    -# GObject Introspection
    -###############################################################################
    -if(BUILD_GIR)
    - if(APPLE)
    - message("The GObject Introspection build always fails on OS X, "
    - "skipping")
    - else(APPLE)
    - include(GObjectIntrospection)
    -
    - set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:${CMAKE_BINARY_DIR}")
    -
    - gobject_introspection(
    - FILENAME GPlugin-${GPLUGIN_MAJOR_VERSION}.0.gir
    - PACKAGES glib-2.0 gmodule-2.0 gobject-2.0
    - LIBRARY gplugin
    - QUIET
    - SCANNER_ARGS --add-include-path=${CMAKE_CURRENT_SOURCE_DIR}
    - --include=GModule-2.0 --include=GObject-2.0
    - COMPILER_ARGS --includedir=${CMAKE_CURRENT_SOURCE_DIR}
    - SYMBOL_PREFIXES gplugin
    - SOURCES ${GPLUGIN_SOURCES} ${GPLUGIN_HEADERS}
    - BUILT_SOURCES ${GPLUGIN_PUBLIC_BUILT_SOURCES}
    - ${GPLUGIN_PUBLIC_BUILT_HEADERS}
    - )
    - # For loader plugin tests dependencies
    - set(GPLUGIN_GIR_TARGETS ${GPLUGIN_GIR_TARGETS} PARENT_SCOPE)
    - endif(APPLE)
    -endif(BUILD_GIR)
    -
    -###############################################################################
    -# Install Stuff
    -###############################################################################
    -# install the main library
    -install(TARGETS gplugin DESTINATION ${CMAKE_INSTALL_LIBDIR})
    -
    -# install gplugin-query
    -install(TARGETS gplugin-query RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
    -
    -# install the single includes into the main directory
    -install(
    - FILES ${CMAKE_CURRENT_BINARY_DIR}/gplugin.h
    - ${CMAKE_CURRENT_BINARY_DIR}/gplugin-native.h
    - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/gplugin-1.0
    -)
    -
    -# install the normal includes into the gplugin subdirectory
    -foreach(HEADER ${GPLUGIN_HEADERS} ${GPLUGIN_NATIVE_HEADERS})
    - install(
    - FILES ${CMAKE_CURRENT_SOURCE_DIR}/${HEADER}
    - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/gplugin-1.0/gplugin
    - )
    -endforeach(HEADER)
    -
    -# install the built include into the gplugin subdirectory
    -foreach(HEADER ${GPLUGIN_PUBLIC_BUILT_HEADERS})
    - install(
    - FILES ${CMAKE_CURRENT_BINARY_DIR}/${HEADER}
    - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/gplugin-1.0/gplugin
    - )
    -endforeach(HEADER)
    -
    -# pkg-config files
    -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/gplugin.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
    -
    -###############################################################################
    -# subdirectories
    -###############################################################################
    -if(TESTING_ENABLED)
    - add_subdirectory(tests)
    -endif(TESTING_ENABLED)
    -
    --- a/gplugin/gplugin-core.c Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/gplugin-core.c Tue Jan 22 22:50:20 2019 -0600
    @@ -23,15 +23,41 @@
    #include <gplugin/gplugin-private.h>
    #include <gplugin/gplugin-plugin.h>
    +/**
    + * SECTION:gplugin-core
    + * @Title: Core API
    + * @Short_description: the core api
    + *
    + * This section contains the core api of gplugin, which includes #gplugin_init
    + * and #gplugin_uninit.
    + */
    +
    /******************************************************************************
    * API
    *****************************************************************************/
    +
    +/**
    + * GPLUGIN_DOMAIN: (skip)
    + *
    + * The #GError domain used internally by GPlugin
    + */
    +
    +/**
    + * GPLUGIN_GLOBAL_HEADER_INSIDE: (skip)
    + *
    + * This define is used to determine if we're inside the gplugin global header
    + * file or not.
    + */
    +
    /**
    * gplugin_init:
    *
    * Initializes the GPlugin library.
    *
    - * This function *MUST* be called before interacting with any other GPlugin API
    + * This function *MUST* be called before interacting with any other GPlugin
    + * API. The one exception is gplugin_get_option_group(). Parsing options with
    + * the GOptionGroup from gplugin_get_option_group() internally calls
    + * gplugin_init().
    */
    void
    gplugin_init(void) {
    --- a/gplugin/gplugin-core.h Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/gplugin-core.h Tue Jan 22 22:50:20 2019 -0600
    @@ -15,11 +15,9 @@
    * License along with this library; if not, see <http://www.gnu.org/licenses/>.
    */
    -#ifndef __GI_SCANNER__ /* hide this bit from g-ir-scanner */
    #if !defined(GPLUGIN_GLOBAL_HEADER_INSIDE) && !defined(GPLUGIN_COMPILATION)
    #error "only <gplugin.h> may be included directly"
    #endif
    -#endif /* __GI_SCANNER__ */
    #ifndef GPLUGIN_CORE_H
    #define GPLUGIN_CORE_H
    --- a/gplugin/gplugin-enums.c.tmpl Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/gplugin-enums.c.tmpl Tue Jan 22 22:50:20 2019 -0600
    @@ -22,10 +22,18 @@
    /*** 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/@filename@"
    +#include "gplugin/@basename@"
    /*** END file-production ***/
    --- a/gplugin/gplugin-enums.h.tmpl Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/gplugin-enums.h.tmpl Tue Jan 22 22:50:20 2019 -0600
    @@ -27,7 +27,7 @@
    /*** BEGIN file-production ***/
    -/* enumerations from "@filename@" */
    +/* enumerations from "@basename@" */
    /*** END file-production ***/
    /*** BEGIN value-header ***/
    --- a/gplugin/gplugin-loader.c Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/gplugin-loader.c Tue Jan 22 22:50:20 2019 -0600
    @@ -19,36 +19,40 @@
    #include <gplugin/gplugin-core.h>
    +/**
    + * SECTION:gplugin-loader
    + * @Title: Plugin Loader Interface
    + * @Short_description: interface for loading plugins
    + *
    + * A PluginLoader has to implement the interface described here for GPlugin to
    + * be able to use it to load plugins.
    + */
    +
    +/******************************************************************************
    + * GObject Stuff
    + *****************************************************************************/
    +G_DEFINE_ABSTRACT_TYPE(GPluginLoader, gplugin_loader, G_TYPE_OBJECT);
    +
    +static void
    +gplugin_loader_init(GPluginLoader *loader) {
    +}
    +
    +static void
    +gplugin_loader_class_init(GPluginLoaderClass *klass) {
    +}
    +
    /******************************************************************************
    * API
    *****************************************************************************/
    -GType
    -gplugin_loader_get_type(void) {
    - static volatile gsize type_volatile = 0;
    -
    - if(g_once_init_enter(&type_volatile)) {
    - GType type = 0;
    -
    - static const GTypeInfo info = {
    - .class_size = sizeof(GPluginLoaderClass),
    - .instance_size = sizeof(GPluginLoader),
    - };
    -
    - type = g_type_register_static(G_TYPE_OBJECT,
    - "GPluginLoader",
    - &info, G_TYPE_FLAG_ABSTRACT);
    -
    - g_once_init_leave(&type_volatile, type);
    - }
    -
    - return type_volatile;
    -}
    /**
    * gplugin_loader_query_plugin:
    * @loader: #GPluginLoader instance performing the query
    * @filename: filename to query
    - * error: return location for a GError, or NULL
    + * @error: return location for a GError, or NULL
    + *
    + * This function is called by the plugin manager to ask a loader to query the
    + * given file and determine if it's a usable plugin.
    *
    * Return value: (transfer full): A #GPluginPlugin instance or NULL on failure
    */
    @@ -75,7 +79,10 @@
    * gplugin_loader_load_plugin:
    * @loader: #GPluginLoader instance performing the load
    * @plugin: #GPluginPlugin instance to load
    - * error: return location for a GError, or NULL
    + * @error: return location for a GError, or NULL
    + *
    + * This function is called by the plugin manager to ask a loader to load the
    + * given plugin.
    *
    * Return value: TRUE if @plugin was loaded successfully, FALSE otherwise
    */
    @@ -110,6 +117,9 @@
    * @plugin: #GPluginPlugin instance to unload
    * @error: return location for a GError, or NULL
    *
    + * This function is called by the plugin manager to ask a loader to unload the
    + * given plugin.
    + *
    * Return value: TRUE if @plugin was unloaded successfully, FALSE otherwise
    */
    gboolean
    --- a/gplugin/gplugin-loader.h Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/gplugin-loader.h Tue Jan 22 22:50:20 2019 -0600
    @@ -15,11 +15,9 @@
    * License along with this library; if not, see <http://www.gnu.org/licenses/>.
    */
    -#ifndef __GI_SCANNER__ /* hide this bit from g-ir-scanner */
    #if !defined(GPLUGIN_GLOBAL_HEADER_INSIDE) && !defined(GPLUGIN_COMPILATION)
    #error "only <gplugin.h> may be included directly"
    #endif
    -#endif /* __GI_SCANNER__ */
    #ifndef GPLUGIN_LOADER_H
    #define GPLUGIN_LOADER_H
    @@ -42,10 +40,7 @@
    struct _GPluginLoader {
    GObject gparent;
    - void (*_gplugin_reserved_1)(void);
    - void (*_gplugin_reserved_2)(void);
    - void (*_gplugin_reserved_3)(void);
    - void (*_gplugin_reserved_4)(void);
    + gpointer reserved[4];
    };
    struct _GPluginLoaderClass {
    @@ -58,10 +53,7 @@
    gboolean (*load)(GPluginLoader *loader, GPluginPlugin *plugin, GError **error);
    gboolean (*unload)(GPluginLoader *loader, GPluginPlugin *plugin, GError **error);
    - 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
    --- a/gplugin/gplugin-manager.c Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/gplugin-manager.c Tue Jan 22 22:50:20 2019 -0600
    @@ -31,6 +31,15 @@
    #include <gplugin/gplugin-file-tree.h>
    +/**
    + * SECTION:gplugin-manager
    + * @Title: Manager API
    + * @Short_description: API for managing plugins
    + *
    + * The manager is used to manager all plugins in GPlugin. This includes
    + * loading, unloading, querying, checking for new plugins, and so on.
    + */
    +
    /******************************************************************************
    * Enums
    *****************************************************************************/
    @@ -77,6 +86,8 @@
    GList *(*list_plugins)(GPluginManager *manager);
    + GSList *(*get_plugin_dependencies)(GPluginManager *manager, GPluginPlugin *plugin, GError **error);
    +
    gboolean (*load_plugin)(GPluginManager *manager,
    GPluginPlugin *plugin,
    GError **error);
    @@ -298,9 +309,7 @@
    for(l = los; l; l = l->next) {
    GPluginLoader *lo = GPLUGIN_LOADER(l->data);
    - if(!GPLUGIN_IS_LOADER(lo))
    - continue;
    -
    + /* check if this is not the loader we're looking for */
    if(G_OBJECT_TYPE(lo) != type)
    continue;
    @@ -448,14 +457,12 @@
    /* we want the internal filename from the plugin to avoid
    * duplicate memory, so we need to grab it for the "view".
    */
    - gchar *real_filename =
    - gplugin_plugin_get_internal_filename(plugin);
    + gchar *real_filename = gplugin_plugin_get_filename(plugin);
    /* we also need the GPluginPluginInfo to get the plugin's
    * ID for the key in our main hash table.
    */
    - const GPluginPluginInfo *info =
    - gplugin_plugin_get_info(plugin);
    + GPluginPluginInfo *info = gplugin_plugin_get_info(plugin);
    const gchar *id = gplugin_plugin_info_get_id(info);
    GSList *l = NULL, *ll = NULL;
    @@ -593,7 +600,8 @@
    }
    static gboolean
    -gplugin_manager_load_dependencies(const GPluginPluginInfo *info,
    +gplugin_manager_load_dependencies(GPluginPlugin *plugin,
    + GPluginPluginInfo *info,
    GError **error)
    {
    const gchar * const *dependencies = NULL;
    @@ -638,7 +646,7 @@
    * version.
    */
    for(m = matches; m; m = m->next) {
    - GPluginPlugin *dplugin = g_object_ref(G_OBJECT(m->data));
    + GPluginPlugin *dplugin = GPLUGIN_PLUGIN(g_object_ref(G_OBJECT(m->data)));
    gboolean ret = FALSE;
    if(oop && over) {
    @@ -680,6 +688,9 @@
    ret = gplugin_manager_load_plugin(dplugin, error);
    +# warning need to figure out dependencies
    +// gplugin_plugin_add_dependent_plugin(dplugin, plugin);
    +
    g_object_unref(G_OBJECT(dplugin));
    if(ret) {
    @@ -705,12 +716,53 @@
    return TRUE;
    }
    +static GSList *
    +gplugin_manager_real_get_plugin_dependencies(GPluginManager *manager,
    + GPluginPlugin *plugin,
    + GError **error)
    +{
    + GPluginPluginInfo *info = NULL;
    + GSList *ret = NULL;
    + const gchar * const *dependencies = NULL;
    + gint idx = 0;
    +
    + info = gplugin_plugin_get_info(plugin);
    + dependencies = gplugin_plugin_info_get_dependencies(info);
    +
    + if(dependencies == NULL) {
    + return NULL;
    + }
    +
    + for(idx = 0; dependencies[idx] != NULL; idx++) {
    + GPluginPlugin *dep = gplugin_manager_find_plugin(dependencies[idx]);
    +
    + if(!GPLUGIN_IS_PLUGIN(dep)) {
    + if(error) {
    + *error = g_error_new(
    + GPLUGIN_DOMAIN,
    + 0,
    + "failed to find plugin dependency '%s'",
    + dependencies[idx]
    + );
    +
    + g_slist_free_full(ret, g_object_unref);
    +
    + return NULL;
    + }
    + }
    +
    + ret = g_slist_prepend(ret, dep);
    + }
    +
    + return ret;
    +}
    +
    static gboolean
    gplugin_manager_real_load_plugin(GPluginManager *manager,
    GPluginPlugin *plugin,
    GError **error)
    {
    - const GPluginPluginInfo *info = NULL;
    + GPluginPluginInfo *info = NULL;
    GPluginLoader *loader = NULL;
    gboolean ret = TRUE;
    @@ -734,7 +786,7 @@
    return FALSE;
    }
    - if(!gplugin_manager_load_dependencies(info, error)) {
    + if(!gplugin_manager_load_dependencies(plugin, info, error)) {
    g_object_unref(G_OBJECT(info));
    return FALSE;
    @@ -749,7 +801,7 @@
    if(error) {
    *error = g_error_new(GPLUGIN_DOMAIN, 0,
    _("The loader for %s is not a loader. This "
    - "should not happend!"),
    + "should not happened!"),
    gplugin_plugin_get_filename(plugin));
    }
    @@ -882,6 +934,8 @@
    manager_class->find_plugins = gplugin_manager_real_find_plugins;
    manager_class->list_plugins = gplugin_manager_real_list_plugins;
    + manager_class->get_plugin_dependencies = gplugin_manager_real_get_plugin_dependencies;
    +
    manager_class->load_plugin = gplugin_manager_real_load_plugin;
    manager_class->unload_plugin = gplugin_manager_real_unload_plugin;
    @@ -910,7 +964,7 @@
    gplugin_marshal_BOOLEAN__OBJECT_POINTER,
    G_TYPE_BOOLEAN,
    2,
    - GPLUGIN_TYPE_PLUGIN, G_TYPE_POINTER);
    + G_TYPE_OBJECT, G_TYPE_POINTER);
    /**
    * GPluginManager::loaded-plugin:
    @@ -930,7 +984,7 @@
    gplugin_marshal_VOID__OBJECT,
    G_TYPE_NONE,
    1,
    - GPLUGIN_TYPE_PLUGIN);
    + G_TYPE_OBJECT);
    /**
    * GPluginManager::load-failed:
    @@ -949,7 +1003,7 @@
    gplugin_marshal_VOID__OBJECT,
    G_TYPE_NONE,
    1,
    - GPLUGIN_TYPE_PLUGIN);
    + G_TYPE_OBJECT);
    /**
    * GPluginManager::unloading-plugin:
    @@ -970,7 +1024,7 @@
    gplugin_marshal_BOOLEAN__OBJECT_POINTER,
    G_TYPE_BOOLEAN,
    2,
    - GPLUGIN_TYPE_PLUGIN, G_TYPE_POINTER);
    + G_TYPE_OBJECT, G_TYPE_POINTER);
    /**
    * GPluginManager::unloaded-plugin:
    @@ -990,7 +1044,7 @@
    gplugin_marshal_VOID__OBJECT,
    G_TYPE_NONE,
    1,
    - GPLUGIN_TYPE_PLUGIN);
    + G_TYPE_OBJECT);
    }
    static void
    @@ -1030,6 +1084,10 @@
    *****************************************************************************/
    void
    gplugin_manager_private_init(void) {
    + if (instance != NULL) {
    + return;
    + }
    +
    instance = g_object_new(GPLUGIN_TYPE_MANAGER, NULL);
    gplugin_manager_register_loader(GPLUGIN_TYPE_NATIVE_LOADER);
    @@ -1041,7 +1099,7 @@
    gplugin_manager_private_uninit(void) {
    g_regex_unref(dependency_regex);
    - g_object_unref(G_OBJECT(instance));
    + g_clear_object(&instance);
    }
    /******************************************************************************
    @@ -1319,13 +1377,41 @@
    if(plugins_list == NULL)
    return NULL;
    - plugin = g_object_ref(G_OBJECT(plugins_list->data));
    + plugin = GPLUGIN_PLUGIN(g_object_ref(G_OBJECT(plugins_list->data)));
    gplugin_manager_free_plugin_list(plugins_list);
    return plugin;
    }
    +/**
    + * gplugin_manager_get_plugin_dependencies:
    + * @plugin: The #GPluginPlugin whose dependencies to get.
    + * @error: Return address for a #GError.
    + *
    + * Returns a list of all the #GPluginPlugin's that @plugin depends on.
    + *
    + * Return value: (element-type GPlugin.Plugin) (transfer full): A #GSList of
    + * #GPluginPlugin's that @plugin depends on, or NULL on error
    + * with @error set.
    + */
    +GSList *
    +gplugin_manager_get_plugin_dependencies(GPluginPlugin *plugin, GError **error) {
    + GPluginManager *manager = NULL;
    + GPluginManagerClass *klass = NULL;
    +
    + g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), NULL);
    +
    + manager = GPLUGIN_MANAGER_INSTANCE;
    + g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), NULL);
    +
    + klass = GPLUGIN_MANAGER_GET_CLASS(manager);
    + if(klass && klass->get_plugin_dependencies) {
    + return klass->get_plugin_dependencies(manager, plugin, error);
    + }
    +
    + return NULL;
    +}
    /**
    * gplugin_manager_load_plugin:
    --- a/gplugin/gplugin-manager.h Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/gplugin-manager.h Tue Jan 22 22:50:20 2019 -0600
    @@ -15,11 +15,9 @@
    * License along with this library; if not, see <http://www.gnu.org/licenses/>.
    */
    -#ifndef __GI_SCANNER__ /* hide this bit from g-ir-scanner */
    #if !defined(GPLUGIN_GLOBAL_HEADER_INSIDE) && !defined(GPLUGIN_COMPILATION)
    #error "only <gplugin.h> may be included directly"
    #endif
    -#endif /* __GI_SCANNER__ */
    #ifndef GPLUGIN_MANAGER_H
    #define GPLUGIN_MANAGER_H
    @@ -51,6 +49,8 @@
    GPluginPlugin *gplugin_manager_find_plugin(const gchar *id);
    +GSList *gplugin_manager_get_plugin_dependencies(GPluginPlugin *plugin, GError **error);
    +
    gboolean gplugin_manager_load_plugin(GPluginPlugin *plugin, GError **error);
    gboolean gplugin_manager_unload_plugin(GPluginPlugin *plugin, GError **error);
    --- a/gplugin/gplugin-native-loader.c Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/gplugin-native-loader.c Tue Jan 22 22:50:20 2019 -0600
    @@ -30,6 +30,23 @@
    #define GPLUGIN_LOAD_SYMBOL "gplugin_load"
    #define GPLUGIN_UNLOAD_SYMBOL "gplugin_unload"
    +/**
    + * SECTION:gplugin-native-loader
    + * @Title: Native Loader API
    + * @Short_description: API for the native plugin loader
    + *
    + * Basic API for the native plugin loader.
    + */
    +
    +/**
    + * GPLUGIN_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.
    + */
    +
    +G_DEFINE_TYPE(GPluginNativeLoader, gplugin_native_loader, GPLUGIN_TYPE_LOADER);
    +
    /******************************************************************************
    * Helpers
    *****************************************************************************/
    @@ -120,7 +137,7 @@
    GError **error)
    {
    GPluginPlugin *plugin = NULL;
    - const GPluginPluginInfo *info = NULL;
    + GPluginPluginInfo *info = NULL;
    GPluginNativePluginLoadFunc load = NULL;
    GPluginNativePluginQueryFunc query = NULL;
    GPluginNativePluginUnloadFunc unload = NULL;
    @@ -218,19 +235,8 @@
    g_return_val_if_fail(plugin != NULL, FALSE);
    g_return_val_if_fail(GPLUGIN_IS_NATIVE_PLUGIN(plugin), FALSE);
    - /* get the function */
    + /* get and call the function */
    g_object_get(G_OBJECT(plugin), "load-func", &func, NULL);
    -
    - /* validate the function */
    - if(func == NULL) {
    - const char *filename = gplugin_plugin_get_filename(plugin);
    -
    - g_warning(_("load function for %s is NULL"), filename);
    -
    - return FALSE;
    - }
    -
    - /* now call the function */
    if(!func(GPLUGIN_NATIVE_PLUGIN(plugin), error)) {
    if(error && *error == NULL)
    *error = g_error_new(GPLUGIN_DOMAIN, 0, _("unknown failure"));
    @@ -275,6 +281,10 @@
    }
    static void
    +gplugin_native_loader_init(GPluginNativeLoader *loader) {
    +}
    +
    +static void
    gplugin_native_loader_class_init(GPluginNativeLoaderClass *klass) {
    GPluginLoaderClass *loader_class =
    GPLUGIN_LOADER_CLASS(klass);
    @@ -285,31 +295,3 @@
    loader_class->load = gplugin_native_loader_load;
    loader_class->unload = gplugin_native_loader_unload;
    }
    -
    -/******************************************************************************
    - * API
    - *****************************************************************************/
    -GType
    -gplugin_native_loader_get_type(void) {
    - static volatile gsize type_volatile = 0;
    -
    - if(g_once_init_enter(&type_volatile)) {
    - GType type = 0;
    -
    - static const GTypeInfo info = {
    - .class_size = sizeof(GPluginNativeLoaderClass),
    - .class_init = (GClassInitFunc)gplugin_native_loader_class_init,
    - .instance_size = sizeof(GPluginNativeLoader),
    - };
    -
    - type = g_type_register_static(GPLUGIN_TYPE_LOADER,
    - "GPluginNativeLoader",
    - &info, 0);
    -
    - g_once_init_leave(&type_volatile, type);
    - }
    -
    - return type_volatile;
    -}
    -
    -
    --- a/gplugin/gplugin-native-loader.h Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/gplugin-native-loader.h Tue Jan 22 22:50:20 2019 -0600
    @@ -15,11 +15,9 @@
    * License along with this library; if not, see <http://www.gnu.org/licenses/>.
    */
    -#ifndef __GI_SCANNER__ /* hide this bit from g-ir-scanner */
    #if !defined(GPLUGIN_GLOBAL_HEADER_INSIDE) && !defined(GPLUGIN_COMPILATION)
    #error "only <gplugin.h> or <gplugin-native.h> may be included directly"
    #endif
    -#endif /* __GI_SCANNER__ */
    #ifndef GPLUGIN_NATIVE_LOADER_H
    #define GPLUGIN_NATIVE_LOADER_H
    @@ -43,15 +41,14 @@
    struct _GPluginNativeLoader {
    GPluginLoader parent;
    +
    + gpointer reserved[4];
    };
    struct _GPluginNativeLoaderClass {
    GPluginLoaderClass parent;
    - 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
    --- a/gplugin/gplugin-native-plugin.c Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/gplugin-native-plugin.c Tue Jan 22 22:50:20 2019 -0600
    @@ -26,41 +26,29 @@
    #include <glib/gi18n.h>
    -#define GPLUGIN_NATIVE_PLUGIN_GET_PRIVATE(obj) \
    - (G_TYPE_INSTANCE_GET_PRIVATE((obj), GPLUGIN_TYPE_NATIVE_PLUGIN, GPluginNativePluginPrivate))
    +/**
    + * SECTION:gplugin-native-plugin
    + * @Title: Native Plugin API
    + * @Short_description: API for native plugins
    + *
    + * API for use by native plugins. That is plugins written in a compiled
    + * language.
    + */
    /******************************************************************************
    * Structs
    *****************************************************************************/
    -typedef struct _GPluginNativePluginPrivate GPluginNativePluginPrivate;
    -typedef struct _GPluginNativePluginTypeInfo GPluginNativePluginTypeInfo;
    -typedef struct _GPluginNativePluginInterfaceInfo GPluginNativePluginInterfaceInfo;
    -
    -struct _GPluginNativePluginPrivate {
    +typedef struct {
    GModule *module;
    gpointer load_func;
    gpointer unload_func;
    - GSList *type_infos;
    - GSList *interface_infos;
    -
    - guint use_count;
    -};
    -
    -struct _GPluginNativePluginTypeInfo {
    - gboolean loaded;
    - GType type;
    - GType parent;
    - GTypeInfo info;
    -};
    -
    -struct _GPluginNativePluginInterfaceInfo {
    - gboolean loaded;
    - GType instance_type;
    - GType interface_type;
    - GInterfaceInfo info;
    -};
    + gchar *filename;
    + GPluginLoader *loader;
    + GPluginPluginInfo *info;
    + GPluginPluginState state;
    +} GPluginNativePluginPrivate;
    /******************************************************************************
    * Enums
    @@ -70,155 +58,52 @@
    PROP_MODULE,
    PROP_LOAD_FUNC,
    PROP_UNLOAD_FUNC,
    - PROP_LAST,
    + N_PROPERTIES,
    + /* overrides */
    + PROP_FILENAME = N_PROPERTIES,
    + PROP_LOADER,
    + PROP_INFO,
    + PROP_STATE
    };
    -
    -/******************************************************************************
    - * Globals
    - *****************************************************************************/
    -static GObjectClass *parent_class = NULL;
    +static GParamSpec *properties[N_PROPERTIES] = {NULL,};
    /******************************************************************************
    - * Helpers
    + * GPluginPlugin Implementation
    *****************************************************************************/
    -static GPluginNativePluginTypeInfo *
    -gplugin_native_plugin_find_type_info(GPluginNativePlugin *plugin, GType type) {
    - GPluginNativePluginPrivate *priv =
    - GPLUGIN_NATIVE_PLUGIN_GET_PRIVATE(plugin);
    - GSList *l = NULL;
    -
    - for(l = priv->type_infos; l; l = l->next) {
    - GPluginNativePluginTypeInfo *info =
    - (GPluginNativePluginTypeInfo *)(l->data);
    -
    - if(info->type == type)
    - return info;
    - }
    -
    - return NULL;
    -}
    -
    -static GPluginNativePluginInterfaceInfo *
    -gplugin_native_plugin_find_interface_info(GPluginNativePlugin *plugin,
    - GType instance_type,
    - GType interface_type)
    -{
    - GPluginNativePluginPrivate *priv =
    - GPLUGIN_NATIVE_PLUGIN_GET_PRIVATE(plugin);
    - GSList *l = NULL;
    -
    - for(l = priv->interface_infos; l; l = l->next) {
    - GPluginNativePluginInterfaceInfo *info =
    - (GPluginNativePluginInterfaceInfo *)(l->data);
    -
    - if(info->instance_type == instance_type &&
    - info->interface_type == interface_type)
    - {
    - return info;
    - }
    - }
    -
    - return NULL;
    +static void
    +gplugin_native_plugin_iface_init(GPluginPluginInterface *iface) {
    + /* we just override properites from GPluginPlugin */
    }
    /******************************************************************************
    - * GTypePlugin Implementation
    + * GTypeModule Implementation
    *****************************************************************************/
    -static void
    -gplugin_native_plugin_priv_use(GTypePlugin *plugin) {
    - GPluginNativePlugin *native = GPLUGIN_NATIVE_PLUGIN(plugin);
    - GError *error = NULL;
    -
    - if(!gplugin_native_plugin_use(native, &error)) {
    - const GPluginPluginInfo *info =
    - gplugin_plugin_get_info(GPLUGIN_PLUGIN(native));
    - const gchar *name = NULL;
    -
    - if(GPLUGIN_IS_PLUGIN_INFO(info))
    - name = gplugin_plugin_info_get_name(info);
    -
    - g_warning(_("Could not reload previously loaded plugin '%s': %s\n"),
    - name ? name : _("(unknown)"),
    - error ? error->message : _("unknown"));
    -
    - g_object_unref(G_OBJECT(info));
    -
    - if (error)
    - g_error_free(error);
    - }
    +static gboolean
    +gplugin_native_plugin_load(GTypeModule *module) {
    + return TRUE;
    }
    static void
    -gplugin_native_plugin_priv_unuse(GTypePlugin *plugin) {
    - GPluginNativePlugin *native = GPLUGIN_NATIVE_PLUGIN(plugin);
    - GError *error = NULL;
    -
    - if(!gplugin_native_plugin_unuse(native, &error)) {
    - const GPluginPluginInfo *info =
    - gplugin_plugin_get_info(GPLUGIN_PLUGIN(native));
    - const gchar *name = NULL;
    -
    - if(GPLUGIN_IS_PLUGIN_INFO(info))
    - name = gplugin_plugin_info_get_name(info);
    -
    - g_warning(_("Could not unuse plugin '%s': %s\n"),
    - name ? name : _("(unknown)"),
    - error ? error->message : _("unknown"));
    -
    - g_object_unref(G_OBJECT(info));
    -
    - if (error)
    - g_error_free(error);
    - }
    -}
    -
    -static void
    -gplugin_native_plugin_complete_type_info(GTypePlugin *plugin, GType type,
    - GTypeInfo *info,
    - GTypeValueTable *value_table)
    -{
    - GPluginNativePlugin *native = GPLUGIN_NATIVE_PLUGIN(plugin);
    - GPluginNativePluginTypeInfo *native_info =
    - gplugin_native_plugin_find_type_info(native, type);
    -
    - *info = native_info->info;
    -
    - if(native_info->info.value_table)
    - *value_table = *native_info->info.value_table;
    -}
    -
    -static void
    -gplugin_native_plugin_complete_interface_info(GTypePlugin *plugin,
    - GType instance_type,
    - GType interface_type,
    - GInterfaceInfo *info)
    -{
    - GPluginNativePlugin *native = GPLUGIN_NATIVE_PLUGIN(plugin);
    - GPluginNativePluginInterfaceInfo *iface_info =
    - gplugin_native_plugin_find_interface_info(native, instance_type,
    - interface_type);
    -
    - *info = iface_info->info;
    -}
    -
    -static void
    -gplugin_native_plugin_iface_init(GTypePluginClass *iface) {
    - iface->use_plugin = gplugin_native_plugin_priv_use;
    - iface->unuse_plugin = gplugin_native_plugin_priv_unuse;
    - iface->complete_type_info = gplugin_native_plugin_complete_type_info;
    - iface->complete_interface_info =
    - gplugin_native_plugin_complete_interface_info;
    +gplugin_native_plugin_unload(GTypeModule *module) {
    }
    /******************************************************************************
    * GObject Implementation
    *****************************************************************************/
    +G_DEFINE_TYPE_WITH_CODE(
    + GPluginNativePlugin,
    + gplugin_native_plugin,
    + G_TYPE_TYPE_MODULE,
    + G_ADD_PRIVATE(GPluginNativePlugin)
    + G_IMPLEMENT_INTERFACE(GPLUGIN_TYPE_PLUGIN, gplugin_native_plugin_iface_init)
    +);
    +
    static void
    gplugin_native_plugin_get_property(GObject *obj, guint param_id, GValue *value,
    GParamSpec *pspec)
    {
    GPluginNativePlugin *plugin = GPLUGIN_NATIVE_PLUGIN(obj);
    - GPluginNativePluginPrivate *priv = GPLUGIN_NATIVE_PLUGIN_GET_PRIVATE(plugin);
    + GPluginNativePluginPrivate *priv = gplugin_native_plugin_get_instance_private(plugin);
    switch(param_id) {
    case PROP_MODULE:
    @@ -231,6 +116,20 @@
    case PROP_UNLOAD_FUNC:
    g_value_set_pointer(value, priv->unload_func);
    break;
    +
    + /* overrides */
    + case PROP_FILENAME:
    + g_value_set_string(value, priv->filename);
    + break;
    + case PROP_LOADER:
    + g_value_set_object(value, priv->loader);
    + break;
    + case PROP_INFO:
    + g_value_set_object(value, priv->info);
    + break;
    + case PROP_STATE:
    + g_value_set_enum(value, priv->state);
    + break;
    default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
    break;
    @@ -241,7 +140,7 @@
    gplugin_native_plugin_set_property(GObject *obj, guint param_id,
    const GValue *value, GParamSpec *pspec)
    {
    - GPluginNativePluginPrivate *priv = GPLUGIN_NATIVE_PLUGIN_GET_PRIVATE(obj);
    + GPluginNativePluginPrivate *priv = gplugin_native_plugin_get_instance_private(GPLUGIN_NATIVE_PLUGIN(obj));
    switch(param_id) {
    case PROP_MODULE:
    @@ -253,6 +152,21 @@
    case PROP_UNLOAD_FUNC:
    priv->unload_func = g_value_get_pointer(value);
    break;
    +
    + /* overrides */
    + case PROP_FILENAME:
    + priv->filename = g_strdup(g_value_get_string(value));
    + break;
    + case PROP_LOADER:
    + priv->loader = g_object_ref(g_value_get_object(value));
    + break;
    + case PROP_INFO:
    + priv->info = g_object_ref(g_value_get_object(value));
    + break;
    + case PROP_STATE:
    + priv->state = g_value_get_enum(value);
    + break;
    +
    default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
    break;
    @@ -261,400 +175,76 @@
    static void
    gplugin_native_plugin_finalize(GObject *obj) {
    - GPluginNativePluginPrivate *priv = GPLUGIN_NATIVE_PLUGIN_GET_PRIVATE(obj);
    + GPluginNativePluginPrivate *priv = gplugin_native_plugin_get_instance_private(GPLUGIN_NATIVE_PLUGIN(obj));
    +
    + g_free(priv->filename);
    + g_object_unref(G_OBJECT(priv->loader));
    + g_object_unref(G_OBJECT(priv->info));
    - g_slist_free(priv->type_infos);
    - g_slist_free(priv->interface_infos);
    + G_OBJECT_CLASS(gplugin_native_plugin_parent_class)->finalize(obj);
    +}
    - G_OBJECT_CLASS(parent_class)->finalize(obj);
    +static void
    +gplugin_native_plugin_init(GPluginNativePlugin *plugin) {
    }
    static void
    gplugin_native_plugin_class_init(GPluginNativePluginClass *klass) {
    GObjectClass *obj_class = G_OBJECT_CLASS(klass);
    -
    - parent_class = g_type_class_peek_parent(klass);
    -
    - g_type_class_add_private(klass, sizeof(GPluginNativePluginPrivate));
    + GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS(klass);
    obj_class->finalize = gplugin_native_plugin_finalize;
    obj_class->get_property = gplugin_native_plugin_get_property;
    obj_class->set_property = gplugin_native_plugin_set_property;
    + module_class->load = gplugin_native_plugin_load;
    + module_class->unload = gplugin_native_plugin_unload;
    +
    /**
    * GPluginNativePlugin:module:
    *
    * The GModule instance for this plugin.
    */
    - g_object_class_install_property(obj_class, PROP_MODULE,
    - g_param_spec_pointer("module", "module handle",
    - "The GModule instance of the plugin",
    - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
    + properties[PROP_MODULE] = g_param_spec_pointer(
    + "module", "module handle",
    + "The GModule instance of the plugin",
    + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
    + );
    /**
    * GPluginNativePlugin:load-func:
    *
    * A function pointer to the load method of the plugin.
    */
    - g_object_class_install_property(obj_class, PROP_LOAD_FUNC,
    - g_param_spec_pointer("load-func", "load function pointer",
    - "address pointer to load function",
    - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
    + properties[PROP_LOAD_FUNC] = g_param_spec_pointer(
    + "load-func", "load function pointer",
    + "address pointer to load function",
    + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
    + );
    /**
    * GPluginNativePlugin:unload-func:
    *
    * A function pointer to the unload method of the plugin.
    */
    - g_object_class_install_property(obj_class, PROP_UNLOAD_FUNC,
    - g_param_spec_pointer("unload-func", "unload function pointer",
    - "address pointer to the unload function",
    - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
    + properties[PROP_UNLOAD_FUNC] = g_param_spec_pointer(
    + "unload-func", "unload function pointer",
    + "address pointer to the unload function",
    + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
    + );
    +
    + g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
    +
    + /* add our overrides */
    + g_object_class_override_property(obj_class, PROP_FILENAME, "filename");
    + g_object_class_override_property(obj_class, PROP_LOADER, "loader");
    + g_object_class_override_property(obj_class, PROP_INFO, "info");
    + g_object_class_override_property(obj_class, PROP_STATE, "state");
    }
    /******************************************************************************
    * API
    *****************************************************************************/
    -GType
    -gplugin_native_plugin_get_type(void) {
    - static volatile gsize type_volatile = 0;
    -
    - if(g_once_init_enter(&type_volatile)) {
    - GType type = 0;
    -
    - static const GTypeInfo info = {
    - .class_size = sizeof(GPluginNativePluginClass),
    - .class_init = (GClassInitFunc)gplugin_native_plugin_class_init,
    - .instance_size = sizeof(GPluginNativePlugin),
    - };
    -
    - static const GInterfaceInfo iface_info = {
    - .interface_init = (GInterfaceInitFunc)gplugin_native_plugin_iface_init,
    - };
    -
    - type = g_type_register_static(GPLUGIN_TYPE_PLUGIN,
    - "GPluginNativePlugin",
    - &info, 0);
    -
    - g_type_add_interface_static(type, G_TYPE_TYPE_PLUGIN, &iface_info);
    -
    - g_once_init_leave(&type_volatile, type);
    - }
    -
    - return type_volatile;
    -}
    -
    -/**
    - * gplugin_native_plugin_use:
    - * @plugin: a #GPluginNativePlugin
    - * @error: (out): return location for a #GError or null
    - *
    - * Increments the ref count of @plugin by one.
    - *
    - * See: g_type_module_use
    - *
    - * Returns: FALSE if @plugin needed to be loaded and loading failed.
    - */
    -gboolean
    -gplugin_native_plugin_use(GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    -{
    - GPluginNativePluginPrivate *priv = NULL;
    -
    - g_return_val_if_fail(GPLUGIN_IS_NATIVE_PLUGIN(plugin), FALSE);
    -
    - priv = GPLUGIN_NATIVE_PLUGIN_GET_PRIVATE(plugin);
    -
    - priv->use_count++;
    - if(priv->use_count == 1) {
    - GSList *l = NULL;
    -
    - for(l = priv->type_infos; l; l = l->next) {
    - GPluginNativePluginTypeInfo *info =
    - (GPluginNativePluginTypeInfo *)(l->data);
    -
    - if(!info->loaded) {
    - const GPluginPluginInfo *plugin_info =
    - gplugin_plugin_get_info(GPLUGIN_PLUGIN(plugin));
    - const gchar *name = NULL;
    -
    - if(GPLUGIN_IS_PLUGIN_INFO(plugin_info))
    - name = gplugin_plugin_info_get_name(plugin_info);
    -
    - if(name == NULL)
    - name = _("(unknown)");
    -
    - g_warning(_("plugin '%s' failed to register type '%s'\n"),
    - name, g_type_name(info->type));
    -
    - g_object_unref(G_OBJECT(plugin_info));
    -
    - return FALSE;
    - }
    - }
    - }
    -
    - return TRUE;
    -}
    -
    -/**
    - * gplugin_native_plugin_unuse:
    - * @plugin: a #GPluginNativePlugin
    - * @error: (out): return location for a #GError or null
    - *
    - * Decreases the ref count of @plugin by one. If the result is zero, @plugin
    - * is unloaded.
    - *
    - * See: g_type_module_unuse
    - *
    - * Returns: TRUE if successful, FALSE otherwise.
    - */
    -gboolean
    -gplugin_native_plugin_unuse(GPluginNativePlugin *plugin,
    - GPLUGIN_UNUSED GError **error)
    -{
    - GPluginNativePluginPrivate *priv = NULL;
    -
    - g_return_val_if_fail(GPLUGIN_IS_NATIVE_PLUGIN(plugin), FALSE);
    -
    - priv = GPLUGIN_NATIVE_PLUGIN_GET_PRIVATE(plugin);
    -
    - g_return_val_if_fail(priv->use_count > 0, FALSE);
    -
    - priv->use_count--;
    -
    - if(priv->use_count == 0) {
    - GSList *l = NULL;
    -
    - for(l = priv->type_infos; l; l = l->next) {
    - GPluginNativePluginTypeInfo *info =
    - (GPluginNativePluginTypeInfo *)(l->data);
    -
    - info->loaded = FALSE;
    - }
    - }
    -
    - return TRUE;
    -}
    -
    -/**
    - * gplugin_native_plugin_register_type:
    - * @plugin: a #GPluginNativePlugin
    - * @parent: the type for the parent class
    - * @name: name for the type
    - * @info: type information structure
    - * @flags: flags field providing details about the type.
    - *
    - * Looks up or registers a type that is implemented in @plugin.
    - *
    - * See: g_type_module_register_type
    - *
    - * Returns: the new or existing type ID
    - */
    -GType
    -gplugin_native_plugin_register_type(GPluginNativePlugin *plugin, GType parent,
    - const gchar *name, const GTypeInfo *info,
    - GTypeFlags flags)
    -{
    - GPluginNativePluginPrivate *priv = NULL;
    - GPluginNativePluginTypeInfo *type_info = NULL;
    - GType type = G_TYPE_INVALID;
    -
    - g_return_val_if_fail(GPLUGIN_IS_NATIVE_PLUGIN(plugin), G_TYPE_INVALID);
    - g_return_val_if_fail(name, G_TYPE_INVALID);
    - g_return_val_if_fail(info, G_TYPE_INVALID);
    -
    - priv = GPLUGIN_NATIVE_PLUGIN_GET_PRIVATE(plugin);
    -
    - type = g_type_from_name(name);
    -
    - if(type != G_TYPE_INVALID) {
    - /* this type is already loaded, let's make sure it's the same plugin
    - * loading it again.
    - */
    - GTypePlugin *old = g_type_get_plugin(type);
    -
    - if(old != G_TYPE_PLUGIN(plugin)) {
    - g_warning(_("Two different plugins tried to register '%s'"),
    - name);
    -
    - return G_TYPE_INVALID;
    - }
    -
    - /* The same plugin is reloading the type */
    - type_info = gplugin_native_plugin_find_type_info(plugin, type);
    - if(type_info == NULL)
    - return G_TYPE_INVALID;
    -
    - if(type_info->parent != parent) {
    - /* eek, them bastards tried to reparent this type! */
    -
    - const gchar *parent_name = g_type_name(parent);
    -
    - g_warning(_("Type '%s' was recreated with a different parent type."
    - "(was '%s', now '%s')"),
    - name, g_type_name(type_info->parent),
    - (parent_name) ? parent_name : _("unknown"));
    -
    - return G_TYPE_INVALID;
    - }
    -
    - /* we need to free the old vtable if the old type had one */
    - if(type_info->info.value_table)
    - g_free((GTypeValueTable *)type_info->info.value_table);
    - } else {
    - /* the type hasn't been loaded before, so now we need to add it */
    - type_info = g_new(GPluginNativePluginTypeInfo, 1);
    -
    - type_info->parent = parent;
    - type_info->type = g_type_register_dynamic(parent, name,
    - G_TYPE_PLUGIN(plugin),
    - flags);
    -
    - priv->type_infos = g_slist_prepend(priv->type_infos, type_info);
    - }
    -
    - /* ok, now finish up */
    - type_info->loaded = TRUE;
    - type_info->info = *info;
    -
    - if(info->value_table) {
    - type_info->info.value_table = g_memdup(info->value_table,
    - sizeof(GTypeValueTable));
    - }
    -
    - if(g_type_is_a(type_info->type, GPLUGIN_TYPE_LOADER) &&
    - !G_TYPE_IS_ABSTRACT(type_info->type))
    - {
    - gplugin_manager_register_loader(type_info->type);
    - }
    -
    - return type_info->type;
    -}
    -
    -/**
    - * gplugin_native_plugin_add_interface:
    - * @plugin: a #GPluginNativePlugin
    - * @instance_type: type to which to add the interface
    - * @interface_type: interface type to add
    - * @interface_info: type information structure
    - *
    - * Registers an additional interface for a type that lives in @plugin.
    - *
    - * See: g_type_module_add_interface
    - */
    -void
    -gplugin_native_plugin_add_interface(GPluginNativePlugin *plugin,
    - GType instance_type, GType interface_type,
    - const GInterfaceInfo *interface_info)
    -{
    - GPluginNativePluginPrivate *priv = NULL;
    - GPluginNativePluginInterfaceInfo *iface_info = NULL;
    -
    - g_return_if_fail(GPLUGIN_IS_NATIVE_PLUGIN(plugin));
    - g_return_if_fail(interface_info);
    -
    - priv = GPLUGIN_NATIVE_PLUGIN_GET_PRIVATE(plugin);
    -
    - if(g_type_is_a(instance_type, interface_type)) {
    - GTypePlugin *old = g_type_interface_get_plugin(instance_type,
    - interface_type);
    -
    - if(!old) {
    - g_warning(_("Interface '%s' for '%s' was previously registered "
    - "statically or for a parent type."),
    - g_type_name(interface_type),
    - g_type_name(instance_type));
    - return;
    - } else if(old != G_TYPE_PLUGIN(plugin)) {
    - g_warning(_("Two different plugins tried to register interface "
    - "'%s' for '%s')"),
    - g_type_name(interface_type),
    - g_type_name(instance_type));
    - return;
    - }
    -
    - iface_info = gplugin_native_plugin_find_interface_info(plugin,
    - instance_type,
    - interface_type);
    -
    - g_return_if_fail(iface_info);
    - } else {
    - iface_info = g_new0(GPluginNativePluginInterfaceInfo, 1);
    -
    - iface_info->instance_type = instance_type;
    - iface_info->interface_type = interface_type;
    -
    - g_type_add_interface_dynamic(instance_type, interface_type,
    - G_TYPE_PLUGIN(plugin));
    -
    - priv->interface_infos = g_slist_prepend(priv->interface_infos,
    - iface_info);
    - }
    -
    - iface_info->loaded = TRUE;
    - iface_info->info = *interface_info;
    -}
    -
    -/**
    - * gplugin_native_plugin_register_enum:
    - * @plugin: a #GPluginNativePlugin
    - * @name: a name for the type
    - * @values: an array of %GEnumValue structs for the possible enumeration
    - * values. The array is terminated by a struct with all members being
    - * 0.
    - *
    - * Looks up or registers a new enumeration named @name with the given @values,
    - * and associates it with @plugin.
    - *
    - * See: g_type_module_register_enum
    - *
    - * Returns: the new or existing type ID.
    - */
    -GType
    -gplugin_native_plugin_register_enum(GPluginNativePlugin *plugin,
    - const gchar *name,
    - const GEnumValue *values)
    -{
    - GTypeInfo enum_info;
    -
    - g_return_val_if_fail(GPLUGIN_IS_NATIVE_PLUGIN(plugin), G_TYPE_INVALID);
    - g_return_val_if_fail(name, G_TYPE_INVALID);
    - g_return_val_if_fail(values, G_TYPE_INVALID);
    -
    - g_enum_complete_type_info(G_TYPE_ENUM, &enum_info, values);
    -
    - return gplugin_native_plugin_register_type(plugin, G_TYPE_ENUM, name,
    - &enum_info, 0);
    -}
    -
    -/**
    - * gplugin_native_plugin_register_flags:
    - * @plugin: a #GPluginNativePlugin
    - * @name: name for the type
    - * @values: an array of %GFlagValue structs for the possible flags values. The
    - * array is terminated by a struct with all members being 0.
    - *
    - * See: g_type_module_register_flags
    - *
    - * Returns: the new or existing type ID.
    - */
    -GType
    -gplugin_native_plugin_register_flags(GPluginNativePlugin *plugin,
    - const gchar *name,
    - const GFlagsValue *values)
    -{
    - GTypeInfo flags_info;
    -
    - g_return_val_if_fail(GPLUGIN_IS_NATIVE_PLUGIN(plugin), G_TYPE_INVALID);
    - g_return_val_if_fail(name, G_TYPE_INVALID);
    - g_return_val_if_fail(values, G_TYPE_INVALID);
    -
    - g_flags_complete_type_info(G_TYPE_FLAGS, &flags_info, values);
    -
    - return gplugin_native_plugin_register_type(plugin, G_TYPE_FLAGS, name,
    - &flags_info, 0);
    -}
    /**
    * gplugin_native_plugin_get_module: (skip)
    @@ -671,7 +261,7 @@
    g_return_val_if_fail(GPLUGIN_IS_NATIVE_PLUGIN(plugin), NULL);
    - priv = GPLUGIN_NATIVE_PLUGIN_GET_PRIVATE(plugin);
    + priv = gplugin_native_plugin_get_instance_private(plugin);
    return priv->module;
    }
    --- a/gplugin/gplugin-native-plugin.h Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/gplugin-native-plugin.h Tue Jan 22 22:50:20 2019 -0600
    @@ -15,11 +15,9 @@
    * License along with this library; if not, see <http://www.gnu.org/licenses/>.
    */
    -#ifndef __GI_SCANNER__ /* hide this bit from g-ir-scanner */
    #if !defined(GPLUGIN_GLOBAL_HEADER_INSIDE) && !defined(GPLUGIN_COMPILATION)
    #error "only <gplugin.h> or <gplugin-native.h> may be included directly"
    #endif
    -#endif /* __GI_SCANNER__ */
    #ifndef GPLUGIN_NATIVE_PLUGIN_H
    #define GPLUGIN_NATIVE_PLUGIN_H
    @@ -39,35 +37,23 @@
    #include <gmodule.h>
    struct _GPluginNativePlugin {
    - GPluginPlugin parent;
    + /*< private >*/
    + GTypeModule parent;
    - void (*_gplugin_reserved_1)(void);
    - void (*_gplugin_reserved_2)(void);
    - void (*_gplugin_reserved_3)(void);
    - void (*_gplugin_reserved_4)(void);
    + gpointer reserved[4];
    };
    struct _GPluginNativePluginClass {
    - GPluginPluginClass parent;
    + /*< private >*/
    + GTypeModuleClass parent;
    - 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_native_plugin_get_type(void);
    -gboolean gplugin_native_plugin_use(GPluginNativePlugin *plugin, GError **error);
    -gboolean gplugin_native_plugin_unuse(GPluginNativePlugin *plugin, GError **error);
    -
    -GType gplugin_native_plugin_register_type(GPluginNativePlugin *plugin, GType parent, const gchar *name, const GTypeInfo *info, GTypeFlags flags);
    -void gplugin_native_plugin_add_interface(GPluginNativePlugin *plugin, GType instance_type, GType interface_type, const GInterfaceInfo *interface_info);
    -GType gplugin_native_plugin_register_enum(GPluginNativePlugin *plugin, const gchar *name, const GEnumValue *values);
    -GType gplugin_native_plugin_register_flags(GPluginNativePlugin *plugin, const gchar *name, const GFlagsValue *values);
    -
    GModule *gplugin_native_plugin_get_module(GPluginNativePlugin *plugin);
    G_END_DECLS
    --- a/gplugin/gplugin-native-private.h Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/gplugin-native-private.h Tue Jan 22 22:50:20 2019 -0600
    @@ -15,11 +15,9 @@
    * License along with this library; if not, see <http://www.gnu.org/licenses/>.
    */
    -#ifndef __GI_SCANNER__ /* hide this bit from g-ir-scanner */
    #if !defined(GPLUGIN_GLOBAL_HEADER_INSIDE) && !defined(GPLUGIN_COMPILATION)
    #error "only <gplugin-native.h> may be included directly"
    #endif
    -#endif /* __GI_SCANNER__ */
    #ifndef GPLUGIN_NATIVE_PRIVATE_H
    #define GPLUGIN_NATIVE_PRIVATE_H
    --- a/gplugin/gplugin-options.c Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/gplugin-options.c Tue Jan 22 22:50:20 2019 -0600
    @@ -21,8 +21,19 @@
    #include <gplugin/gplugin-options.h>
    +#include <gplugin/gplugin-core.h>
    #include <gplugin/gplugin-manager.h>
    +/**
    + * SECTION:gplugin-options
    + * @Title: Command line option support
    + * @Short_description: command line option support
    + *
    + * This section contains #gplugin_get_option_group that makes it easy to
    + * initialize GPlugin from your application when it is added to a
    + * #GOptionContext.
    + */
    +
    /******************************************************************************
    * Options
    *****************************************************************************/
    @@ -63,6 +74,8 @@
    {
    gint i = 0;
    + gplugin_init();
    +
    if(add_default_paths)
    gplugin_manager_add_default_paths();
    --- a/gplugin/gplugin-options.h Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/gplugin-options.h Tue Jan 22 22:50:20 2019 -0600
    @@ -15,11 +15,9 @@
    * License along with this library; if not, see <http://www.gnu.org/licenses/>.
    */
    -#ifndef __GI_SCANNER__ /* hide this bit from g-ir-scanner */
    #if !defined(GPLUGIN_GLOBAL_HEADER_INSIDE) && !defined(GPLUGIN_COMPILATION)
    #error "only <gplugin.h> may be included directly"
    #endif
    -#endif /* __GI_SCANNER__ */
    #ifndef GPLUGIN_OPTIONS_H
    #define GPLUGIN_OPTIONS_H
    --- a/gplugin/gplugin-plugin-info.c Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/gplugin-plugin-info.c Tue Jan 22 22:50:20 2019 -0600
    @@ -21,8 +21,13 @@
    #include <gplugin/gplugin-enums.h>
    #include <gplugin/gplugin-private.h>
    -#define GPLUGIN_PLUGIN_INFO_GET_PRIVATE(obj) \
    - (G_TYPE_INSTANCE_GET_PRIVATE((obj), GPLUGIN_TYPE_PLUGIN_INFO, GPluginPluginInfoPrivate))
    +/**
    + * SECTION:gplugin-plugin-info
    + * @Title: Plugin Info Objects
    + * @Short_description: information about plugins
    + *
    + * #GPluginPluginInfo holds metadata for plugins.
    + */
    /******************************************************************************
    * Structs
    @@ -83,18 +88,16 @@
    PROP_DEPENDENCIES,
    N_PROPERTIES,
    };
    +static GParamSpec *properties[N_PROPERTIES] = {NULL,};
    -/******************************************************************************
    - * Globals
    - *****************************************************************************/
    -static GObjectClass *parent_class = NULL;
    +G_DEFINE_TYPE_WITH_PRIVATE(GPluginPluginInfo, gplugin_plugin_info, G_TYPE_INITIALLY_UNOWNED)
    /******************************************************************************
    * Private API
    *****************************************************************************/
    static void
    gplugin_plugin_info_set_id(GPluginPluginInfo *info, const gchar *id) {
    - GPluginPluginInfoPrivate *priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    g_free(priv->id);
    priv->id = (id) ? g_strdup(id) : NULL;
    @@ -104,21 +107,21 @@
    gplugin_plugin_info_set_abi_version(GPluginPluginInfo *info,
    guint32 abi_version)
    {
    - GPluginPluginInfoPrivate *priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    priv->abi_version = abi_version;
    }
    static void
    gplugin_plugin_info_set_internal(GPluginPluginInfo *info, gboolean internal) {
    - GPluginPluginInfoPrivate *priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    priv->internal = internal;
    }
    static void
    gplugin_plugin_info_set_load_on_query(GPluginPluginInfo *info, gboolean loq) {
    - GPluginPluginInfoPrivate *priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    priv->load_on_query = loq;
    }
    @@ -127,14 +130,14 @@
    gplugin_plugin_info_set_bind_local(GPluginPluginInfo *info,
    gboolean bind_local)
    {
    - GPluginPluginInfoPrivate *priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    priv->bind_local = bind_local;
    }
    static void
    gplugin_plugin_info_set_name(GPluginPluginInfo *info, const gchar *name) {
    - GPluginPluginInfoPrivate *priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    g_free(priv->name);
    priv->name = (name) ? g_strdup(name) : NULL;
    @@ -144,7 +147,7 @@
    gplugin_plugin_info_set_version(GPluginPluginInfo *info,
    const gchar *version)
    {
    - GPluginPluginInfoPrivate *priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    g_free(priv->version);
    priv->version = (version) ? g_strdup(version) : NULL;
    @@ -154,7 +157,7 @@
    gplugin_plugin_info_set_version_func(GPluginPluginInfo *info,
    GPluginVersionCompareFunc func)
    {
    - GPluginPluginInfoPrivate *priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    priv->version_func = func;
    }
    @@ -163,7 +166,7 @@
    gplugin_plugin_info_set_license_id(GPluginPluginInfo *info,
    const gchar *license_id)
    {
    - GPluginPluginInfoPrivate *priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    g_free(priv->license_id);
    priv->license_id = (license_id) ? g_strdup(license_id) : NULL;
    @@ -174,7 +177,7 @@
    gplugin_plugin_info_set_license_text(GPluginPluginInfo *info,
    const gchar *license_text)
    {
    - GPluginPluginInfoPrivate *priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    g_free(priv->license_text);
    priv->license_text = (license_text) ? g_strdup(license_text) : NULL;
    @@ -185,7 +188,7 @@
    gplugin_plugin_info_set_license_url(GPluginPluginInfo *info,
    const gchar *license_url)
    {
    - GPluginPluginInfoPrivate *priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    g_free(priv->license_url);
    priv->license_url = (license_url) ? g_strdup(license_url) : NULL;
    @@ -193,7 +196,7 @@
    static void
    gplugin_plugin_info_set_icon(GPluginPluginInfo *info, const gchar *icon) {
    - GPluginPluginInfoPrivate *priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    g_free(priv->icon);
    priv->icon = (icon) ? g_strdup(icon) : NULL;
    @@ -203,7 +206,7 @@
    gplugin_plugin_info_set_summary(GPluginPluginInfo *info,
    const gchar *summary)
    {
    - GPluginPluginInfoPrivate *priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    g_free(priv->summary);
    priv->summary = (summary) ? g_strdup(summary) : NULL;
    @@ -213,7 +216,7 @@
    gplugin_plugin_info_set_description(GPluginPluginInfo *info,
    const gchar *description)
    {
    - GPluginPluginInfoPrivate *priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    g_free(priv->description);
    priv->description = (description) ? g_strdup(description) : NULL;
    @@ -223,7 +226,7 @@
    gplugin_plugin_info_set_category(GPluginPluginInfo *info,
    const gchar *category)
    {
    - GPluginPluginInfoPrivate *priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    g_free(priv->category);
    priv->category = (category) ? g_strdup(category) : NULL;
    @@ -232,7 +235,7 @@
    static void
    gplugin_plugin_info_set_authors(GPluginPluginInfo *info,
    const gchar * const *authors) {
    - GPluginPluginInfoPrivate *priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    g_strfreev(priv->authors);
    @@ -242,7 +245,7 @@
    static void
    gplugin_plugin_info_set_help(GPluginPluginInfo *info, const gchar *help)
    {
    - GPluginPluginInfoPrivate *priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    g_free(priv->help);
    priv->help = (help) ? g_strdup(help) : NULL;
    @@ -252,7 +255,7 @@
    gplugin_plugin_info_set_website(GPluginPluginInfo *info,
    const gchar *website)
    {
    - GPluginPluginInfoPrivate *priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    g_free(priv->website);
    priv->website = (website) ? g_strdup(website) : NULL;
    @@ -262,7 +265,7 @@
    gplugin_plugin_info_set_dependencies(GPluginPluginInfo *info,
    const gchar * const *dependencies)
    {
    - GPluginPluginInfoPrivate *priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(info);
    g_strfreev(priv->dependencies);
    @@ -430,7 +433,7 @@
    static void
    gplugin_plugin_info_finalize(GObject *obj) {
    - GPluginPluginInfoPrivate *priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(obj);
    + GPluginPluginInfoPrivate *priv = gplugin_plugin_info_get_instance_private(GPLUGIN_PLUGIN_INFO(obj));
    g_free(priv->id);
    g_free(priv->name);
    @@ -446,17 +449,17 @@
    g_free(priv->website);
    g_strfreev(priv->dependencies);
    - G_OBJECT_CLASS(parent_class)->finalize(obj);
    + G_OBJECT_CLASS(gplugin_plugin_info_parent_class)->finalize(obj);
    +}
    +
    +static void
    +gplugin_plugin_info_init(GPluginPluginInfo *info) {
    }
    static void
    gplugin_plugin_info_class_init(GPluginPluginInfoClass *klass) {
    GObjectClass *obj_class = G_OBJECT_CLASS(klass);
    - parent_class = g_type_class_peek_parent(klass);
    -
    - g_type_class_add_private(klass, sizeof(GPluginPluginInfoPrivate));
    -
    obj_class->get_property = gplugin_plugin_info_get_property;
    obj_class->set_property = gplugin_plugin_info_set_property;
    obj_class->finalize = gplugin_plugin_info_finalize;
    @@ -468,17 +471,18 @@
    * The id of the plugin.
    *
    * While not required, the recommended convention is to use the following
    - * format: <application or library>/<name of the plugin>.
    + * format: &lt;application or library&gt;/&lt;name of the plugin&gt;.
    *
    * For example, the python loader in GPlugin has an id of
    * "gplugin/python-plugin-loader".
    */
    - g_object_class_install_property(obj_class, PROP_ID,
    - g_param_spec_string("id", "id",
    - "The ID of the plugin",
    - NULL,
    - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
    - G_PARAM_CONSTRUCT_ONLY));
    + properties[PROP_ID] = g_param_spec_string(
    + "id", "id",
    + "The ID of the plugin",
    + NULL,
    + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
    + G_PARAM_CONSTRUCT_ONLY
    + );
    /**
    * GPluginPluginInfo:abi-version:
    @@ -497,12 +501,12 @@
    * The application here uses the thrid and fourth bytes, but could use
    * the second as well.
    */
    - g_object_class_install_property(obj_class, PROP_ABI_VERSION,
    - g_param_spec_uint("abi-version", "abi_version",
    - "The ABI version of the plugin",
    - 0, G_MAXUINT32, 0,
    - G_PARAM_READWRITE |
    - G_PARAM_CONSTRUCT_ONLY));
    + properties[PROP_ABI_VERSION] = g_param_spec_uint(
    + "abi-version", "abi_version",
    + "The ABI version of the plugin",
    + 0, G_MAXUINT32, 0,
    + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
    + );
    /**
    * GPluginPluginInfo:internal:
    @@ -511,12 +515,12 @@
    *
    * Defaults to FALSE.
    */
    - g_object_class_install_property(obj_class, PROP_INTERNAL,
    - g_param_spec_boolean("internal", "internal",
    - "Whether or not the plugin is an internal plugin",
    - FALSE,
    - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
    - G_PARAM_STATIC_STRINGS));
    + properties[PROP_INTERNAL] = g_param_spec_boolean(
    + "internal", "internal",
    + "Whether or not the plugin is an internal plugin",
    + FALSE,
    + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS
    + );
    /**
    * GPluginPluginInfo:load-on-query:
    @@ -528,13 +532,12 @@
    *
    * Defaults to FALSE.
    */
    - g_object_class_install_property(obj_class, PROP_LOQ,
    - g_param_spec_boolean("load-on-query", "load-on-query",
    - "Whether or not the plugin should be loaded when "
    - "queried",
    - FALSE,
    - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
    - G_PARAM_STATIC_STRINGS));
    + properties[PROP_LOQ] = g_param_spec_boolean(
    + "load-on-query", "load-on-query",
    + "Whether or not the plugin should be loaded when queried",
    + FALSE,
    + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS
    + );
    /**
    * GPluginPluginInfo:bind-local:
    @@ -543,48 +546,47 @@
    *
    * Note: This should only be used by the native plugin loader.
    */
    - g_object_class_install_property(obj_class, PROP_BIND_LOCAL,
    - g_param_spec_boolean("bind-local", "bind-local",
    - "Whether symbols should be bound locally",
    - FALSE,
    - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
    - G_PARAM_STATIC_STRINGS));
    + properties[PROP_BIND_LOCAL] = g_param_spec_boolean(
    + "bind-local", "bind-local",
    + "Whether symbols should be bound locally",
    + FALSE,
    + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS
    + );
    /**
    * GPluginPluginInfo:name:
    *
    * The display name of the plugin. This should be a translated string.
    */
    - g_object_class_install_property(obj_class, PROP_NAME,
    - g_param_spec_string("name", "name",
    - "The name of the plugin",
    - NULL,
    - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
    - G_PARAM_CONSTRUCT_ONLY));
    + properties[PROP_NAME] = g_param_spec_string(
    + "name", "name",
    + "The name of the plugin",
    + NULL,
    + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
    + );
    /**
    * GPluginPluginInfo:version:
    *
    * The version of the plugin.
    */
    - g_object_class_install_property(obj_class, PROP_VERSION,
    - g_param_spec_string("version", "version",
    - "The version of the plugin",
    - NULL,
    - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
    - G_PARAM_CONSTRUCT_ONLY));
    + properties[PROP_VERSION] = g_param_spec_string(
    + "version", "version",
    + "The version of the plugin",
    + NULL,
    + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
    + );
    /**
    * GPluginPluginInfo:version-func:
    *
    * The function to use to compare versions of this plugin.
    */
    - g_object_class_install_property(obj_class, PROP_VERSION_FUNC,
    - g_param_spec_pointer("version-func", "version-func",
    - "The function that can compare versions of " \
    - "this plugin",
    - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
    - G_PARAM_CONSTRUCT_ONLY));
    + properties[PROP_VERSION_FUNC] = g_param_spec_pointer(
    + "version-func", "version-func",
    + "The function that can compare versions of this plugin",
    + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
    + );
    /**
    * GPluginPluginInfo:license-id:
    @@ -599,12 +601,12 @@
    * (|). In the odd case that you have multiple licenses that are used at
    * the same time, they should be separated by an ampersand (&).
    */
    - g_object_class_install_property(obj_class, PROP_LICENSE_ID,
    - g_param_spec_string("license-id", "license-id",
    - "The license id of the plugin according to SPDX",
    - NULL,
    - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
    - G_PARAM_CONSTRUCT_ONLY));
    + properties[PROP_LICENSE_ID] = g_param_spec_string(
    + "license-id", "license-id",
    + "The license id of the plugin according to SPDX",
    + NULL,
    + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
    + );
    /**
    * GPluginPluginInfo:license-text:
    @@ -612,12 +614,12 @@
    * The text of the license for this plugin. This should only be used when
    * the plugin is licensed under a license that is not listed in DEP5.
    */
    - g_object_class_install_property(obj_class, PROP_LICENSE_TEXT,
    - g_param_spec_string("license-text", "license text",
    - "The text of the license for the plugin",
    - NULL,
    - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
    - G_PARAM_CONSTRUCT_ONLY));
    + properties[PROP_LICENSE_TEXT] = g_param_spec_string(
    + "license-text", "license text",
    + "The text of the license for the plugin",
    + NULL,
    + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
    + );
    /**
    * GPluginPluginInfo:license-url:
    @@ -625,12 +627,12 @@
    * The url to the text of the license. This should primarily only be used
    * for licenses not listed in DEP5.
    */
    - g_object_class_install_property(obj_class, PROP_LICENSE_URL,
    - g_param_spec_string("license-url", "license url",
    - "The url to the license of the plugin",
    - NULL,
    - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
    - G_PARAM_CONSTRUCT_ONLY));
    + properties[PROP_LICENSE_URL] = g_param_spec_string(
    + "license-url", "license url",
    + "The url to the license of the plugin",
    + NULL,
    + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
    + );
    /**
    * GPluginPluginInfo:icon:
    @@ -638,12 +640,12 @@
    * A string representing an icon for the plugin. The actual use of this
    * is determined by the application/library using GPlugin.
    */
    - g_object_class_install_property(obj_class, PROP_ICON,
    - g_param_spec_string("icon", "icon",
    - "The file path of the icon for the plugin",
    - NULL,
    - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
    - G_PARAM_CONSTRUCT_ONLY));
    + properties[PROP_ICON] = g_param_spec_string(
    + "icon", "icon",
    + "The file path of the icon for the plugin",
    + NULL,
    + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
    + );
    /**
    * GPluginPluginInfo:summary:
    @@ -651,12 +653,12 @@
    * A short description of the plugin that can be listed with the name in a
    * user interface.
    */
    - g_object_class_install_property(obj_class, PROP_SUMMARY,
    - g_param_spec_string("summary", "summary",
    - "The summary of the plugin",
    - NULL,
    - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
    - G_PARAM_CONSTRUCT_ONLY));
    + properties[PROP_SUMMARY] = g_param_spec_string(
    + "summary", "summary",
    + "The summary of the plugin",
    + NULL,
    + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
    + );
    /**
    * GPluginPluginInfo:description:
    @@ -664,12 +666,12 @@
    * The full description of the plugin that will be used in a "more
    * information" section in a user interface.
    */
    - g_object_class_install_property(obj_class, PROP_DESCRIPTION,
    - g_param_spec_string("description", "description",
    - "The description of the plugin",
    - NULL,
    - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
    - G_PARAM_CONSTRUCT_ONLY));
    + properties[PROP_DESCRIPTION] = g_param_spec_string(
    + "description", "description",
    + "The description of the plugin",
    + NULL,
    + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
    + );
    /**
    * GPluginPluginInfo:category:
    @@ -681,12 +683,12 @@
    * set of categories that plugin authors should use, and put all plugins
    * that don't match this category into an "Other" category.
    */
    - g_object_class_install_property(obj_class, PROP_CATEGORY,
    - g_param_spec_string("category", "category",
    - "The category of the plugin",
    - NULL,
    - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
    - G_PARAM_CONSTRUCT_ONLY));
    + properties[PROP_CATEGORY] = g_param_spec_string(
    + "category", "category",
    + "The category of the plugin",
    + NULL,
    + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
    + );
    /**
    * GPluginPluginInfo:authors:
    @@ -697,75 +699,55 @@
    * "First Last <user@domain.com>" with additional authors separated by a
    * comma.
    */
    - g_object_class_install_property(obj_class, PROP_AUTHORS,
    - g_param_spec_boxed("authors", "authors",
    - "The authors of the plugin",
    - G_TYPE_STRV,
    - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
    - G_PARAM_CONSTRUCT_ONLY));
    + properties[PROP_AUTHORS] = g_param_spec_boxed(
    + "authors", "authors",
    + "The authors of the plugin",
    + G_TYPE_STRV,
    + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
    + );
    /**
    * GPluginPluginInfo:help:
    *
    * The url of the plugin that can be represented in a user interface.
    */
    - g_object_class_install_property(obj_class, PROP_HELP,
    - g_param_spec_string("help", "help",
    - "The help string for the plugin",
    - NULL,
    - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
    - G_PARAM_CONSTRUCT_ONLY));
    + properties[PROP_HELP] = g_param_spec_string(
    + "help", "help",
    + "The help string for the plugin",
    + NULL,
    + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
    + );
    /**
    * GPluginPluginInfo:website:
    *
    * The url of the plugin that can be represented in a user interface.
    */
    - g_object_class_install_property(obj_class, PROP_WEBSITE,
    - g_param_spec_string("website", "website",
    - "The website of the plugin",
    - NULL,
    - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
    - G_PARAM_CONSTRUCT_ONLY));
    + properties[PROP_WEBSITE] = g_param_spec_string(
    + "website", "website",
    + "The website of the plugin",
    + NULL,
    + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
    + );
    /**
    * GPluginPluginInfo:dependencies:
    *
    * A comma separated list of plugin id's that this plugin depends on.
    */
    - g_object_class_install_property(obj_class, PROP_DEPENDENCIES,
    - g_param_spec_boxed("dependencies", "dependencies",
    - "The dependencies of the plugin",
    - G_TYPE_STRV,
    - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
    - G_PARAM_CONSTRUCT_ONLY));
    + properties[PROP_DEPENDENCIES] = g_param_spec_boxed(
    + "dependencies", "dependencies",
    + "The dependencies of the plugin",
    + G_TYPE_STRV,
    + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY
    + );
    +
    + g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
    }
    /******************************************************************************
    * GPluginPlugin API
    *****************************************************************************/
    -GType
    -gplugin_plugin_info_get_type(void) {
    - static volatile gsize type_volatile = 0;
    -
    - if(g_once_init_enter(&type_volatile)) {
    - GType type = 0;
    -
    - static const GTypeInfo info = {
    - .class_size = sizeof(GPluginPluginInfoClass),
    - .class_init = (GClassInitFunc)gplugin_plugin_info_class_init,
    - .instance_size = sizeof(GPluginPluginInfo),
    - };
    -
    - type = g_type_register_static(G_TYPE_OBJECT,
    - "GPluginPluginInfo",
    - &info, 0);
    -
    - g_once_init_leave(&type_volatile, type);
    - }
    -
    - return type_volatile;
    -}
    /**
    * gplugin_plugin_info_new: (skip)
    @@ -782,15 +764,17 @@
    * gplugin_plugin_info_get_id:
    * @info: #GPluginPluginInfo instance
    *
    - * Return value: The id from @info.
    + * Returns the id that the plugin identifies itself as.
    + *
    + * Returns: The id from @info.
    */
    const gchar *
    -gplugin_plugin_info_get_id(const GPluginPluginInfo *info) {
    +gplugin_plugin_info_get_id(GPluginPluginInfo *info) {
    GPluginPluginInfoPrivate *priv = NULL;
    g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
    - priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + priv = gplugin_plugin_info_get_instance_private(info);
    return priv->id;
    }
    @@ -799,15 +783,18 @@
    * gplugin_plugin_info_get_abi_version:
    * @info: #GPluginPluginInfo instance
    *
    - * Return value: The abi_version from @info.
    + * Returns the ABI or Application Binary Interface version that the plugin
    + * is supposed to work against.
    + *
    + * Returns: The abi_version from @info.
    */
    guint32
    -gplugin_plugin_info_get_abi_version(const GPluginPluginInfo *info) {
    +gplugin_plugin_info_get_abi_version(GPluginPluginInfo *info) {
    GPluginPluginInfoPrivate *priv = NULL;
    g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), 0);
    - priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + priv = gplugin_plugin_info_get_instance_private(info);
    return priv->abi_version;
    }
    @@ -816,15 +803,19 @@
    * gplugin_plugin_info_get_internal:
    * @info: #GPluginPluginInfo instance
    *
    - * Return value: Whether or not this plugin is considered an internal plugin
    + * Returns where or not this plugin is is considered an internal plugin. An
    + * internal plugin would be something like a plugin loader or another plugin
    + * that should not be shown to users.
    + *
    + * Returns: TRUE if the plugin is internal, FALSE otherwise.
    */
    gboolean
    -gplugin_plugin_info_get_internal(const GPluginPluginInfo *info) {
    +gplugin_plugin_info_get_internal(GPluginPluginInfo *info) {
    GPluginPluginInfoPrivate *priv = NULL;
    g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), FALSE);
    - priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + priv = gplugin_plugin_info_get_instance_private(info);
    return priv->internal;
    }
    @@ -833,15 +824,20 @@
    * gplugin_plugin_info_get_load_on_query:
    * @info: #GPluginPluginInfo instance
    *
    - * Return value: Whether or not this plugin should be loaded when queried
    + * Returns whether or not this plugin should be loaded when queried. This is
    + * useful for internal plugins that are adding functionality and should always
    + * be turned on. The plugin loaders use this to make sure all plugins can
    + * always be loaded.
    + *
    + * Returns: TRUE if the plugin should be loaded on query, FALSE otherwise.
    */
    gboolean
    -gplugin_plugin_info_get_load_on_query(const GPluginPluginInfo *info) {
    +gplugin_plugin_info_get_load_on_query(GPluginPluginInfo *info) {
    GPluginPluginInfoPrivate *priv = NULL;
    g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), FALSE);
    - priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + priv = gplugin_plugin_info_get_instance_private(info);
    return priv->load_on_query;
    }
    @@ -850,15 +846,17 @@
    * gplugin_plugin_info_get_name:
    * @info: #GPluginPluginInfo instance
    *
    - * Return value: The name from @info.
    + * Returns the name of the plugin as specified in @info.
    + *
    + * Returns: The name from @info.
    */
    const gchar *
    -gplugin_plugin_info_get_name(const GPluginPluginInfo *info) {
    +gplugin_plugin_info_get_name(GPluginPluginInfo *info) {
    GPluginPluginInfoPrivate *priv = NULL;
    g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
    - priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + priv = gplugin_plugin_info_get_instance_private(info);
    return priv->name;
    }
    @@ -867,15 +865,17 @@
    * gplugin_plugin_info_get_version:
    * @info: #GPluginPluginInfo instance
    *
    - * Return value: The version from @info.
    + * Returns the version of the plugin as specified in @info.
    + *
    + * Returns: The version from @info.
    */
    const gchar *
    -gplugin_plugin_info_get_version(const GPluginPluginInfo *info) {
    +gplugin_plugin_info_get_version(GPluginPluginInfo *info) {
    GPluginPluginInfoPrivate *priv = NULL;
    g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
    - priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + priv = gplugin_plugin_info_get_instance_private(info);
    return priv->version;
    }
    @@ -884,16 +884,19 @@
    * gplugin_plugin_info_get_version_func: (skip)
    * @info: #GPluginPluginInfo instance
    *
    + * Returns the #GPluginVersionCompareFunc used to compare versions of the
    + * plugin.
    + *
    * Returns: The #GPluginVersionCompareFunc that can compare versions of this
    * plugins.
    */
    GPluginVersionCompareFunc
    -gplugin_plugin_info_get_version_func(const GPluginPluginInfo *info) {
    +gplugin_plugin_info_get_version_func(GPluginPluginInfo *info) {
    GPluginPluginInfoPrivate *priv = NULL;
    g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
    - priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + priv = gplugin_plugin_info_get_instance_private(info);
    return priv->version_func;
    }
    @@ -902,15 +905,17 @@
    * gplugin_plugin_info_get_license_id:
    * @info: #GPluginPluginInfo instance
    *
    - * Return value: The license-id from @info.
    + * Returns the liences id for the plugin as specified in @info.
    + *
    + * Returns: The license-id from @info.
    */
    const gchar *
    -gplugin_plugin_info_get_license_id(const GPluginPluginInfo *info) {
    +gplugin_plugin_info_get_license_id(GPluginPluginInfo *info) {
    GPluginPluginInfoPrivate *priv = NULL;
    g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
    - priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + priv = gplugin_plugin_info_get_instance_private(info);
    return priv->license_id;
    }
    @@ -919,15 +924,17 @@
    * gplugin_plugin_info_get_license_text:
    * @info: #GPluginPluginInfo instance
    *
    - * Return value: The text of the license from @info.
    + * Returns the license text for the plugin as specified in @info.
    + *
    + * Returns: The text of the license from @info.
    */
    const gchar *
    -gplugin_plugin_info_get_license_text(const GPluginPluginInfo *info) {
    +gplugin_plugin_info_get_license_text(GPluginPluginInfo *info) {
    GPluginPluginInfoPrivate *priv = NULL;
    g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
    - priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + priv = gplugin_plugin_info_get_instance_private(info);
    return priv->license_text;
    }
    @@ -936,15 +943,17 @@
    * gplugin_plugin_info_get_license_url:
    * @info: #GPluginPluginInfo instance
    *
    - * Return value: The url of the license from @info.
    + * Returns the url of the license for the plugin as specified in @info
    + *
    + * Returns: The url of the license from @info.
    */
    const gchar *
    -gplugin_plugin_info_get_license_url(const GPluginPluginInfo *info) {
    +gplugin_plugin_info_get_license_url(GPluginPluginInfo *info) {
    GPluginPluginInfoPrivate *priv = NULL;
    g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
    - priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + priv = gplugin_plugin_info_get_instance_private(info);
    return priv->license_url;
    }
    @@ -953,15 +962,17 @@
    * gplugin_plugin_info_get_icon:
    * @info: #GPluginPluginInfo instance
    *
    - * Return value: The icon from @info.
    + * Returns the name of the icon for the plugin as specified in @info.
    + *
    + * Returns: The icon from @info.
    */
    const gchar *
    -gplugin_plugin_info_get_icon(const GPluginPluginInfo *info) {
    +gplugin_plugin_info_get_icon(GPluginPluginInfo *info) {
    GPluginPluginInfoPrivate *priv = NULL;
    g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
    - priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + priv = gplugin_plugin_info_get_instance_private(info);
    return priv->icon;
    }
    @@ -970,15 +981,17 @@
    * gplugin_plugin_info_get_summary:
    * @info: #GPluginPluginInfo instance
    *
    - * Return value: The summary from @info.
    + * Returns the summery for the plugin as specified in @info.
    + *
    + * Returns: The summary from @info.
    */
    const gchar *
    -gplugin_plugin_info_get_summary(const GPluginPluginInfo *info) {
    +gplugin_plugin_info_get_summary(GPluginPluginInfo *info) {
    GPluginPluginInfoPrivate *priv = NULL;
    g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
    - priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + priv = gplugin_plugin_info_get_instance_private(info);
    return priv->summary;
    }
    @@ -987,15 +1000,17 @@
    * gplugin_plugin_info_get_description:
    * @info: #GPluginPluginInfo instance
    *
    - * Return value: The description from @info.
    + * Returns the description for the plugin as specified in @info.
    + *
    + * Returns: The description from @info.
    */
    const gchar *
    -gplugin_plugin_info_get_description(const GPluginPluginInfo *info) {
    +gplugin_plugin_info_get_description(GPluginPluginInfo *info) {
    GPluginPluginInfoPrivate *priv = NULL;
    g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
    - priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + priv = gplugin_plugin_info_get_instance_private(info);
    return priv->description;
    }
    @@ -1004,15 +1019,17 @@
    * gplugin_plugin_info_get_category:
    * @info: #GPluginPluginInfo instance
    *
    - * Return value: The category from @info.
    + * Returns the category of the plugin as specified in @info.
    + *
    + * Returns: The category from @info.
    */
    const gchar *
    -gplugin_plugin_info_get_category(const GPluginPluginInfo *info) {
    +gplugin_plugin_info_get_category(GPluginPluginInfo *info) {
    GPluginPluginInfoPrivate *priv = NULL;
    g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
    - priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + priv = gplugin_plugin_info_get_instance_private(info);
    return priv->category;
    }
    @@ -1021,16 +1038,17 @@
    * gplugin_plugin_info_get_authors:
    * @info: #GPluginPluginInfo instance
    *
    - * Return value: (array zero-terminated=1) (transfer none): The authors from
    - * @info.
    + * Returns the authors of the plugin as specified in @info.
    + *
    + * Returns: (array zero-terminated=1) (transfer none): The authors from @info.
    */
    const gchar * const *
    -gplugin_plugin_info_get_authors(const GPluginPluginInfo *info) {
    +gplugin_plugin_info_get_authors(GPluginPluginInfo *info) {
    GPluginPluginInfoPrivate *priv = NULL;
    g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
    - priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + priv = gplugin_plugin_info_get_instance_private(info);
    return (const gchar * const *)priv->authors;
    }
    @@ -1039,15 +1057,17 @@
    * gplugin_plugin_info_get_help:
    * @info: #GPluginPluginInfo instance
    *
    - * Return value: The help from @info.
    + * Returns the help text for the plugin as specified in @info.
    + *
    + * Returns: The help from @info.
    */
    const gchar *
    -gplugin_plugin_info_get_help(const GPluginPluginInfo *info) {
    +gplugin_plugin_info_get_help(GPluginPluginInfo *info) {
    GPluginPluginInfoPrivate *priv = NULL;
    g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
    - priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + priv = gplugin_plugin_info_get_instance_private(info);
    return priv->help;
    }
    @@ -1056,15 +1076,17 @@
    * gplugin_plugin_info_get_website:
    * @info: #GPluginPluginInfo instance
    *
    - * Return value: The website from @info.
    + * Returns the website for the plugin as specified in @info.
    + *
    + * Returns: The website from @info.
    */
    const gchar *
    -gplugin_plugin_info_get_website(const GPluginPluginInfo *info) {
    +gplugin_plugin_info_get_website(GPluginPluginInfo *info) {
    GPluginPluginInfoPrivate *priv = NULL;
    g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
    - priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + priv = gplugin_plugin_info_get_instance_private(info);
    return priv->website;
    }
    @@ -1073,16 +1095,18 @@
    * gplugin_plugin_info_get_dependencies:
    * @info: #GPluginPluginInfo instance
    *
    - * Return value: (array zero-terminated=1) (transfer none): The list of
    - * dependencies from @info.
    + * Returns the dependencies of the plugins as specified in @info.
    + *
    + * Returns: (array zero-terminated=1) (transfer none): The list of
    + * dependencies from @info.
    */
    const gchar * const *
    -gplugin_plugin_info_get_dependencies(const GPluginPluginInfo *info) {
    +gplugin_plugin_info_get_dependencies(GPluginPluginInfo *info) {
    GPluginPluginInfoPrivate *priv = NULL;
    g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), NULL);
    - priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + priv = gplugin_plugin_info_get_instance_private(info);
    return (const gchar * const *)priv->dependencies;
    }
    @@ -1093,17 +1117,16 @@
    *
    * This function is only used by the native plugin loader.
    *
    - * Return value: TRUE if the plugin has requested to be loaded with it's
    - * symbols bound locally, FALSE if they should bind be bound
    - * globally.
    + * Returns: TRUE if the plugin has requested to be loaded with it's symbols
    + * bound locally, FALSE if they should bind be bound globally.
    */
    gboolean
    -gplugin_plugin_info_get_bind_local(const GPluginPluginInfo *info) {
    +gplugin_plugin_info_get_bind_local(GPluginPluginInfo *info) {
    GPluginPluginInfoPrivate *priv = NULL;
    g_return_val_if_fail(GPLUGIN_IS_PLUGIN_INFO(info), FALSE);
    - priv = GPLUGIN_PLUGIN_INFO_GET_PRIVATE(info);
    + priv = gplugin_plugin_info_get_instance_private(info);
    return priv->bind_local;
    }
    --- a/gplugin/gplugin-plugin-info.h Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/gplugin-plugin-info.h Tue Jan 22 22:50:20 2019 -0600
    @@ -15,11 +15,9 @@
    * License along with this library; if not, see <http://www.gnu.org/licenses/>.
    */
    -#ifndef __GI_SCANNER__ /* hide this bit from g-ir-scanner */
    #if !defined(GPLUGIN_GLOBAL_HEADER_INSIDE) && !defined(GPLUGIN_COMPILATION)
    #error "only <gplugin.h> may be included directly"
    #endif
    -#endif /* __GI_SCANNER__ */
    #ifndef GPLUGIN_PLUGIN_INFO_H
    #define GPLUGIN_PLUGIN_INFO_H
    @@ -65,24 +63,24 @@
    __VA_ARGS__) \
    )
    -const gchar *gplugin_plugin_info_get_id(const GPluginPluginInfo *info);
    -guint32 gplugin_plugin_info_get_abi_version(const GPluginPluginInfo *info);
    -gboolean gplugin_plugin_info_get_internal(const GPluginPluginInfo *info);
    -gboolean gplugin_plugin_info_get_load_on_query(const GPluginPluginInfo *info);
    -const gchar *gplugin_plugin_info_get_name(const GPluginPluginInfo *info);
    -const gchar *gplugin_plugin_info_get_version(const GPluginPluginInfo *info);
    -const gchar *gplugin_plugin_info_get_license_id(const GPluginPluginInfo *info);
    -const gchar *gplugin_plugin_info_get_license_text(const GPluginPluginInfo *info);
    -const gchar *gplugin_plugin_info_get_license_url(const GPluginPluginInfo *info);
    -const gchar *gplugin_plugin_info_get_icon(const GPluginPluginInfo *info);
    -const gchar *gplugin_plugin_info_get_summary(const GPluginPluginInfo *info);
    -const gchar *gplugin_plugin_info_get_description(const GPluginPluginInfo *info);
    -const gchar *gplugin_plugin_info_get_category(const GPluginPluginInfo *info);
    -const gchar * const *gplugin_plugin_info_get_authors(const GPluginPluginInfo *info);
    -const gchar *gplugin_plugin_info_get_website(const GPluginPluginInfo *info);
    -const gchar * const *gplugin_plugin_info_get_dependencies(const GPluginPluginInfo *info);
    -GPluginVersionCompareFunc gplugin_plugin_info_get_version_func(const GPluginPluginInfo *info);
    -const gchar *gplugin_plugin_info_get_help(const GPluginPluginInfo *info);
    +const gchar *gplugin_plugin_info_get_id(GPluginPluginInfo *info);
    +guint32 gplugin_plugin_info_get_abi_version(GPluginPluginInfo *info);
    +gboolean gplugin_plugin_info_get_internal(GPluginPluginInfo *info);
    +gboolean gplugin_plugin_info_get_load_on_query(GPluginPluginInfo *info);
    +const gchar *gplugin_plugin_info_get_name(GPluginPluginInfo *info);
    +const gchar *gplugin_plugin_info_get_version(GPluginPluginInfo *info);
    +const gchar *gplugin_plugin_info_get_license_id(GPluginPluginInfo *info);
    +const gchar *gplugin_plugin_info_get_license_text(GPluginPluginInfo *info);
    +const gchar *gplugin_plugin_info_get_license_url(GPluginPluginInfo *info);
    +const gchar *gplugin_plugin_info_get_icon(GPluginPluginInfo *info);
    +const gchar *gplugin_plugin_info_get_summary(GPluginPluginInfo *info);
    +const gchar *gplugin_plugin_info_get_description(GPluginPluginInfo *info);
    +const gchar *gplugin_plugin_info_get_category(GPluginPluginInfo *info);
    +const gchar * const *gplugin_plugin_info_get_authors(GPluginPluginInfo *info);
    +const gchar *gplugin_plugin_info_get_website(GPluginPluginInfo *info);
    +const gchar * const *gplugin_plugin_info_get_dependencies(GPluginPluginInfo *info);
    +GPluginVersionCompareFunc gplugin_plugin_info_get_version_func(GPluginPluginInfo *info);
    +const gchar *gplugin_plugin_info_get_help(GPluginPluginInfo *info);
    G_END_DECLS
    --- a/gplugin/gplugin-plugin.c Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/gplugin-plugin.c Tue Jan 22 22:50:20 2019 -0600
    @@ -21,8 +21,15 @@
    #include <gplugin/gplugin-marshallers.h>
    #include <gplugin/gplugin-private.h>
    -#define GPLUGIN_PLUGIN_GET_PRIVATE(obj) \
    - (G_TYPE_INSTANCE_GET_PRIVATE((obj), GPLUGIN_TYPE_PLUGIN, GPluginPluginPrivate))
    +/**
    + * SECTION:gplugin-plugin
    + * @Title: Plugin Objects
    + * @Short_description: abstract plugin implementation
    + *
    + * #GPluginPlugin is an abstract class that tracks the state of a plugin. It
    + * is subclassed by each loader for them to add additional data for their
    + * implementation.
    + */
    /**
    * GPluginPluginState:
    @@ -38,206 +45,75 @@
    */
    /******************************************************************************
    - * Structs
    - *****************************************************************************/
    -typedef struct {
    - gchar *filename;
    -
    - GPluginLoader *loader;
    - GPluginPluginInfo *info;
    -
    - GPluginPluginState state;
    -} GPluginPluginPrivate;
    -
    -/******************************************************************************
    * Enums
    *****************************************************************************/
    enum {
    - PROP_ZERO,
    - PROP_FILENAME,
    - PROP_LOADER,
    - PROP_INFO,
    - PROP_STATE,
    - PROP_LAST,
    -};
    -
    -enum {
    SIG_STATE_CHANGED,
    SIG_LAST,
    };
    -
    -/******************************************************************************
    - * Globals
    - *****************************************************************************/
    -static GObjectClass *parent_class = NULL;
    static guint signals[SIG_LAST] = {0, };
    -/******************************************************************************
    - * Private API
    - *****************************************************************************/
    -static void
    -gplugin_plugin_set_filename(GPluginPlugin *plugin, const gchar *filename) {
    - GPluginPluginPrivate *priv = GPLUGIN_PLUGIN_GET_PRIVATE(plugin);
    -
    - g_free(priv->filename);
    -
    - priv->filename = (filename) ? g_strdup(filename) : NULL;
    -
    - g_object_notify(G_OBJECT(plugin), "filename");
    -}
    -
    -static void
    -gplugin_plugin_set_loader(GPluginPlugin *plugin, GPluginLoader *loader) {
    - GPluginPluginPrivate *priv = GPLUGIN_PLUGIN_GET_PRIVATE(plugin);
    -
    - if(priv->loader)
    - g_object_unref(G_OBJECT(priv->loader));
    -
    - if(GPLUGIN_IS_LOADER(loader))
    - priv->loader = g_object_ref(G_OBJECT(loader));
    - else
    - priv->loader = NULL;
    -}
    -
    -static void
    -gplugin_plugin_set_info(GPluginPlugin *plugin, GPluginPluginInfo *info) {
    - GPluginPluginPrivate *priv = GPLUGIN_PLUGIN_GET_PRIVATE(plugin);
    -
    - if(priv->info)
    - g_object_unref(G_OBJECT(priv->info));
    -
    - priv->info = (info) ? g_object_ref(G_OBJECT(info)) : NULL;
    -}
    -
    -gchar *
    -gplugin_plugin_get_internal_filename(GPluginPlugin *plugin) {
    - GPluginPluginPrivate *priv = GPLUGIN_PLUGIN_GET_PRIVATE(plugin);
    -
    - return priv->filename;
    -}
    +G_DEFINE_INTERFACE(GPluginPlugin, gplugin_plugin, G_TYPE_INVALID);
    /******************************************************************************
    * Object Stuff
    *****************************************************************************/
    static void
    -gplugin_plugin_get_property(GObject *obj, guint param_id, GValue *value,
    - GParamSpec *pspec)
    -{
    - GPluginPlugin *plugin = GPLUGIN_PLUGIN(obj);
    -
    - switch(param_id) {
    - case PROP_FILENAME:
    - g_value_set_string(value, gplugin_plugin_get_filename(plugin));
    - break;
    - case PROP_LOADER:
    - g_value_take_object(value, gplugin_plugin_get_loader(plugin));
    - break;
    - case PROP_INFO:
    - g_value_take_object(value, gplugin_plugin_get_info(plugin));
    - break;
    - case PROP_STATE:
    - g_value_set_enum(value, gplugin_plugin_get_state(plugin));
    - break;
    - default:
    - G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
    - break;
    - }
    -}
    -
    -static void
    -gplugin_plugin_set_property(GObject *obj, guint param_id, const GValue *value,
    - GParamSpec *pspec)
    -{
    - GPluginPlugin *plugin = GPLUGIN_PLUGIN(obj);
    -
    - switch(param_id) {
    - case PROP_FILENAME:
    - gplugin_plugin_set_filename(plugin, g_value_get_string(value));
    - break;
    - case PROP_LOADER:
    - gplugin_plugin_set_loader(plugin, g_value_get_object(value));
    - break;
    - case PROP_INFO:
    - gplugin_plugin_set_info(plugin, g_value_get_object(value));
    - break;
    - case PROP_STATE:
    - gplugin_plugin_set_state(plugin, g_value_get_enum(value));
    - break;
    - default:
    - G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
    - break;
    - }
    -}
    -
    -static void
    -gplugin_plugin_finalize(GObject *obj) {
    - GPluginPluginPrivate *priv = GPLUGIN_PLUGIN_GET_PRIVATE(obj);
    -
    - g_free(priv->filename);
    - g_object_unref(priv->loader);
    -
    - if(priv->info)
    - g_object_unref(G_OBJECT(priv->info));
    -
    - G_OBJECT_CLASS(parent_class)->finalize(obj);
    -}
    -
    -static void
    -gplugin_plugin_class_init(GPluginPluginClass *klass) {
    - GObjectClass *obj_class = G_OBJECT_CLASS(klass);
    -
    - parent_class = g_type_class_peek_parent(klass);
    -
    - g_type_class_add_private(klass, sizeof(GPluginPluginPrivate));
    -
    - obj_class->get_property = gplugin_plugin_get_property;
    - obj_class->set_property = gplugin_plugin_set_property;
    - obj_class->finalize = gplugin_plugin_finalize;
    +gplugin_plugin_default_init(GPluginPluginInterface *iface) {
    + GParamSpec *pspec = NULL;
    /**
    * GPluginPlugin:filename:
    *
    * The absolute path to the plugin on disk.
    */
    - g_object_class_install_property(obj_class, PROP_FILENAME,
    - g_param_spec_string("filename", "filename",
    - "The filename of the plugin",
    - NULL,
    - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
    + pspec = g_param_spec_string(
    + "filename", "filename",
    + "The filename of the plugin",
    + NULL,
    + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
    + );
    + g_object_interface_install_property(iface, pspec);
    /**
    * GPluginPlugin:loader:
    *
    * The #GPluginLoader that loaded this plugin.
    */
    - g_object_class_install_property(obj_class, PROP_LOADER,
    - g_param_spec_object("loader", "loader",
    - "The loader for this plugin",
    - GPLUGIN_TYPE_LOADER,
    - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
    + pspec = g_param_spec_object(
    + "loader", "loader",
    + "The loader for this plugin",
    + GPLUGIN_TYPE_LOADER,
    + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
    + );
    + g_object_interface_install_property(iface, pspec);
    /**
    * GPluginPlugin:info:
    *
    * The #GPluginPluginInfo from this plugin.
    */
    - g_object_class_install_property(obj_class, PROP_INFO,
    - g_param_spec_object("info", "info",
    - "The information for the plugin",
    - GPLUGIN_TYPE_PLUGIN_INFO,
    - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
    + pspec = g_param_spec_object(
    + "info", "info",
    + "The information for the plugin",
    + GPLUGIN_TYPE_PLUGIN_INFO,
    + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
    + );
    + g_object_interface_install_property(iface, pspec);
    /**
    * GPluginPlugin:state:
    *
    * The #GPluginPluginState that this plugin is in.
    */
    - g_object_class_install_property(obj_class, PROP_STATE,
    - g_param_spec_enum("state", "state",
    - "The state of the plugin",
    - GPLUGIN_TYPE_PLUGIN_STATE,
    - GPLUGIN_PLUGIN_STATE_UNKNOWN,
    - G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
    + pspec = g_param_spec_enum(
    + "state", "state",
    + "The state of the plugin",
    + GPLUGIN_TYPE_PLUGIN_STATE,
    + GPLUGIN_PLUGIN_STATE_UNKNOWN,
    + G_PARAM_READWRITE | G_PARAM_CONSTRUCT
    + );
    + g_object_interface_install_property(iface, pspec);
    /**
    * GPluginPlugin::state-changed:
    @@ -249,9 +125,9 @@
    */
    signals[SIG_STATE_CHANGED] =
    g_signal_new("state-changed",
    - G_OBJECT_CLASS_TYPE(klass),
    + GPLUGIN_TYPE_PLUGIN,
    G_SIGNAL_RUN_LAST,
    - G_STRUCT_OFFSET(GPluginPluginClass, state_changed),
    + G_STRUCT_OFFSET(GPluginPluginInterface, state_changed),
    NULL, NULL,
    gplugin_marshal_VOID__ENUM_ENUM,
    G_TYPE_NONE,
    @@ -262,78 +138,62 @@
    /******************************************************************************
    * GPluginPlugin API
    *****************************************************************************/
    -GType
    -gplugin_plugin_get_type(void) {
    - static volatile gsize type_volatile = 0;
    -
    - if(g_once_init_enter(&type_volatile)) {
    - GType type = 0;
    -
    - static const GTypeInfo info = {
    - .class_size = sizeof(GPluginPluginClass),
    - .class_init = (GClassInitFunc)gplugin_plugin_class_init,
    - .instance_size = sizeof(GPluginPlugin),
    - };
    -
    - type = g_type_register_static(G_TYPE_OBJECT,
    - "GPluginPlugin",
    - &info, G_TYPE_FLAG_ABSTRACT);
    -
    - g_once_init_leave(&type_volatile, type);
    - }
    -
    - return type_volatile;
    -}
    /**
    * gplugin_plugin_get_filename:
    * @plugin: #GPluginPlugin instance
    *
    - * Return value: The filename of @plugin
    + * Returns the filename that @plugin was loaded from.
    + *
    + * Returns: (transfer full): The filename of @plugin
    */
    -const gchar *
    -gplugin_plugin_get_filename(const GPluginPlugin *plugin) {
    - GPluginPluginPrivate *priv = NULL;
    +gchar *
    +gplugin_plugin_get_filename(GPluginPlugin *plugin) {
    + gchar *filename = NULL;
    g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), NULL);
    - priv = GPLUGIN_PLUGIN_GET_PRIVATE(plugin);
    + g_object_get(G_OBJECT(plugin), "filename", &filename, NULL);
    - return priv->filename;
    + return filename;
    }
    /**
    * gplugin_plugin_get_loader:
    * @plugin: #GPluginPlugin instance
    *
    - * Return Value: (transfer full): The #GPluginLoader that loaded @plugin
    + * Returns the #GPluginLoader that loaded @plugin.
    + *
    + * Returns: (transfer full): The #GPluginLoader that loaded @plugin
    */
    GPluginLoader *
    -gplugin_plugin_get_loader(const GPluginPlugin *plugin) {
    - GPluginPluginPrivate *priv = NULL;
    +gplugin_plugin_get_loader(GPluginPlugin *plugin) {
    + GPluginLoader *loader = NULL;
    g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), NULL);
    - priv = GPLUGIN_PLUGIN_GET_PRIVATE(plugin);
    + g_object_get(G_OBJECT(plugin), "loader", &loader, NULL);
    - return (priv->info) ? g_object_ref(G_OBJECT(priv->loader)) : NULL;
    + return loader;
    }
    /**
    * gplugin_plugin_get_info:
    * @plugin: #GPluginPlugin instance
    *
    - * Return value: (transfer full): The #GPluginPluginInfo instance for @plugin
    + * Returns the #GPluginPluginInfo for @plugin.
    + *
    + * Returns: (transfer full): The #GPluginPluginInfo instance for @plugin
    */
    GPluginPluginInfo *
    -gplugin_plugin_get_info(const GPluginPlugin *plugin) {
    - GPluginPluginPrivate *priv = NULL;
    +gplugin_plugin_get_info(GPluginPlugin *plugin) {
    + GPluginPluginInfo *info = NULL;
    g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), NULL);
    - priv = GPLUGIN_PLUGIN_GET_PRIVATE(plugin);
    + g_object_get(G_OBJECT(plugin), "info", &info, NULL);
    - return (priv->info) ? g_object_ref(G_OBJECT(priv->info)) : NULL;
    + return info;
    }
    /**
    @@ -342,17 +202,17 @@
    *
    * Gets the current state of @plugin
    *
    - * Return value: (transfer full): The current state of @plugin
    + * Returns: (transfer full): The current state of @plugin
    */
    GPluginPluginState
    -gplugin_plugin_get_state(const GPluginPlugin *plugin) {
    - GPluginPluginPrivate *priv = NULL;
    +gplugin_plugin_get_state(GPluginPlugin *plugin) {
    + GPluginPluginState state = GPLUGIN_PLUGIN_STATE_UNKNOWN;
    g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), GPLUGIN_PLUGIN_STATE_UNKNOWN);
    - priv = GPLUGIN_PLUGIN_GET_PRIVATE(plugin);
    + g_object_get(G_OBJECT(plugin), "state", &state, NULL);
    - return priv->state;
    + return state;
    }
    /**
    @@ -365,17 +225,14 @@
    */
    void
    gplugin_plugin_set_state(GPluginPlugin *plugin, GPluginPluginState state) {
    - GPluginPluginPrivate *priv = NULL;
    GPluginPluginState oldstate = GPLUGIN_PLUGIN_STATE_UNKNOWN;
    g_return_if_fail(GPLUGIN_IS_PLUGIN(plugin));
    - priv = GPLUGIN_PLUGIN_GET_PRIVATE(plugin);
    + oldstate = gplugin_plugin_get_state(plugin);
    - oldstate = priv->state;
    - priv->state = state;
    + g_object_set(G_OBJECT(plugin), "state", state, NULL);
    g_signal_emit(plugin, signals[SIG_STATE_CHANGED], 0,
    - oldstate, priv->state);
    + oldstate, state);
    }
    -
    --- a/gplugin/gplugin-plugin.h Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/gplugin-plugin.h Tue Jan 22 22:50:20 2019 -0600
    @@ -15,24 +15,20 @@
    * License along with this library; if not, see <http://www.gnu.org/licenses/>.
    */
    -#ifndef __GI_SCANNER__ /* hide this bit from g-ir-scanner */
    #if !defined(GPLUGIN_GLOBAL_HEADER_INSIDE) && !defined(GPLUGIN_COMPILATION)
    #error "only <gplugin.h> may be included directly"
    #endif
    -#endif /* __GI_SCANNER__ */
    #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_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GPLUGIN_TYPE_PLUGIN, GPluginPluginClass))
    #define GPLUGIN_IS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GPLUGIN_TYPE_PLUGIN))
    -#define GPLUGIN_IS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GPLUGIN_TYPE_PLUGIN))
    -#define GPLUGIN_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GPLUGIN_TYPE_PLUGIN, GPluginPluginClass))
    +#define GPLUGIN_PLUGIN_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE((obj), GPLUGIN_TYPE_PLUGIN, GPluginPluginInterface))
    typedef struct _GPluginPlugin GPluginPlugin;
    -typedef struct _GPluginPluginClass GPluginPluginClass;
    +typedef struct _GPluginPluginInterface GPluginPluginInterface;
    typedef enum /*< prefix=GPLUGIN_PLUGIN_STATE,underscore_name=GPLUGIN_PLUGIN_STATE >*/ {
    GPLUGIN_PLUGIN_STATE_UNKNOWN = -1,
    @@ -41,6 +37,8 @@
    GPLUGIN_PLUGIN_STATE_REQUERY,
    GPLUGIN_PLUGIN_STATE_LOADED,
    GPLUGIN_PLUGIN_STATE_LOAD_FAILED,
    +
    + /*< private >*/
    GPLUGIN_PLUGIN_STATES, /*< skip >*/
    } GPluginPluginState;
    @@ -50,30 +48,25 @@
    #include <gplugin/gplugin-plugin-info.h>
    #include <gplugin/gplugin-loader.h>
    -struct _GPluginPlugin {
    - GObject gparent;
    -};
    -
    -struct _GPluginPluginClass {
    - GObjectClass gparent;
    +struct _GPluginPluginInterface {
    + /*< private >*/
    + GTypeInterface parent;
    void (*state_changed)(GPluginPlugin *plugin, GPluginPluginState oldstate, GPluginPluginState newstate);
    - void (*_gplugin_reserved_1)(void);
    - void (*_gplugin_reserved_2)(void);
    - void (*_gplugin_reserved_3)(void);
    - void (*_gplugin_reserved_4)(void);
    + /*< private >*/
    + gpointer reserved[8];
    };
    G_BEGIN_DECLS
    GType gplugin_plugin_get_type(void);
    -const gchar *gplugin_plugin_get_filename(const GPluginPlugin *plugin);
    -GPluginLoader *gplugin_plugin_get_loader(const GPluginPlugin *plugin);
    -GPluginPluginInfo *gplugin_plugin_get_info(const GPluginPlugin *plugin);
    +gchar *gplugin_plugin_get_filename(GPluginPlugin *plugin);
    +GPluginLoader *gplugin_plugin_get_loader(GPluginPlugin *plugin);
    +GPluginPluginInfo *gplugin_plugin_get_info(GPluginPlugin *plugin);
    -GPluginPluginState gplugin_plugin_get_state(const GPluginPlugin *plugin);
    +GPluginPluginState gplugin_plugin_get_state(GPluginPlugin *plugin);
    void gplugin_plugin_set_state(GPluginPlugin *plugin, GPluginPluginState state);
    G_END_DECLS
    --- a/gplugin/gplugin-private.h Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/gplugin-private.h Tue Jan 22 22:50:20 2019 -0600
    @@ -15,11 +15,9 @@
    * License along with this library; if not, see <http://www.gnu.org/licenses/>.
    */
    -#ifndef __GI_SCANNER__ /* hide this bit from g-ir-scanner */
    #if !defined(GPLUGIN_GLOBAL_HEADER_INSIDE) && !defined(GPLUGIN_COMPILATION)
    #error "only <gplugin.h> may be included directly"
    #endif
    -#endif /* __GI_SCANNER__ */
    #ifndef GPLUGIN_PRIVATE_H
    #define GPLUGIN_PRIVATE_H
    @@ -32,14 +30,12 @@
    G_BEGIN_DECLS
    -gchar *gplugin_plugin_get_internal_filename(GPluginPlugin *plugin);
    -
    void gplugin_manager_private_init(void);
    void gplugin_manager_private_uninit(void);
    gboolean gplugin_boolean_accumulator(GSignalInvocationHint *hint, GValue *return_accu, const GValue *handler_return, gpointer data);
    -gboolean gplugin_plugin_info_get_bind_local(const GPluginPluginInfo *info);
    +gboolean gplugin_plugin_info_get_bind_local(GPluginPluginInfo *info);
    G_END_DECLS
    --- a/gplugin/gplugin-query.c Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/gplugin-query.c Tue Jan 22 22:50:20 2019 -0600
    @@ -111,7 +111,7 @@
    for(l = plugins; l; l = l->next) {
    GPluginPlugin *plugin = GPLUGIN_PLUGIN(l->data);
    - const GPluginPluginInfo *info = gplugin_plugin_get_info(plugin);
    + GPluginPluginInfo *info = gplugin_plugin_get_info(plugin);
    gboolean internal, loq;
    guint32 abi_version;
    gchar *name, *version;
    --- a/gplugin/gplugin-uninstalled.pc.in Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,7 +0,0 @@
    -Name: libgplugin
    -Description: A fully featured GModule based plugin library
    -Version: @GPLUGIN_VERSION@
    -Requires: glib-2.0 gobject-2.0 gmodule-2.0
    -Libs: -L@CMAKE_BINARY_DIR@/gplugin -lgplugin
    -Cflags: -I@CMAKE_SOURCE_DIR@/gplugin -I@CMAKE_BINARY_DIR@/gplugin
    -
    --- a/gplugin/gplugin-version.c Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/gplugin-version.c Tue Jan 22 22:50:20 2019 -0600
    @@ -15,6 +15,16 @@
    * License along with this library; if not, see <http://www.gnu.org/licenses/>.
    */
    +/**
    + * SECTION:gplugin-version
    + * @Title: Version Information
    + * @Short_description: variables and functions to check the GPlugin version
    + *
    + * GPlugin provides version information, primarily useful in configure
    + * checks for builds that have a configure script. Applications will
    + * not typically use the features described here.
    + */
    +
    #include <gplugin/gplugin-core.h>
    #include <gplugin/gplugin-version.h>
    @@ -105,6 +115,50 @@
    /******************************************************************************
    * GPluginVersion API
    *****************************************************************************/
    +
    +/**
    + * GPLUGIN_MAJOR_VERSION:
    + *
    + * This is the major version number of GPlugin that was compiled against.
    + */
    +
    +/**
    + * GPLUGIN_MINOR_VERSION:
    + *
    + * This is the minor version number of GPlugin that was compiled against.
    + */
    +
    +/**
    + * GPLUGIN_MICRO_VERSION:
    + *
    + * This is the micro version number of GPlugin that was compiled against.
    + */
    +
    +/**
    + * GPLUGIN_EXTRA_VERSION:
    + *
    + * This is the extra version string of GPlugin that was compiled against.
    + */
    +
    +/**
    + * GPLUGIN_VERSION:
    + *
    + * This is the string version number of GPlugin that was compiled against.
    + */
    +
    +/**
    + * GPLUGIN_VERSION_CHECK:
    + * @major: the major version to compare for
    + * @minor: the minor version to compare for
    + * @micro: the micro version to compare for
    + *
    + * Checks the version of the GPlugin library that is being compiled
    + * against. See gplugin_version_compare() for a runtime check.
    + *
    + * Returns: %TRUE if the version of the GPlugin header files
    + * is the same as or newer than the passed-in version.
    + */
    +
    /**
    * GPluginVersionCompareFunc:
    * @v1: The first version to compare
    --- a/gplugin/gplugin-version.h.in Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/gplugin-version.h.in Tue Jan 22 22:50:20 2019 -0600
    @@ -14,11 +14,10 @@
    * 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 __GI_SCANNER__ /* hide this bit from g-ir-scanner */
    +
    #if !defined(GPLUGIN_GLOBAL_HEADER_INSIDE) && !defined(GPLUGIN_COMPILATION)
    #error "only <gplugin.h> may be included directly"
    #endif
    -#endif /* __GI_SCANNER__ */
    #ifndef GPLUGIN_VERSION_H
    #define GPLUGIN_VERSION_H
    @@ -30,10 +29,10 @@
    #define GPLUGIN_VERSION "@GPLUGIN_VERSION@"
    -#define GPLUGIN_VERSION_CHECK(x,y,z) \
    - ((x) == GPLUGIN_MAJOR_VERSION && \
    - ((y) < GPLUGIN_MINOR_VERSION || \
    - ((y) == GPLUGIN_MINOR_VERSION && (z) <= GPLUGIN_MICRO_VERSION)))
    +#define GPLUGIN_VERSION_CHECK(major,minor,micro) \
    + ((major) == GPLUGIN_MAJOR_VERSION && \
    + ((minor) < GPLUGIN_MINOR_VERSION || \
    + ((minor) == GPLUGIN_MINOR_VERSION && (micro) <= GPLUGIN_MICRO_VERSION)))
    #include <glib.h>
    --- a/gplugin/gplugin.pc.in Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,13 +0,0 @@
    -prefix=@CMAKE_INSTALL_PREFIX@
    -libdir=${prefix}/lib
    -includedir=${prefix}/include/gplugin-1.0/
    -
    -plugindir=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@
    -
    -Name: libgplugin
    -Description: A fully featured GModule based plugin library
    -Version: @GPLUGIN_VERSION@
    -Requires: glib-2.0 gobject-2.0 gmodule-2.0
    -Libs: -L${libdir} -lgplugin
    -Cflags: -I${includedir}
    -
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin/meson.build Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,283 @@
    +###############################################################################
    +# Library
    +###############################################################################
    +
    +GPLUGIN_LIBRARY_VERSION = '0.1.0'
    +
    +GPLUGIN_HEADERS = [
    + 'gplugin-core.h',
    + 'gplugin-loader.h',
    + 'gplugin-manager.h',
    + 'gplugin-options.h',
    + 'gplugin-plugin.h',
    + 'gplugin-plugin-info.h',
    +]
    +
    +GPLUGIN_SOURCES = [
    + 'gplugin-core.c',
    + 'gplugin-plugin.c',
    + 'gplugin-loader.c',
    + 'gplugin-manager.c',
    + 'gplugin-options.c',
    + 'gplugin-plugin-info.c',
    + 'gplugin-private.c',
    + 'gplugin-version.c',
    +]
    +
    +GPLUGIN_PUBLIC_BUILT_HEADERS = [
    + # Modified below.
    +]
    +
    +GPLUGIN_PUBLIC_BUILT_SOURCES = [
    + # Modified below.
    +]
    +
    +GPLUGIN_PRIVATE_HEADERS = [
    + 'gplugin-file-tree.h',
    +]
    +
    +GPLUGIN_PRIVATE_SOURCES = [
    + 'gplugin-file-tree.c',
    +]
    +
    +GPLUGIN_PRIVATE_BUILT_HEADERS = [
    + # Modified below.
    +]
    +
    +GPLUGIN_PRIVATE_BUILT_SOURCES = [
    + # Modified below.
    +]
    +
    +GPLUGIN_NATIVE_HEADERS = [
    + 'gplugin-native-plugin.h',
    + 'gplugin-native-loader.h',
    +]
    +
    +GPLUGIN_NATIVE_SOURCES = [
    + 'gplugin-native-plugin.c',
    + 'gplugin-native-loader.c',
    +]
    +
    +###############################################################################
    +# gplugin-enum.[ch] generation
    +###############################################################################
    +ENUM_HEADERS = [
    + 'gplugin-plugin.h',
    +]
    +
    +enums = gnome.mkenums('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]
    +
    +GPLUGIN_PUBLIC_BUILT_HEADERS += [
    + enums_h
    +]
    +
    +GPLUGIN_PUBLIC_BUILT_SOURCES += [
    + 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
    +###############################################################################
    +PRIVATE_HEADERS = GPLUGIN_PRIVATE_HEADERS + GPLUGIN_PRIVATE_BUILT_HEADERS + ['gplugin-private.h', 'gplugin-native-private.h']
    +
    +###############################################################################
    +# Configure Files
    +###############################################################################
    +gplugin_version_h = configure_file(
    + input : 'gplugin-version.h.in',
    + output : 'gplugin-version.h',
    + configuration : version_conf,
    + install : true,
    + install_dir : join_paths(get_option('includedir'), 'gplugin-1.0', 'gplugin')
    +)
    +
    +GPLUGIN_PUBLIC_BUILT_HEADERS += [
    + gplugin_version_h
    +]
    +
    +
    +gplugin_inc = include_directories('.')
    +
    +# Build gplugin.h
    +GPLUGIN_H_INCLUDES = ''
    +
    +foreach header : GPLUGIN_HEADERS
    + GPLUGIN_H_INCLUDES = '@0@\n#include <gplugin/@1@>'.format(
    + GPLUGIN_H_INCLUDES,
    + header)
    +endforeach
    +
    +foreach header : ['gplugin-version.h', 'gplugin-enums.h'] # GPLUGIN_PUBLIC_BUILT_HEADERS
    + GPLUGIN_H_INCLUDES = '@0@\n#include <gplugin/@1@>'.format(
    + GPLUGIN_H_INCLUDES,
    + header)
    +endforeach
    +
    +conf = configuration_data()
    +conf.set('GPLUGIN_H_INCLUDES', GPLUGIN_H_INCLUDES)
    +gplugin_h = configure_file(
    + input : 'gplugin.h.in',
    + output : 'gplugin.h',
    + configuration : conf,
    + install : true,
    + install_dir : join_paths(get_option('includedir'), 'gplugin-1.0'))
    +
    +# Build gplugin-native.h
    +GPLUGIN_NATIVE_H_INCLUDES = ''
    +foreach header : GPLUGIN_NATIVE_HEADERS
    + GPLUGIN_NATIVE_H_INCLUDES = '@0@\n#include <gplugin/@1@>'.format(
    + GPLUGIN_NATIVE_H_INCLUDES,
    + header)
    +endforeach
    +
    +conf = configuration_data()
    +conf.set('GPLUGIN_NATIVE_H_INCLUDES', GPLUGIN_NATIVE_H_INCLUDES)
    +gplugin_native_h = configure_file(
    + input : 'gplugin-native.h.in',
    + output : 'gplugin-native.h',
    + configuration : conf,
    + install : true,
    + install_dir : join_paths(get_option('includedir'), 'gplugin-1.0'))
    +
    +###############################################################################
    +# Library target
    +###############################################################################
    +gplugin = shared_library('gplugin',
    + GPLUGIN_SOURCES,
    + GPLUGIN_NATIVE_SOURCES,
    + GPLUGIN_PUBLIC_BUILT_SOURCES,
    + GPLUGIN_PRIVATE_SOURCES,
    + GPLUGIN_PRIVATE_BUILT_SOURCES,
    + GPLUGIN_NATIVE_HEADERS,
    + GPLUGIN_HEADERS,
    + GPLUGIN_PUBLIC_BUILT_HEADERS,
    + PRIVATE_HEADERS,
    + gplugin_h,
    + gplugin_native_h,
    + c_args : ['-DGPLUGIN_COMPILATION', '-DG_LOG_DOMAIN="GPlugin"'],
    + include_directories : toplevel_inc,
    + dependencies : [GLIB, GOBJECT, GMODULE],
    + version : GPLUGIN_LIBRARY_VERSION,
    + install : true
    +)
    +
    +gplugin_dep = declare_dependency(
    + include_directories : [toplevel_inc, include_directories('.')],
    + link_with : gplugin,
    + sources : GPLUGIN_PUBLIC_BUILT_HEADERS, # Ensure they're built before use.
    + dependencies : [GLIB, GOBJECT]
    +)
    +
    +pkgconfig.generate(
    + name : 'libgplugin',
    + description : 'A fully featured GModule based plugin library',
    + version : meson.project_version(),
    + filebase : 'gplugin',
    + subdirs : 'gplugin-1.0',
    + libraries : gplugin,
    + requires : ['glib-2.0', 'gobject-2.0', 'gmodule-2.0'],
    + variables : [
    + 'plugindir=${libdir}',
    + ],
    +)
    +
    +# 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
    +###############################################################################
    +gplugin_query = executable('gplugin-query',
    + 'gplugin-query.c',
    + dependencies : [gplugin_dep, GLIB, GOBJECT],
    + install : true)
    +
    +if get_option('help2man')
    + custom_target('gplugin-query.1',
    + command : [help2man,
    + '--name=Query installed plugins', '--section=1',
    + '--help-option=--help-all', '--no-info',
    + '--output', '@OUTPUT@',
    + gplugin_query],
    + output : 'gplugin-query.1',
    + install : true,
    + install_dir : join_paths(get_option('mandir'), 'man1'))
    +endif
    +
    +###############################################################################
    +# loader-tests static library
    +###############################################################################
    +gplugin_loader_tests = static_library('gplugin-loader-tests',
    + 'gplugin-loader-tests.c',
    + 'gplugin-loader-tests.h',
    + c_args : ['-DGI_TYPELIB_PATH="@0@"'.format(meson.current_build_dir())],
    + dependencies : [gplugin_dep],
    +)
    +
    +###############################################################################
    +# GObject Introspection
    +###############################################################################
    +if get_option('gobject-introspection')
    + gplugin_gir = gnome.generate_gir(gplugin,
    + sources : GPLUGIN_SOURCES + GPLUGIN_HEADERS +
    + GPLUGIN_PUBLIC_BUILT_SOURCES +
    + GPLUGIN_PUBLIC_BUILT_HEADERS,
    + includes : ['GModule-2.0', 'GObject-2.0'],
    + namespace : 'GPlugin',
    + symbol_prefix : 'gplugin',
    + nsversion : '@0@.0'.format(GPLUGIN_MAJOR_VERSION),
    + install : true,
    + extra_args : ['--quiet', '-DGPLUGIN_COMPILATION'])
    +endif
    +
    +###############################################################################
    +# Install Stuff
    +###############################################################################
    +# install the normal includes into the gplugin subdirectory
    +install_headers(
    + GPLUGIN_HEADERS,
    + GPLUGIN_NATIVE_HEADERS,
    + subdir : 'gplugin-1.0/gplugin'
    +)
    +
    +###############################################################################
    +# subdirectories
    +###############################################################################
    +subdir('tests')
    +
    +if ENABLE_DOC
    + subdir('reference')
    +endif
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin/reference/gplugin-docs.xml Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,59 @@
    +<?xml version="1.0"?>
    +<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
    + "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
    +
    +<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
    +<!ENTITY version SYSTEM "version.xml">
    +]>
    +<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
    + <bookinfo>
    + <title>GPlugin Reference Manual</title>
    + <abstract>
    + <title>GPlugin &version;</title>
    + <para>
    + 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.
    + </para>
    + </abstract>
    + </bookinfo>
    +
    + <part id="object-hierarchy">
    + <title>Object Hierarchy</title>
    +
    + <xi:include href="xml/tree_index.sgml"/>
    + </part>
    +
    + <part id="API">
    + <title>API Reference</title>
    +
    + <chapter id="coreapi">
    + <title>Core API</title>
    + <xi:include href="xml/gplugin-core.xml"/>
    + <xi:include href="xml/gplugin-loader.xml"/>
    + <xi:include href="xml/gplugin-manager.xml"/>
    + <xi:include href="xml/gplugin-options.xml"/>
    + <xi:include href="xml/gplugin-plugin-info.xml"/>
    + <xi:include href="xml/gplugin-plugin.xml"/>
    + <xi:include href="xml/gplugin-version.xml"/>
    + </chapter>
    +
    + <chapter id="nativeapi">
    + <title>Native API</title>
    +
    + <xi:include href="xml/gplugin-native-plugin.xml"/>
    + <xi:include href="xml/gplugin-native-loader.xml"/>
    + </chapter>
    + </part>
    +
    + <index id="api-index-full">
    + <title>Index</title>
    + <xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
    + </index>
    + <index id="api-index-deprecated" role="deprecated">
    + <title>Index of deprecated symbols</title>
    + <xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
    + </index>
    + <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
    +</book>
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin/reference/meson.build Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,45 @@
    +DOC_MODULE = 'gplugin'
    +
    +# Header files or dirs to ignore when scanning. Use base file/dir names
    +ignore_hfiles = [
    + 'gplugin.h',
    + 'gplugin-private.h',
    + 'gplugin-loader-tests.h',
    + 'gplugin-marshallers.h',
    + 'gplugin-native.h',
    + 'gplugin-native-private.h',
    + 'dynamic-test.h',
    +]
    +ignore_hfiles += GPLUGIN_PRIVATE_HEADERS
    +
    +# Extra options to supply to gtkdoc-scan.
    +scan_args = [
    + '--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(
    + input : 'version.xml.in',
    + output : 'version.xml',
    + configuration : version_conf)
    +
    +content_files = [
    +]
    +
    +gnome.gtkdoc(DOC_MODULE,
    + main_xml : DOC_MODULE + '-docs.xml',
    + src_dir : gplugin_inc,
    + dependencies : gplugin_dep,
    + 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/version.xml.in Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,1 @@
    +@GPLUGIN_VERSION@
    --- a/gplugin/tests/CMakeLists.txt Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,155 +0,0 @@
    -###############################################################################
    -# Macros
    -###############################################################################
    -macro(add_test_plugin plugin)
    - add_library(${plugin} MODULE ${plugin}.c)
    - set_target_properties(${plugin} PROPERTIES PREFIX "")
    - target_link_libraries(${plugin} ${GLIB_LIBRARIES} gplugin)
    -endmacro(add_test_plugin)
    -
    -macro(add_gtest target)
    - add_executable(${target} ${target}.c)
    - target_link_libraries(${target} ${GLIB_LIBRARIES} gplugin)
    -
    - get_target_property(_output_name ${target} RUNTIME_OUTPUT_NAME)
    - if(${_output_name})
    - else(${_output_name})
    - get_target_property(_output_name ${target} LOCATION)
    - endif(${_output_name})
    -
    - list(APPEND TESTS ${_output_name})
    -endmacro(add_gtest)
    -
    -###############################################################################
    -# Subdirectories
    -###############################################################################
    -add_subdirectory(plugins)
    -add_subdirectory(bad-plugins)
    -add_subdirectory(dynamic-type)
    -add_subdirectory(id-collision)
    -add_subdirectory(load-on-query-pass)
    -add_subdirectory(load-on-query-fail)
    -add_subdirectory(versioned-dependencies)
    -add_subdirectory(bind-local)
    -add_subdirectory(unresolved-symbol)
    -
    -###############################################################################
    -# Tests
    -###############################################################################
    -
    -#######################################
    -# Simple Tests (single file)
    -#######################################
    -add_gtest(test-core)
    -add_gtest(test-option-group)
    -add_gtest(test-plugin-manager-paths)
    -add_gtest(test-plugin-info)
    -add_gtest(test-signals)
    -add_gtest(test-version-compare)
    -
    -#######################################
    -# Dynamic Type
    -#######################################
    -add_gtest(test-dynamic-type)
    -add_dependencies(test-dynamic-type dynamic-type-provider dynamic-type-user)
    -add_definitions(-DTEST_DYNAMIC_DIR="${CMAKE_CURRENT_BINARY_DIR}/dynamic-type/")
    -
    -#######################################
    -# ID Collision
    -#######################################
    -add_gtest(test-id-collision)
    -add_dependencies(test-id-collision id-collision1 id-collision2)
    -
    -#######################################
    -# Load On Query
    -#######################################
    -add_gtest(test-load-on-query)
    -add_dependencies(test-load-on-query load-on-query-pass load-on-query-fail)
    -add_definitions(
    - -DTEST_LOAD_ON_QUERY_PASS_DIR="${CMAKE_CURRENT_BINARY_DIR}/load-on-query-pass"
    - -DTEST_LOAD_ON_QUERY_FAIL_DIR="${CMAKE_CURRENT_BINARY_DIR}/load-on-query-fail"
    -)
    -
    -#######################################
    -# Versioned Dependencies
    -#######################################
    -add_gtest(test-versioned-dependencies)
    -add_dependencies(test-versioned-dependencies
    - super-dependent
    - no-version
    - exact1
    - exact2
    - greater
    - greater-equal
    - less
    - less-equal
    - bar
    - baz
    - fez
    -)
    -add_definitions(
    - -DTEST_VERSIONED_DEPENDENCY_DIR="${CMAKE_CURRENT_BINARY_DIR}/versioned-dependencies"
    -)
    -
    -#######################################
    -# Native Loader
    -#######################################
    -add_gtest(test-native-loader)
    -add_dependencies(test-native-loader
    - basic-plugin
    - dependent-plugin
    - broken-dependent-plugin
    - query-error
    -
    - load-exception
    - load-failed
    - unload-failed
    -)
    -target_link_libraries(test-native-loader gplugin-loader-tests)
    -add_definitions(-DTEST_DIR="${CMAKE_CURRENT_BINARY_DIR}/plugins/")
    -add_definitions(-DTEST_BAD_DIR="${CMAKE_CURRENT_BINARY_DIR}/bad-plugins/")
    -add_definitions(-DTEST_ID_DIR="${CMAKE_CURRENT_BINARY_DIR}/id-collision/")
    -
    -###############################################################################
    -# Bind Local
    -###############################################################################
    -add_gtest(test-bind-local)
    -add_dependencies(test-bind-local bind-local)
    -add_definitions(-DTEST_BIND_LOCAL_DIR="${CMAKE_CURRENT_BINARY_DIR}/bind-local/")
    -
    -#######################################
    -# Unresolved Symbol
    -#######################################
    -add_gtest(test-unresolved-symbol)
    -add_dependencies(test-unresolved-symbol unresolved-symbol)
    -add_definitions(
    - -DPLUGIN_DIR="${CMAKE_CURRENT_BINARY_DIR}/unresolved-symbol"
    -)
    -
    -###############################################################################
    -# GTester Stuff
    -###############################################################################
    -set(GTESTER_TESTS "${TESTS}")
    -set(GTESTER_LOG "testgplugin.xml")
    -set(GTESTER_JUNIT "testgplugin-junit.xml")
    -
    -add_custom_command(
    - COMMAND ${GTESTER} -k --verbose -o ${GTESTER_LOG} ${GTESTER_TESTS}
    - OUTPUT ${GTESTER_LOG}
    - DEPENDS ${TESTS}
    - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
    -)
    -
    -add_custom_command(
    - COMMAND ${XSLTPROC} -o ${GTESTER_JUNIT} --nonet
    - ${CMAKE_SOURCE_DIR}/xsl/gtester-junit.xsl
    - ${GTESTER_LOG}
    - OUTPUT ${GTESTER_JUNIT}
    - DEPENDS ${GTESTER_LOG}
    - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
    -)
    -
    -add_custom_target(tests ALL
    - DEPENDS ${GTESTER_LOG} ${GTESTER_JUNIT}
    -)
    -
    --- a/gplugin/tests/bad-plugins/CMakeLists.txt Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,2 +0,0 @@
    -add_test_plugin(query-error)
    -
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin/tests/bad-plugins/meson.build Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,3 @@
    +shared_library('query-error', 'query-error.c',
    + name_prefix : '',
    + dependencies : [gplugin_dep, GLIB])
    --- a/gplugin/tests/bind-local/CMakeLists.txt Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,2 +0,0 @@
    -add_test_plugin(bind-local)
    -
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin/tests/bind-local/meson.build Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,3 @@
    +shared_library('bind-local', 'bind-local.c',
    + name_prefix : '',
    + dependencies : [gplugin_dep, GLIB])
    --- a/gplugin/tests/dynamic-type/CMakeLists.txt Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,3 +0,0 @@
    -add_test_plugin(dynamic-type-provider)
    -add_test_plugin(dynamic-type-user)
    -
    --- a/gplugin/tests/dynamic-type/dynamic-type-provider.c Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/tests/dynamic-type/dynamic-type-provider.c Tue Jan 22 22:50:20 2019 -0600
    @@ -20,36 +20,20 @@
    #include "dynamic-test.h"
    -static GType type_real = 0;
    +G_DEFINE_DYNAMIC_TYPE(DynamicTest, dynamic_test, G_TYPE_OBJECT);
    static void
    -dynamic_test_register_type(GPluginNativePlugin *plugin) {
    - if(g_once_init_enter(&type_real)) {
    - GType type = 0;
    -
    - static const GTypeInfo info = {
    - .class_size = sizeof(DynamicTestClass),
    - .instance_size = sizeof(DynamicTest),
    - };
    -
    - type = gplugin_native_plugin_register_type(plugin,
    - G_TYPE_OBJECT,
    - "DynamicTest",
    - &info,
    - 0);
    -
    - g_once_init_leave(&type_real, type);
    - }
    +dynamic_test_init(DynamicTest *inst) {
    + g_message("instance created");
    }
    -GType
    -dynamic_test_get_type(void) {
    - if(G_UNLIKELY(type_real == 0)) {
    - g_warning("dynamic_test_get_type was called before "
    - "the type was registered!\n");
    - }
    +static void
    +dynamic_test_class_finalize(DynamicTestClass *klass) {
    +}
    - return type_real;
    +static void
    +dynamic_test_class_init(DynamicTestClass *klass) {
    + g_message("class created");
    }
    G_MODULE_EXPORT GPluginPluginInfo *
    @@ -63,13 +47,7 @@
    G_MODULE_EXPORT gboolean
    gplugin_load(GPluginNativePlugin *plugin, GError **error) {
    - dynamic_test_register_type(plugin);
    -
    - if (type_real == 0) {
    - *error = g_error_new(GPLUGIN_DOMAIN, 0,
    - "type DynamicTest was not registered");
    - return FALSE;
    - }
    + dynamic_test_register_type(G_TYPE_MODULE(plugin));
    return TRUE;
    }
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin/tests/dynamic-type/meson.build Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,8 @@
    +dynamic_type_provider = shared_library('dynamic-type-provider',
    + 'dynamic-type-provider.c',
    + name_prefix : '',
    + dependencies : [gplugin_dep, GLIB])
    +
    +shared_module('dynamic-type-user', 'dynamic-type-user.c',
    + name_prefix : '',
    + dependencies : [gplugin_dep, GLIB])
    --- a/gplugin/tests/id-collision/CMakeLists.txt Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,3 +0,0 @@
    -add_test_plugin(id-collision1)
    -add_test_plugin(id-collision2)
    -
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin/tests/id-collision/meson.build Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,7 @@
    +shared_library('id-collision1', 'id-collision1.c',
    + name_prefix : '',
    + dependencies : [gplugin_dep, GLIB])
    +
    +shared_library('id-collision2', 'id-collision2.c',
    + name_prefix : '',
    + dependencies : [gplugin_dep, GLIB])
    --- a/gplugin/tests/load-on-query-fail/CMakeLists.txt Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,2 +0,0 @@
    -add_test_plugin(load-on-query-fail)
    -
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin/tests/load-on-query-fail/meson.build Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,3 @@
    +shared_library('load-on-query-fail', 'load-on-query-fail.c',
    + name_prefix : '',
    + dependencies : [gplugin_dep, GLIB])
    --- a/gplugin/tests/load-on-query-pass/CMakeLists.txt Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,2 +0,0 @@
    -add_test_plugin(load-on-query-pass)
    -
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin/tests/load-on-query-pass/meson.build Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,3 @@
    +shared_library('load-on-query-pass', 'load-on-query-pass.c',
    + name_prefix : '',
    + dependencies : [gplugin_dep, GLIB])
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin/tests/meson.build Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,140 @@
    +###############################################################################
    +# Subdirectories
    +###############################################################################
    +subdir('plugins')
    +subdir('bad-plugins')
    +subdir('dynamic-type')
    +subdir('id-collision')
    +subdir('load-on-query-pass')
    +subdir('load-on-query-fail')
    +subdir('versioned-dependencies')
    +subdir('bind-local')
    +subdir('unresolved-symbol')
    +
    +###############################################################################
    +# Tests
    +###############################################################################
    +
    +#######################################
    +# Simple Tests (single file)
    +#######################################
    +e = executable('test-core', 'test-core.c',
    + c_args : [
    + '-DTEST_DIR="@0@/plugins/"'.format(
    + meson.current_build_dir()),
    + '-DTEST_ID_DIR="@0@/id-collision/"'.format(
    + meson.current_build_dir()),
    + ],
    + dependencies : [gplugin_dep, GLIB, GOBJECT])
    +test('Core', e)
    +
    +e = executable('test-option-group', 'test-option-group.c',
    + dependencies : [gplugin_dep, GLIB, GOBJECT])
    +test('Option Group', e)
    +
    +e = executable('test-plugin-manager-paths', 'test-plugin-manager-paths.c',
    + dependencies : [gplugin_dep, GLIB, GOBJECT])
    +test('Plugin Manager Paths', e)
    +
    +e = executable('test-plugin-info', 'test-plugin-info.c',
    + dependencies : [gplugin_dep, GLIB, GOBJECT])
    +test('Plugin Info', e)
    +
    +e = executable('test-signals', 'test-signals.c',
    + c_args : ['-DTEST_DIR="@0@/plugins/"'.format(meson.current_build_dir())],
    + dependencies : [gplugin_dep, GLIB, GOBJECT])
    +test('Signals', e)
    +
    +e = executable('test-version-compare', 'test-version-compare.c',
    + dependencies : [gplugin_dep, GLIB, GOBJECT])
    +test('Version Compare', e)
    +
    +#######################################
    +# Dynamic Type
    +#######################################
    +e = executable('test-dynamic-type', 'test-dynamic-type.c',
    + c_args : [
    + '-DTEST_DYNAMIC_DIR="@0@/dynamic-type/"'.format(
    + meson.current_build_dir())
    + ],
    + dependencies : [gplugin_dep, GLIB, GOBJECT])
    +test('Dynamic Type', e)
    +
    +#######################################
    +# ID Collision
    +#######################################
    +e = executable('test-id-collision', 'test-id-collision.c',
    + c_args : [
    + '-DTEST_ID_DIR="@0@/id-collision/"'.format(
    + meson.current_build_dir()),
    + ],
    + dependencies : [gplugin_dep, GLIB, GOBJECT])
    +test('ID Collision', e)
    +
    +#######################################
    +# Load On Query
    +#######################################
    +e = executable('test-load-on-query', 'test-load-on-query.c',
    + c_args : [
    + '-DTEST_DIR="@0@/plugins/"'.format(
    + meson.current_build_dir()),
    + '-DTEST_LOAD_ON_QUERY_PASS_DIR="@0@/load-on-query-pass"'.format(
    + meson.current_build_dir()),
    + '-DTEST_LOAD_ON_QUERY_FAIL_DIR="@0@/load-on-query-fail"'.format(
    + meson.current_build_dir())
    + ],
    + dependencies : [gplugin_dep, GLIB, GOBJECT])
    +test('Load On Query', e)
    +
    +#######################################
    +# Versioned Dependencies
    +#######################################
    +e = executable('test-versioned-dependencies', 'test-versioned-dependencies.c',
    + c_args : [
    + '-DTEST_VERSIONED_DEPENDENCY_DIR="@0@/versioned-dependencies"'.format(
    + meson.current_build_dir()),
    + ],
    + dependencies : [gplugin_dep, GLIB, GOBJECT])
    +test('Versioned Dependencies', e)
    +
    +#######################################
    +# Native Loader
    +#######################################
    +e = executable('test-native-loader', 'test-native-loader.c',
    + c_args : [
    + '-DTEST_DIR="@0@/plugins/"'.format(
    + meson.current_build_dir()),
    + '-DTEST_BAD_DIR="@0@/bad-plugins/"'.format(
    + meson.current_build_dir()),
    + '-DTEST_ID_DIR="@0@/id-collision/"'.format(
    + meson.current_build_dir()),
    + ],
    + link_with : gplugin_loader_tests,
    + dependencies : [gplugin_dep, GLIB, GOBJECT])
    +test('Native Loader', e)
    +
    +###############################################################################
    +# Bind Local
    +###############################################################################
    +e = executable('test-bind-local', 'test-bind-local.c',
    + c_args : [
    + '-DTEST_BIND_LOCAL_DIR="@0@/bind-local/"'.format(
    + meson.current_build_dir()),
    + '-DTEST_BAD_DIR="@0@/bad-plugins/"'.format(
    + meson.current_build_dir()),
    + '-DTEST_ID_DIR="@0@/id-collision/"'.format(
    + meson.current_build_dir()),
    + ],
    + dependencies : [gplugin_dep, GLIB, GOBJECT])
    +test('Bind Local', e)
    +
    +###############################################################################
    +# Unresolved Symbol
    +###############################################################################
    +e = executable('test-unresolved-symbol', 'test-unresolved-symbol.c',
    + c_args : [
    + '-DPLUGIN_DIR="@0@/unresolved-symbol/"'.format(
    + meson.current_build_dir()),
    + ],
    + dependencies : [gplugin_dep, GLIB, GOBJECT])
    +# test('Unresolved Symbol', e)
    --- a/gplugin/tests/plugins/CMakeLists.txt Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,6 +0,0 @@
    -add_test_plugin(basic-plugin)
    -add_test_plugin(dependent-plugin)
    -add_test_plugin(broken-dependent-plugin)
    -add_test_plugin(load-failed)
    -add_test_plugin(load-exception)
    -add_test_plugin(unload-failed)
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin/tests/plugins/meson.build Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,23 @@
    +shared_library('basic-plugin', 'basic-plugin.c',
    + name_prefix : '',
    + dependencies : [gplugin_dep, GLIB])
    +
    +shared_library('dependent-plugin', 'dependent-plugin.c',
    + name_prefix : '',
    + dependencies : [gplugin_dep, GLIB])
    +
    +shared_library('broken-dependent-plugin', 'broken-dependent-plugin.c',
    + name_prefix : '',
    + dependencies : [gplugin_dep, GLIB])
    +
    +shared_library('load-failed', 'load-failed.c',
    + name_prefix : '',
    + dependencies : [gplugin_dep, GLIB])
    +
    +shared_library('load-exception', 'load-exception.c',
    + name_prefix : '',
    + dependencies : [gplugin_dep, GLIB])
    +
    +shared_library('unload-failed', 'unload-failed.c',
    + name_prefix : '',
    + dependencies : [gplugin_dep, GLIB])
    --- a/gplugin/tests/test-core.c Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/tests/test-core.c Tue Jan 22 22:50:20 2019 -0600
    @@ -29,6 +29,13 @@
    }
    static void
    +test_gplugin_init_init_uninit(void) {
    + gplugin_init();
    + gplugin_init();
    + gplugin_uninit();
    +}
    +
    +static void
    test_gplugin_init_uninit_with_refresh(void) {
    gplugin_init();
    gplugin_manager_refresh();
    @@ -96,6 +103,8 @@
    g_test_add_func("/core/init_uninit",
    test_gplugin_init_uninit);
    + g_test_add_func("/core/init_init_uninit",
    + test_gplugin_init_init_uninit);
    g_test_add_func("/core/init_uninit_with_refresh",
    test_gplugin_init_uninit_with_refresh);
    g_test_add_func("/core/init_uninit_with_refresh_plugins",
    --- a/gplugin/tests/test-option-group.c Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/tests/test-option-group.c Tue Jan 22 22:50:20 2019 -0600
    @@ -34,8 +34,6 @@
    argv = g_strsplit(args, ",", 0);
    argc = g_strv_length(argv);
    - gplugin_init();
    -
    ctx = g_option_context_new(NULL);
    group = gplugin_get_option_group();
    g_option_context_add_group(ctx, group);
    @@ -123,7 +121,7 @@
    static void
    test_gplugin_option_group_no_default_paths_long(void) {
    - gchar *args = "test-option-group,--no-defualt-paths";
    + gchar *args = "test-option-group,--no-default-paths";
    test_gplugin_option_group_paths(args, NULL);
    }
    --- a/gplugin/tests/test-unresolved-symbol.c Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/tests/test-unresolved-symbol.c Tue Jan 22 22:50:20 2019 -0600
    @@ -31,7 +31,7 @@
    g_test_expect_message(
    G_LOG_DOMAIN,
    G_LOG_LEVEL_WARNING,
    - "*undefined symbol: some_unresolved_symbol"
    + "*some_unresolved_symbol*"
    );
    gplugin_manager_remove_paths();
    --- a/gplugin/tests/test-versioned-dependencies.c Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/tests/test-versioned-dependencies.c Tue Jan 22 22:50:20 2019 -0600
    @@ -23,9 +23,39 @@
    #include <glib.h>
    /******************************************************************************
    + * Helpers
    + *****************************************************************************/
    +static void
    +_test_plugin_load_and_has_dependent(GPluginPlugin *dependent,
    + const gchar *id)
    +{
    + GPluginPlugin *plugin = NULL;
    + GSList *deps = NULL, *l = NULL;
    + gboolean found = FALSE;
    +
    + plugin = gplugin_manager_find_plugin("gplugin/test-no-version");
    + g_assert_cmpint(gplugin_plugin_get_state(plugin), ==,
    + GPLUGIN_PLUGIN_STATE_LOADED);
    +
    + deps = gplugin_manager_get_plugin_dependencies(plugin, NULL);
    + if(deps != NULL) {
    + for(l = deps; l; l = l->next) {
    + if(l->data == dependent) {
    + found = TRUE;
    + }
    + }
    +
    + g_slist_free_full(deps, g_object_unref);
    +
    + g_assert_true(found);
    + }
    +
    + g_object_unref(G_OBJECT(plugin));
    +}
    +
    +/******************************************************************************
    * Tests
    *****************************************************************************/
    -/* load on query */
    static void
    test_load_with_dependencies(void) {
    GPluginPlugin *plugin = NULL;
    @@ -47,55 +77,16 @@
    g_object_unref(G_OBJECT(plugin));
    /* now make sure each dependent plugin that's available was loaded */
    - plugin = gplugin_manager_find_plugin("gplugin/test-no-version");
    - g_assert_cmpint(gplugin_plugin_get_state(plugin), ==,
    - GPLUGIN_PLUGIN_STATE_LOADED);
    - g_object_unref(G_OBJECT(plugin));
    -
    - plugin = gplugin_manager_find_plugin("gplugin/test-exact1");
    - g_assert_cmpint(gplugin_plugin_get_state(plugin), ==,
    - GPLUGIN_PLUGIN_STATE_LOADED);
    - g_object_unref(G_OBJECT(plugin));
    -
    - plugin = gplugin_manager_find_plugin("gplugin/test-exact2");
    - g_assert_cmpint(gplugin_plugin_get_state(plugin), ==,
    - GPLUGIN_PLUGIN_STATE_LOADED);
    - g_object_unref(G_OBJECT(plugin));
    -
    - plugin = gplugin_manager_find_plugin("gplugin/test-greater");
    - g_assert_cmpint(gplugin_plugin_get_state(plugin), ==,
    - GPLUGIN_PLUGIN_STATE_LOADED);
    - g_object_unref(G_OBJECT(plugin));
    -
    - plugin = gplugin_manager_find_plugin("gplugin/test-greater-equal");
    - g_assert_cmpint(gplugin_plugin_get_state(plugin), ==,
    - GPLUGIN_PLUGIN_STATE_LOADED);
    - g_object_unref(G_OBJECT(plugin));
    -
    - plugin = gplugin_manager_find_plugin("gplugin/test-less");
    - g_assert_cmpint(gplugin_plugin_get_state(plugin), ==,
    - GPLUGIN_PLUGIN_STATE_LOADED);
    - g_object_unref(G_OBJECT(plugin));
    -
    - plugin = gplugin_manager_find_plugin("gplugin/test-less-equal");
    - g_assert_cmpint(gplugin_plugin_get_state(plugin), ==,
    - GPLUGIN_PLUGIN_STATE_LOADED);
    - g_object_unref(G_OBJECT(plugin));
    -
    - plugin = gplugin_manager_find_plugin("gplugin/bar");
    - g_assert_cmpint(gplugin_plugin_get_state(plugin), ==,
    - GPLUGIN_PLUGIN_STATE_LOADED);
    - g_object_unref(G_OBJECT(plugin));
    -
    - plugin = gplugin_manager_find_plugin("gplugin/baz");
    - g_assert_cmpint(gplugin_plugin_get_state(plugin), ==,
    - GPLUGIN_PLUGIN_STATE_LOADED);
    - g_object_unref(G_OBJECT(plugin));
    -
    - plugin = gplugin_manager_find_plugin("gplugin/fez");
    - g_assert_cmpint(gplugin_plugin_get_state(plugin), ==,
    - GPLUGIN_PLUGIN_STATE_LOADED);
    - g_object_unref(G_OBJECT(plugin));
    + _test_plugin_load_and_has_dependent(plugin, "gplugin/test-no-version");
    + _test_plugin_load_and_has_dependent(plugin, "gplugin/test-exact1");
    + _test_plugin_load_and_has_dependent(plugin, "gplugin/test-exact2");
    + _test_plugin_load_and_has_dependent(plugin, "gplugin/test-greater");
    + _test_plugin_load_and_has_dependent(plugin, "gplugin/test-greater-equal");
    + _test_plugin_load_and_has_dependent(plugin, "gplugin/test-less");
    + _test_plugin_load_and_has_dependent(plugin, "gplugin/test-less-equal");
    + _test_plugin_load_and_has_dependent(plugin, "gplugin/bar");
    + _test_plugin_load_and_has_dependent(plugin, "gplugin/baz");
    + _test_plugin_load_and_has_dependent(plugin, "gplugin/fez");
    }
    /******************************************************************************
    --- a/gplugin/tests/unresolved-symbol/CMakeLists.txt Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,1 +0,0 @@
    -add_test_plugin(unresolved-symbol)
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin/tests/unresolved-symbol/meson.build Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,4 @@
    +shared_module('unresolved-symbol', 'unresolved-symbol.c',
    + name_prefix : '',
    + link_args : '-Wl,--warn-unresolved-symbols',
    + dependencies : [gplugin_dep, GLIB])
    --- a/gplugin/tests/unresolved-symbol/unresolved-symbol.c Mon Apr 18 22:32:13 2016 -0500
    +++ b/gplugin/tests/unresolved-symbol/unresolved-symbol.c Tue Jan 22 22:50:20 2019 -0600
    @@ -18,6 +18,8 @@
    #include <gplugin.h>
    #include <gplugin-native.h>
    +void some_unresolved_symbol(void);
    +
    G_MODULE_EXPORT GPluginPluginInfo *
    gplugin_query(GPLUGIN_UNUSED GError **error) {
    some_unresolved_symbol();
    --- a/gplugin/tests/versioned-dependencies/CMakeLists.txt Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,12 +0,0 @@
    -add_test_plugin(super-dependent)
    -add_test_plugin(no-version)
    -add_test_plugin(exact1)
    -add_test_plugin(exact2)
    -add_test_plugin(greater)
    -add_test_plugin(greater-equal)
    -add_test_plugin(less)
    -add_test_plugin(less-equal)
    -add_test_plugin(bar)
    -add_test_plugin(baz)
    -add_test_plugin(fez)
    -
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin/tests/versioned-dependencies/meson.build Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,43 @@
    +shared_library('super-dependent', 'super-dependent.c',
    + name_prefix : '',
    + dependencies : [gplugin_dep, GLIB])
    +
    +shared_library('no-version', 'no-version.c',
    + name_prefix : '',
    + dependencies : [gplugin_dep, GLIB])
    +
    +shared_library('exact1', 'exact1.c',
    + name_prefix : '',
    + dependencies : [gplugin_dep, GLIB])
    +
    +shared_library('exact2', 'exact2.c',
    + name_prefix : '',
    + dependencies : [gplugin_dep, GLIB])
    +
    +shared_library('greater', 'greater.c',
    + name_prefix : '',
    + dependencies : [gplugin_dep, GLIB])
    +
    +shared_library('greater-equal', 'greater-equal.c',
    + name_prefix : '',
    + dependencies : [gplugin_dep, GLIB])
    +
    +shared_library('less', 'less.c',
    + name_prefix : '',
    + dependencies : [gplugin_dep, GLIB])
    +
    +shared_library('less-equal', 'less-equal.c',
    + name_prefix : '',
    + dependencies : [gplugin_dep, GLIB])
    +
    +shared_library('bar', 'bar.c',
    + name_prefix : '',
    + dependencies : [gplugin_dep, GLIB])
    +
    +shared_library('baz', 'baz.c',
    + name_prefix : '',
    + dependencies : [gplugin_dep, GLIB])
    +
    +shared_library('fez', 'fez.c',
    + name_prefix : '',
    + dependencies : [gplugin_dep, GLIB])
    --- a/lua/CMakeLists.txt Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,90 +0,0 @@
    -option(
    - BUILD_LUA
    - "Whether or not to build the Lua plugin loader"
    - "On"
    -)
    -
    -if(BUILD_LUA)
    - if(NOT BUILD_GIR)
    - message(FATAL_ERROR "Lua plugin requires GObject Introspection.")
    - endif(NOT BUILD_GIR)
    -
    - set(GPLUGIN_LUA_SOURCES
    - gplugin-lua-core.c
    - gplugin-lua-loader.c
    - gplugin-lua-plugin.c
    - )
    -
    - set(GPLUGIN_LUA_HEADERS
    - gplugin-lua-loader.h
    - gplugin-lua-plugin.h
    - )
    -
    - set(_LUAS "lua>=5.1.0;lua5.1>=5.1.0;luajit>=2.0.0;lua5.2>=5.2.0")
    - foreach(_LUA ${_LUAS})
    - if(NOT LUA_FOUND)
    - pkg_check_modules(LUA ${_LUA})
    - endif(NOT LUA_FOUND)
    - endforeach(_LUA)
    -
    - if(NOT LUA_FOUND)
    - message(FATAL_ERROR "No usable Lua library was found")
    - endif(NOT LUA_FOUND)
    -
    - include_directories(${LUA_INCLUDE_DIRS})
    -
    - message(STATUS "checking for lua module 'lgi'")
    -
    - # compile our lua-lgi test program
    - try_compile(LUA_LGI_COMPILE
    - ${CMAKE_CURRENT_BINARY_DIR}
    - ${CMAKE_CURRENT_SOURCE_DIR}/gplugin-lua-test-lgi.c
    - CMAKE_FLAGS
    - -DINCLUDE_DIRECTORIES:STRING=${LUA_INCLUDE_DIRS}
    - -DLINK_LIBRARIES:STRING=${LUA_LIBRARIES}
    - OUTPUT_VARIABLE OUTPUT
    - COPY_FILE ${CMAKE_CURRENT_BINARY_DIR}/gplugin-lua-test-lgi
    - )
    - if(NOT ${LUA_LGI_COMPILE})
    - message(STATUS ${OUTPUT})
    - message(FATAL_ERROR "Failed to compile the lua-lgi test")
    - endif(NOT ${LUA_LGI_COMPILE})
    -
    - # run our lua-lgi test program
    - execute_process(
    - COMMAND ${CMAKE_CURRENT_BINARY_DIR}/gplugin-lua-test-lgi
    - RESULT_VARIABLE LUA_LGI_FOUND
    - )
    -
    - if(${LUA_LGI_FOUND} EQUAL 0)
    - message(STATUS " found lgi")
    - else(${LUA_LGI_FOUND} EQUAL 0)
    - message(FATAL_ERROR " failed to find the 'lgi' lua module")
    - endif(${LUA_LGI_FOUND} EQUAL 0)
    -
    - option(
    - MOONSCRIPT_TESTS
    - "Whether or not to run the moonscript tests"
    - "Off"
    - )
    -
    - # now add the library
    - add_library(gplugin-lua MODULE
    - ${GPLUGIN_LUA_SOURCES}
    - ${GPLUGIN_LUA_HEADERS}
    - )
    -
    - set_target_properties(gplugin-lua PROPERTIES PREFIX "")
    -
    - target_link_libraries(gplugin-lua
    - ${LUA_LIBRARIES}
    - gplugin
    - )
    -
    - install(TARGETS gplugin-lua DESTINATION ${CMAKE_INSTALL_LIBDIR}/gplugin)
    -endif(BUILD_LUA)
    -
    -if(TESTING_ENABLED)
    - add_subdirectory(tests)
    -endif(TESTING_ENABLED)
    -
    --- a/lua/gplugin-lua-loader.c Mon Apr 18 22:32:13 2016 -0500
    +++ b/lua/gplugin-lua-loader.c Tue Jan 22 22:50:20 2019 -0600
    @@ -25,11 +25,7 @@
    #include <lauxlib.h>
    #include <lualib.h>
    -/******************************************************************************
    - * Globals
    - *****************************************************************************/
    -static GObjectClass *parent_class = NULL;
    -static GType type_real = 0;
    +G_DEFINE_DYNAMIC_TYPE(GPluginLuaLoader, gplugin_lua_loader, GPLUGIN_TYPE_LOADER);
    /******************************************************************************
    * Helpers
    @@ -171,7 +167,7 @@
    plugin = g_object_new(GPLUGIN_TYPE_LUA_PLUGIN,
    "filename", filename,
    "loader", loader,
    - "state", L,
    + "lua-state", L,
    "info", info,
    NULL);
    @@ -199,11 +195,17 @@
    * GObject Stuff
    *****************************************************************************/
    static void
    +gplugin_lua_loader_init(GPluginLuaLoader *loader) {
    +}
    +
    +static void
    +gplugin_lua_loader_class_finalize(GPluginLuaLoaderClass *klass) {
    +}
    +
    +static void
    gplugin_lua_loader_class_init(GPluginLuaLoaderClass *klass) {
    GPluginLoaderClass *loader_class = GPLUGIN_LOADER_CLASS(klass);
    - parent_class = g_type_class_peek_parent(klass);
    -
    loader_class->supported_extensions =
    gplugin_lua_loader_class_supported_extensions;
    loader_class->query = gplugin_lua_loader_query;
    @@ -216,32 +218,5 @@
    *****************************************************************************/
    void
    gplugin_lua_loader_register(GPluginNativePlugin *plugin) {
    - if(g_once_init_enter(&type_real)) {
    - GType type = 0;
    -
    - static const GTypeInfo info = {
    - .class_size = sizeof(GPluginLuaLoaderClass),
    - .class_init = (GClassInitFunc)gplugin_lua_loader_class_init,
    - .instance_size = sizeof(GPluginLuaLoader),
    - };
    -
    - type = gplugin_native_plugin_register_type(plugin,
    - GPLUGIN_TYPE_LOADER,
    - "GPluginLuaLoader",
    - &info,
    - 0);
    -
    - g_once_init_leave(&type_real, type);
    - }
    + gplugin_lua_loader_register_type(G_TYPE_MODULE(plugin));
    }
    -
    -GType
    -gplugin_lua_loader_get_type(void) {
    - if(G_UNLIKELY(type_real == 0)) {
    - g_warning("gplugin_lua_loader_get_type was called before "
    - "the type was registered!\n");
    - }
    -
    - return type_real;
    -}
    -
    --- a/lua/gplugin-lua-loader.h Mon Apr 18 22:32:13 2016 -0500
    +++ b/lua/gplugin-lua-loader.h Tue Jan 22 22:50:20 2019 -0600
    @@ -32,21 +32,17 @@
    #include <gplugin-native.h>
    struct _GPluginLuaLoader {
    + /*< private >*/
    GPluginLoader parent;
    - void (*_gplugin_reserved_1)(void);
    - void (*_gplugin_reserved_2)(void);
    - void (*_gplugin_reserved_3)(void);
    - void (*_gplugin_reserved_4)(void);
    + gpointer reserved[4];
    };
    struct _GPluginLuaLoaderClass {
    + /*< private >*/
    GPluginLoaderClass parent;
    - 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
    --- a/lua/gplugin-lua-plugin.c Mon Apr 18 22:32:13 2016 -0500
    +++ b/lua/gplugin-lua-plugin.c Tue Jan 22 22:50:20 2019 -0600
    @@ -19,14 +19,16 @@
    #include <lua.h>
    -#define GPLUGIN_LUA_PLUGIN_GET_PRIVATE(obj) \
    - (G_TYPE_INSTANCE_GET_PRIVATE((obj), GPLUGIN_TYPE_LUA_PLUGIN, GPluginLuaPluginPrivate))
    -
    /******************************************************************************
    * Typedefs
    *****************************************************************************/
    typedef struct {
    lua_State *L;
    +
    + gchar *filename;
    + GPluginLoader *loader;
    + GPluginPluginInfo *info;
    + GPluginPluginState state;
    } GPluginLuaPluginPrivate;
    /******************************************************************************
    @@ -34,24 +36,33 @@
    *****************************************************************************/
    enum {
    PROP_ZERO,
    - PROP_STATE,
    - PROP_LAST,
    + PROP_LUA_STATE,
    + N_PROPERTIES,
    + /* overrides */
    + PROP_FILENAME = N_PROPERTIES,
    + PROP_LOADER,
    + PROP_INFO,
    + PROP_STATE
    };
    +static GParamSpec *properties[N_PROPERTIES] = {NULL,};
    +
    +/* I hate forward declarations... */
    +static void gplugin_lua_plugin_iface_init(GPluginPluginInterface *iface);
    +
    +G_DEFINE_DYNAMIC_TYPE_EXTENDED(
    + GPluginLuaPlugin,
    + gplugin_lua_plugin,
    + G_TYPE_OBJECT,
    + 0,
    + G_ADD_PRIVATE_DYNAMIC(GPluginLuaPlugin)
    + G_IMPLEMENT_INTERFACE(GPLUGIN_TYPE_PLUGIN, gplugin_lua_plugin_iface_init)
    +);
    /******************************************************************************
    - * Globals
    - *****************************************************************************/
    -static GObjectClass *parent_class = NULL;
    -static GType type_real = 0;
    -
    -/******************************************************************************
    - * Private Stuff
    + * GPluginPlugin Implementation
    *****************************************************************************/
    static void
    -gplugin_lua_plugin_set_state(GPluginLuaPlugin *plugin, lua_State *L) {
    - GPluginLuaPluginPrivate *priv = GPLUGIN_LUA_PLUGIN_GET_PRIVATE(plugin);
    -
    - priv->L = L;
    +gplugin_lua_plugin_iface_init(GPluginPluginInterface *iface) {
    }
    /******************************************************************************
    @@ -62,12 +73,27 @@
    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);
    + break;
    +
    + /* overrides */
    + case PROP_FILENAME:
    + g_value_set_string(value, priv->filename);
    + break;
    + case PROP_LOADER:
    + g_value_set_object(value, priv->loader);
    + break;
    + case PROP_INFO:
    + g_value_set_object(value, priv->info);
    + break;
    case PROP_STATE:
    - g_value_set_pointer(value,
    - gplugin_lua_plugin_get_state(plugin));
    + g_value_set_enum(value, priv->state);
    break;
    +
    default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
    break;
    @@ -79,12 +105,27 @@
    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);
    + break;
    +
    + /* overrides */
    + case PROP_FILENAME:
    + priv->filename = g_strdup(g_value_get_string(value));
    + break;
    + case PROP_LOADER:
    + priv->loader = g_object_ref(g_value_get_object(value));
    + break;
    + case PROP_INFO:
    + priv->info = g_object_ref(g_value_get_object(value));
    + break;
    case PROP_STATE:
    - gplugin_lua_plugin_set_state(plugin,
    - g_value_get_pointer(value));
    + priv->state = g_value_get_enum(value);
    break;
    +
    default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
    break;
    @@ -93,70 +134,64 @@
    static void
    gplugin_lua_plugin_finalize(GObject *obj) {
    - GPluginLuaPluginPrivate *priv = GPLUGIN_LUA_PLUGIN_GET_PRIVATE(obj);
    + GPluginLuaPluginPrivate *priv = gplugin_lua_plugin_get_instance_private(GPLUGIN_LUA_PLUGIN(obj));
    if(priv->L)
    lua_close(priv->L);
    - G_OBJECT_CLASS(parent_class)->finalize(obj);
    + g_free(priv->filename);
    + g_object_unref(G_OBJECT(priv->loader));
    + g_object_unref(G_OBJECT(priv->info));
    +
    + G_OBJECT_CLASS(gplugin_lua_plugin_parent_class)->finalize(obj);
    +}
    +
    +static void
    +gplugin_lua_plugin_init(GPluginLuaPlugin *plugin) {
    +}
    +
    +static void
    +gplugin_lua_plugin_class_finalize(GPluginLuaPluginClass *klass) {
    }
    static void
    gplugin_lua_plugin_class_init(GPluginLuaPluginClass *klass) {
    GObjectClass *obj_class = G_OBJECT_CLASS(klass);
    - parent_class = g_type_class_peek_parent(klass);
    -
    - g_type_class_add_private(klass, sizeof(GPluginLuaPluginPrivate));
    -
    obj_class->get_property = gplugin_lua_plugin_get_property;
    obj_class->set_property = gplugin_lua_plugin_set_property;
    obj_class->finalize = gplugin_lua_plugin_finalize;
    - g_object_class_install_property(obj_class, PROP_STATE,
    - g_param_spec_pointer("state", "state",
    - "The lua state for the plugin",
    - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
    + properties[PROP_LUA_STATE] = g_param_spec_pointer(
    + "lua-state", "lua-state",
    + "The lua state for the plugin",
    + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
    + );
    +
    + g_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_lua_plugin_register(GPluginNativePlugin *plugin) {
    - if(g_once_init_enter(&type_real)) {
    - GType type = 0;
    -
    - static const GTypeInfo info = {
    - .class_size = sizeof(GPluginLuaPluginClass),
    - .class_init = (GClassInitFunc)gplugin_lua_plugin_class_init,
    - .instance_size = sizeof(GPluginLuaPlugin),
    - };
    -
    - type = gplugin_native_plugin_register_type(plugin,
    - GPLUGIN_TYPE_PLUGIN,
    - "GPluginLuaPlugin",
    - &info,
    - 0);
    -
    - g_once_init_leave(&type_real, type);
    - }
    -}
    -
    -GType
    -gplugin_lua_plugin_get_type(void) {
    - if(G_UNLIKELY(type_real == 0)) {
    - g_warning("gplugin_lua_plugin_get_type was called before "
    - "the type was registered!\n");
    - }
    -
    - return type_real;
    +gplugin_lua_plugin_register(GPluginNativePlugin *native) {
    + gplugin_lua_plugin_register_type(G_TYPE_MODULE(native));
    }
    lua_State *
    -gplugin_lua_plugin_get_state(const GPluginLuaPlugin *plugin) {
    - GPluginLuaPluginPrivate *priv = GPLUGIN_LUA_PLUGIN_GET_PRIVATE(plugin);
    +gplugin_lua_plugin_get_state(GPluginLuaPlugin *plugin) {
    + GPluginLuaPluginPrivate *priv = NULL;
    +
    + g_return_val_if_fail(GPLUGIN_IS_LUA_PLUGIN(plugin), NULL);
    +
    + priv = gplugin_lua_plugin_get_instance_private(plugin);
    return priv->L;
    }
    -
    --- a/lua/gplugin-lua-plugin.h Mon Apr 18 22:32:13 2016 -0500
    +++ b/lua/gplugin-lua-plugin.h Tue Jan 22 22:50:20 2019 -0600
    @@ -34,24 +34,25 @@
    #include <lua.h>
    struct _GPluginLuaPlugin {
    - GPluginPlugin parent;
    + /*< private >*/
    + GObject parent;
    +
    + gpointer reserved[4];
    };
    struct _GPluginLuaPluginClass {
    - GPluginPluginClass parent;
    + /*< private >*/
    + GObjectClass parent;
    - 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
    -void gplugin_lua_plugin_register(GPluginNativePlugin *plugin);
    +void gplugin_lua_plugin_register(GPluginNativePlugin *native);
    GType gplugin_lua_plugin_get_type(void);
    -lua_State *gplugin_lua_plugin_get_state(const GPluginLuaPlugin *plugin);
    +lua_State *gplugin_lua_plugin_get_state(GPluginLuaPlugin *plugin);
    G_END_DECLS
    --- a/lua/gplugin-lua-test-lgi.c Mon Apr 18 22:32:13 2016 -0500
    +++ b/lua/gplugin-lua-test-lgi.c Tue Jan 22 22:50:20 2019 -0600
    @@ -16,18 +16,46 @@
    */
    #include <stdio.h>
    +#include <string.h>
    #include <lua.h>
    #include <lauxlib.h>
    #include <lualib.h>
    +static void
    +_add_require_path(lua_State *L, const char *path) {
    + const char *pkg_path = NULL;
    + char buff[255];
    +
    + lua_getglobal(L, "package");
    + lua_getfield(L, -1, "path"); // get field "path" from table at top of stack (-1)
    + pkg_path = lua_tostring(L, -1); // grab path string from top of stack
    +
    + memset(buff, 0, sizeof(buff));
    + snprintf(buff, sizeof(buff), "%s;%s", pkg_path, path);
    +
    + lua_pop(L, 1); // pop off the path field
    + lua_pushstring(L, buff); // push the new one
    + lua_setfield(L, -2, "path"); // set the field "path" in table at -2 with value at top of stack
    + lua_pop( L, 1 ); // get rid of package table from top of stack
    +}
    +
    int
    main(int argc, char *argv[]) {
    - lua_State *L = luaL_newstate();
    + lua_State *L = NULL;
    int ret = 0;
    + L = luaL_newstate();
    + if(L == NULL) {
    + return 134;
    + }
    +
    luaL_openlibs(L);
    + /* add some additional paths to package.path */
    + //_add_require_path(L, "/usr/local/lib/luarocks/rocks");
    +
    + /* now try to do the require */
    lua_getglobal(L, "require");
    lua_pushstring(L, "lgi");
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/lua/meson.build Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,52 @@
    +if get_option('lua')
    + if not get_option('gobject-introspection')
    + error('Lua plugin requires GObject Introspection.')
    + endif
    +
    + GPLUGIN_LUA_SOURCES = [
    + 'gplugin-lua-core.c',
    + 'gplugin-lua-loader.c',
    + 'gplugin-lua-plugin.c',
    + ]
    +
    + GPLUGIN_LUA_HEADERS = [
    + 'gplugin-lua-loader.h',
    + 'gplugin-lua-plugin.h',
    + ]
    +
    + _LUAS = [['lua', '>=5.1.0'],
    + ['lua5.1', '>=5.1.0'],
    + ['luajit', '>=2.0.0'],
    + ['lua5.2', '>=5.2.0']]
    + LUA_FOUND = false
    + foreach _LUA : _LUAS
    + if not LUA_FOUND
    + LUA = dependency(_LUA[0], version : _LUA[1], required : false)
    + LUA_FOUND = LUA.found()
    + endif
    + endforeach
    +
    + if not LUA_FOUND
    + error('No usable Lua library was found')
    + endif
    +
    + # Compile and run our lua-lgi test program
    + lua_lgi_test = compiler.run(files('gplugin-lua-test-lgi.c'),
    + dependencies : LUA,
    + name : 'lua "lgi" module')
    + if not lua_lgi_test.compiled() or lua_lgi_test.returncode() != 0
    + error('Failed to find the "lgi" lua module')
    + endif
    +
    + # now add the library
    + shared_library('gplugin-lua',
    + GPLUGIN_LUA_SOURCES,
    + GPLUGIN_LUA_HEADERS,
    + name_prefix : '',
    + dependencies : [LUA, gplugin_dep],
    + install : true,
    + install_dir : join_paths(get_option('libdir'), 'gplugin')
    + )
    +endif # lua
    +
    +subdir('tests')
    --- a/lua/tests/CMakeLists.txt Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,58 +0,0 @@
    -if(BUILD_LUA)
    -
    -macro(add_lua_gtest target)
    - add_executable(${target} ${target}.c)
    - target_link_libraries(${target}
    - ${GLIB_LIBRARIES} ${LUA_LIBRARIES} gplugin
    - )
    - add_dependencies(${target} gplugin-lua)
    -
    - get_target_property(_output_name ${target} RUNTIME_OUTPUT_NAME)
    - if(NOT ${_output_name})
    - get_target_property(_output_name ${target} LOCATION)
    - endif(NOT ${_output_name})
    -
    - list(APPEND LUA_TESTS ${_output_name})
    -endmacro(add_lua_gtest)
    -
    -add_definitions(
    - -DLUA_LOADER_DIR="${CMAKE_BINARY_DIR}/lua"
    - -DLUA_PLUGIN_DIR="${CMAKE_CURRENT_SOURCE_DIR}/lua-plugins"
    - -DMOONSCRIPT_PLUGIN_DIR="${CMAKE_CURRENT_SOURCE_DIR}/moonscript-plugins"
    -)
    -
    -add_lua_gtest(test-lua-loader)
    -target_link_libraries(test-lua-loader gplugin-loader-tests)
    -
    -if(MOONSCRIPT_TESTS)
    - add_lua_gtest(test-lua-moon-loader)
    - target_link_libraries(test-lua-moon-loader gplugin-loader-tests)
    -endif(MOONSCRIPT_TESTS)
    -
    -set(GTESTER_LUA_TESTS "${LUA_TESTS}")
    -set(GTESTER_LUA_LOG "test-gplugin-lua.xml")
    -set(GTESTER_LUA_JUNIT "test-gplugin-lua-junit.xml")
    -
    -add_custom_command(
    - COMMAND ${GTESTER} -k --verbose -o ${GTESTER_LUA_LOG} ${LUA_TESTS}
    - OUTPUT ${GTESTER_LUA_LOG}
    - DEPENDS gplugin ${GPLUGIN_GIR_TARGETS} gplugin-lua
    - ${LUA_TESTS} ${CMAKE_CURRENT_SOURCE_DIR}/lua-plugins
    - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
    -)
    -
    -add_custom_command(
    - COMMAND ${XSLTPROC} -o ${GTESTER_LUA_JUNIT} --nonet
    - ${CMAKE_SOURCE_DIR}/xsl/gtester-junit.xsl
    - ${GTESTER_LUA_LOG}
    - OUTPUT ${GTESTER_LUA_JUNIT}
    - DEPENDS ${GTESTER_LUA_LOG}
    - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
    -)
    -
    -add_custom_target(lua-tests ALL
    - DEPENDS ${GTESTER_LUA_LOG} ${GTESTER_LUA_JUNIT} ${LUA_TESTS}
    -)
    -
    -endif(BUILD_LUA)
    -
    --- a/lua/tests/lua-plugins/basic.lua Mon Apr 18 22:32:13 2016 -0500
    +++ b/lua/tests/lua-plugins/basic.lua Tue Jan 22 22:50:20 2019 -0600
    @@ -41,3 +41,4 @@
    return true
    end
    +print(gplugin_query())
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/lua/tests/meson.build Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,29 @@
    +if get_option('lua')
    +
    +e = executable('test-lua-loader', 'test-lua-loader.c',
    + c_args : [
    + '-DLUA_LOADER_DIR="@0@/lua"'.format(meson.build_root()),
    + '-DLUA_PLUGIN_DIR="@0@/lua-plugins"'.format(
    + meson.current_source_dir()),
    + '-DMOONSCRIPT_PLUGIN_DIR="@0@/moonscript-plugins"'.format(
    + meson.current_source_dir()),
    + ],
    + link_with : gplugin_loader_tests,
    + dependencies : [GLIB, GOBJECT, LUA, gplugin_dep])
    +test('Lua Loader', e)
    +
    +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_PLUGIN_DIR="@0@/lua-plugins"'.format(
    + meson.current_source_dir()),
    + '-DMOONSCRIPT_PLUGIN_DIR="@0@/moonscript-plugins"'.format(
    + meson.current_source_dir()),
    + ],
    + link_with : gplugin_loader_tests,
    + dependencies : [GLIB, GOBJECT, LUA, gplugin_dep])
    + test('Lua Moon Loader', e)
    +endif
    +
    +endif # lua
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/meson.build Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,158 @@
    +###############################################################################
    +# Project Info
    +###############################################################################
    +project('gplugin', 'c', version : '0.28.0',
    + meson_version : '>=0.37.0',
    + default_options : ['c_std=c99'])
    +
    +parts = meson.project_version().split('-')
    +if parts.length() > 1
    + extra = parts[1]
    +else
    + extra = ''
    +endif
    +
    +parts = parts[0].split('.')
    +GPLUGIN_MAJOR_VERSION = parts[0]
    +
    +version_conf = configuration_data()
    +version_conf.set('GPLUGIN_MAJOR_VERSION', GPLUGIN_MAJOR_VERSION)
    +version_conf.set('GPLUGIN_MINOR_VERSION', parts[1])
    +version_conf.set('GPLUGIN_MICRO_VERSION', parts[2])
    +version_conf.set('GPLUGIN_EXTRA_VERSION', extra)
    +version_conf.set('GPLUGIN_VERSION', meson.project_version())
    +
    +LOCALE_DIR = join_paths(get_option('prefix'), get_option('localedir'))
    +add_project_arguments('-DLOCALEDIR="@0@"'.format(LOCALE_DIR), language : 'c')
    +
    +###############################################################################
    +# Dependencies
    +###############################################################################
    +gnome = import('gnome')
    +pkgconfig = import('pkgconfig')
    +
    +if get_option('help2man')
    + help2man = find_program('help2man')
    +endif
    +
    +GLIB = dependency('glib-2.0', version : '>=2.40.0')
    +GOBJECT = dependency('gobject-2.0')
    +
    +# we separate gmodule out so our test aren't linked to it
    +GMODULE = dependency('gmodule-2.0')
    +
    +###############################################################################
    +# NLS
    +###############################################################################
    +GETTEXT_PACKAGE = 'gplugin'
    +
    +add_project_arguments('-DGETTEXT_PACKAGE="@0@"'.format(GETTEXT_PACKAGE),
    + language : 'c')
    +
    +if get_option('nls')
    + i18n = import('i18n')
    +endif
    +
    +###############################################################################
    +# Build Info
    +###############################################################################
    +compiler = meson.get_compiler('c')
    +
    +add_project_arguments(
    + '-DPREFIX="@0@"'.format(get_option('prefix')),
    + '-DLIBDIR="@0@"'.format(get_option('libdir')),
    + '-DGPLUGIN_WEBSITE="https://bitbucket.org/gplugin/gplugin"',
    + language : 'c'
    +)
    +
    +if compiler.has_argument('-Wformat')
    + add_project_arguments('-Wformat', language : 'c')
    + if compiler.has_multi_arguments(['-Wformat', '-Werror=format-security'])
    + add_project_arguments('-Werror=format-security', language : 'c')
    + endif
    +endif
    +
    +configure_file(
    + input : 'gplugin-version.sh.in',
    + 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('.')
    +
    +
    +###############################################################################
    +# gtk-doc
    +###############################################################################
    +ENABLE_DOC = get_option('doc')
    +if ENABLE_DOC
    + if meson.version().version_compare('<0.41.2')
    + error('Meson 0.41.2 or newer is required to build documentation.')
    + endif
    +endif
    +
    +###############################################################################
    +# Subdirectories
    +###############################################################################
    +subdir('gplugin')
    +subdir('gplugin-gtk')
    +subdir('gplugin-gtk-viewer')
    +subdir('packaging')
    +subdir('plugins')
    +subdir('po')
    +
    +subdir('lua')
    +subdir('perl')
    +subdir('python')
    +subdir('tcc')
    +
    +###############################################################################
    +# Install stuff
    +###############################################################################
    +# documentation
    +install_data('ChangeLog', 'INSTALL', 'README', '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})
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/meson_options.txt Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,62 @@
    +###############################################################################
    +# Options
    +###############################################################################
    +option(
    + 'gobject-introspection',
    + type : 'boolean', value : true,
    + description : 'Whether or not to build a GObject Introspection type library'
    +)
    +
    +option(
    + 'nls',
    + type : 'boolean', value : true,
    + description : 'Install translation files'
    +)
    +
    +option(
    + 'help2man',
    + type : 'boolean', value : true,
    + description : 'Whether or not to build man pages from --help output'
    +)
    +
    +option(
    + 'doc',
    + type : 'boolean', value : true,
    + description : 'build documentation with gtk-doc'
    +)
    +
    +option(
    + 'gtk3',
    + type : 'boolean', value : true,
    + description : 'Whether or not to build the gtk3 library'
    +)
    +
    +option(
    + 'lua',
    + type : 'boolean', value : true,
    + description : 'Whether or not to build the Lua plugin loader'
    +)
    +
    +option(
    + 'moonscript-tests',
    + type : 'boolean', value : false,
    + description : 'Whether or not to run the moonscript tests'
    +)
    +
    +option(
    + 'perl',
    + type : 'boolean', value : false,
    + description : 'Whether or not to build the Perl plugin loader'
    +)
    +
    +option(
    + 'python',
    + type : 'boolean', value : true,
    + description : 'Whether or not to build the Python 3.x plugin loader'
    +)
    +
    +option(
    + 'tcc',
    + type : 'boolean', value : false,
    + description : 'Whether or not to build the TCC plugin loader'
    +)
    --- a/packaging/debian/changelog Mon Apr 18 22:32:13 2016 -0500
    +++ b/packaging/debian/changelog Tue Jan 22 22:50:20 2019 -0600
    @@ -1,4 +1,4 @@
    -gplugin (0.27) unstable; urgency=medium
    +gplugin (0.28) UNRELEASED; urgency=medium
    * New upstream release, see official changelog
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/packaging/debian/clean Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,1 @@
    +build
    --- a/packaging/debian/control Mon Apr 18 22:32:13 2016 -0500
    +++ b/packaging/debian/control Tue Jan 22 22:50:20 2019 -0600
    @@ -2,16 +2,16 @@
    Section: libs
    Priority: optional
    Maintainer: Gary Kramlich <grim@reaperworld.com>
    -Build-Depends: debhelper (>=9), dh-exec,
    - cmake, libglib2.0-dev, libgtk-3-dev,
    +Build-Depends: debhelper (>=9),
    + meson (>=0.37.0), libglib2.0-dev, libgtk-3-dev,
    xsltproc, gettext, help2man,
    gobject-introspection, libgirepository1.0-dev,
    liblua5.1-0-dev, lua-lgi,
    python3-dev, python-gi-dev, python3-gi
    -Homepage: https://bitbucket.org/gplugin/main
    -Vcs-Browser: https://bitbucket.org/gplugin/main/src
    -Vcs-Hg: https://bitbucket.org/gplugin/main
    -Standards-Version: 3.9.6
    +Homepage: https://bitbucket.org/gplugin/gplugin
    +Vcs-Browser: https://bitbucket.org/gplugin/gplugin/src
    +Vcs-Hg: https://bitbucket.org/gplugin/gplugin
    +Standards-Version: 3.9.8
    Package: libgplugin0
    Architecture: any
    @@ -24,6 +24,17 @@
    .
    This package contains the main library.
    +Package: libgplugin0-bin
    +Architecture: any
    +Section: utils
    +Depends: ${misc:Depends}, ${shlibs:Depends}, libgplugin0 (= ${binary:Version}), libglib2.0-0 (>=2.20.0)
    +Description: GObject based plugin library utilities
    + GPlugin is a GObject based library that implements a reusable plugin system
    + which supports loading plugins in other languages via loaders. It relies
    + heavily on GObjectIntrospection to expose its API to the other languages.
    + .
    + This package contains utilities for the library.
    +
    Package: libgplugin-dev
    Architecture: any
    Section: libdevel
    @@ -81,7 +92,7 @@
    Package: gir1.2-gplugin-0.0
    Architecture: any
    -Depends: ${misc:Depends}, libgplugin0
    +Depends: ${gir:Depends}, ${misc:Depends}, libgplugin0
    Section: introspection
    Description: typelibe for libgplugin
    GPlugin is a GObject based library that implements a reusable plugin system
    --- a/packaging/debian/copyright Mon Apr 18 22:32:13 2016 -0500
    +++ b/packaging/debian/copyright Tue Jan 22 22:50:20 2019 -0600
    @@ -1,7 +1,7 @@
    -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
    +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
    Upstream-Name: gplugin
    Upstream-Contact: grim@reaperworld.com
    -Source: https://bitbucket.org/gplugin/main
    +Source: https://bitbucket.org/gplugin/gplugin
    Files: *
    Copyright: 2011-2014 Gary Kramlich <grim@reaperworld.com>
    --- a/packaging/debian/gir1.2-gplugin-0.0.install Mon Apr 18 22:32:13 2016 -0500
    +++ b/packaging/debian/gir1.2-gplugin-0.0.install Tue Jan 22 22:50:20 2019 -0600
    @@ -1,3 +1,2 @@
    -#!/usr/bin/dh-exec
    -usr/lib/${DEB_HOST_MULTIARCH}/girepository-1.0/
    -usr/share/gir-1.0/
    +debian/tmp/usr/lib/*/girepository-1.0/
    +debian/tmp/usr/share/gir-1.0/
    --- a/packaging/debian/libgplugin-dev.install Mon Apr 18 22:32:13 2016 -0500
    +++ b/packaging/debian/libgplugin-dev.install Tue Jan 22 22:50:20 2019 -0600
    @@ -1,6 +1,5 @@
    -#!/usr/bin/dh-exec
    -usr/include/gplugin-1.0/gplugin
    -usr/include/gplugin-1.0/gplugin.h
    -usr/include/gplugin-1.0/gplugin-native.h
    -usr/lib/${DEB_HOST_MULTIARCH}/libgplugin.so
    -usr/lib/${DEB_HOST_MULTIARCH}/pkgconfig/gplugin.pc
    +debian/tmp/usr/include/gplugin-1.0/gplugin
    +debian/tmp/usr/include/gplugin-1.0/gplugin.h
    +debian/tmp/usr/include/gplugin-1.0/gplugin-native.h
    +debian/tmp/usr/lib/*/libgplugin.so
    +debian/tmp/usr/lib/*/pkgconfig/gplugin.pc
    --- a/packaging/debian/libgplugin-gtk-bin.install Mon Apr 18 22:32:13 2016 -0500
    +++ b/packaging/debian/libgplugin-gtk-bin.install Tue Jan 22 22:50:20 2019 -0600
    @@ -1,2 +1,2 @@
    -usr/bin/gplugin-gtk-viewer
    -usr/share/man/man1/gplugin-gtk-viewer.1
    +debian/tmp/usr/bin/gplugin-gtk-viewer
    +debian/tmp/usr/share/man/man1/gplugin-gtk-viewer.1
    --- a/packaging/debian/libgplugin-gtk-dev.install Mon Apr 18 22:32:13 2016 -0500
    +++ b/packaging/debian/libgplugin-gtk-dev.install Tue Jan 22 22:50:20 2019 -0600
    @@ -1,5 +1,4 @@
    -#!/usr/bin/dh-exec
    usr/include/gplugin-1.0/gplugin-gtk
    usr/include/gplugin-1.0/gplugin-gtk.h
    -usr/lib/${DEB_HOST_MULTIARCH}/libgplugin-gtk.so
    -usr/lib/${DEB_HOST_MULTIARCH}/pkgconfig/gplugin-gtk.pc
    +debian/tmp/usr/lib/*/libgplugin-gtk.so
    +debian/tmp/usr/lib/*/pkgconfig/gplugin-gtk.pc
    --- a/packaging/debian/libgplugin-gtk0.install Mon Apr 18 22:32:13 2016 -0500
    +++ b/packaging/debian/libgplugin-gtk0.install Tue Jan 22 22:50:20 2019 -0600
    @@ -1,2 +1,1 @@
    -#!/usr/bin/dh-exec
    -usr/lib/${DEB_HOST_MULTIARCH}/libgplugin-gtk.so.*
    +debian/tmp/usr/lib/*/libgplugin-gtk.so.*
    --- a/packaging/debian/libgplugin-gtk0.postinst Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,11 +0,0 @@
    -#!/bin/sh
    -
    -set -e
    -
    -if [ "$1" = "configure" ]; then
    - ldconfig
    -fi
    -
    -#DEBHELPER#
    -
    -exit 0
    --- a/packaging/debian/libgplugin-gtk0.postrm Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,11 +0,0 @@
    -#!/bin/sh
    -
    -set -e
    -
    -if [ "$1" = "remove" ] ; then
    - ldconfig
    -fi
    -
    -#DEBHELPER#
    -
    -exit 0
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/packaging/debian/libgplugin-gtk0.triggers Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,1 @@
    +activate-noawait ldconfig
    --- a/packaging/debian/libgplugin-lua.install Mon Apr 18 22:32:13 2016 -0500
    +++ b/packaging/debian/libgplugin-lua.install Tue Jan 22 22:50:20 2019 -0600
    @@ -1,2 +1,1 @@
    -#!/usr/bin/dh-exec
    -usr/lib/${DEB_HOST_MULTIARCH}/gplugin/gplugin-lua.so
    +debian/tmp/usr/lib/*/gplugin/gplugin-lua.so
    --- a/packaging/debian/libgplugin-python.install Mon Apr 18 22:32:13 2016 -0500
    +++ b/packaging/debian/libgplugin-python.install Tue Jan 22 22:50:20 2019 -0600
    @@ -1,2 +1,1 @@
    -#!/usr/bin/dh-exec
    -usr/lib/${DEB_HOST_MULTIARCH}/gplugin/gplugin-python.so
    +debian/tmp/usr/lib/*/gplugin/gplugin-python.so
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/packaging/debian/libgplugin0-bin.install Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,2 @@
    +debian/tmp/usr/bin/gplugin-query
    +debian/tmp/usr/share/man/man1/gplugin-query.1
    --- a/packaging/debian/libgplugin0.install Mon Apr 18 22:32:13 2016 -0500
    +++ b/packaging/debian/libgplugin0.install Tue Jan 22 22:50:20 2019 -0600
    @@ -1,4 +1,1 @@
    -#!/usr/bin/dh-exec
    -usr/lib/${DEB_HOST_MULTIARCH}/libgplugin.so.*
    -usr/bin/gplugin-query
    -usr/share/man/man1/gplugin-query.1
    +debian/tmp/usr/lib/*/libgplugin.so.*
    --- a/packaging/debian/libgplugin0.postinst Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,7 +0,0 @@
    -#/bin/sh
    -
    -set -e
    -
    -#DEBHELPER#
    -
    -exit 0
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/packaging/debian/libgplugin0.triggers Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,1 @@
    +activate-noawait ldconfig
    --- a/packaging/debian/rules Mon Apr 18 22:32:13 2016 -0500
    +++ b/packaging/debian/rules Tue Jan 22 22:50:20 2019 -0600
    @@ -1,5 +1,33 @@
    #!/usr/bin/make -f
    +export DH_VERBOSE = 1
    +export DEB_BUILD_MAINT_OPTIONS = hardening=+all
    +
    +export ARTIFACTS_DIR ?= ..
    +
    +BUILD_DIR := debian/build
    +
    %:
    - dh $@
    + dh $@ --with gir
    +
    +override_dh_auto_clean:
    + rm -rf $(BUILD_DIR)
    +
    +override_dh_auto_configure:
    + mkdir -p $(BUILD_DIR)
    + meson --prefix /usr --warnlevel 3 $(BUILD_DIR)
    +
    +override_dh_auto_build:
    + ninja -v -C $(BUILD_DIR)
    +override_dh_auto_test:
    + ninja -v -C $(BUILD_DIR) test
    +
    +override_dh_auto_install:
    + DESTDIR=$(CURDIR)/debian/tmp ninja -v -C $(BUILD_DIR) install
    +
    +override_dh_builddeb:
    + # copy the dsc and the tar file to the uploads dir
    + cp ../gplugin_*.dsc ../gplugin_*.tar.* $(ARTIFACTS_DIR)
    + dh_builddeb $@ --destdir=$(ARTIFACTS_DIR)
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/packaging/gplugin.spec.in Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,228 @@
    +Name: gplugin
    +Version: @GPLUGIN_MAJOR_VERSION@.@GPLUGIN_MINOR_VERSION@.@GPLUGIN_MICRO_VERSION@
    +%if "@GPLUGIN_EXTRA_VERSION@" == ""
    +Release: 1.%{?build_number}%{?!build_number:1}%{?dist}
    +%else
    +Release: 0.%{?build_number}%{?!build_number:1}%{?dist}
    +%endif
    +License: LGPL-2.0+
    +Summary: A GObject based library that implements a reusable plugin system
    +Url: https://bitbucket.org/rw_grim/gplugin/overview
    +Group: Development/Libraries
    +
    +BuildRequires: meson >= 0.37.0
    +BuildRequires: glib2-devel >= 2.40.0
    +BuildRequires: gobject-introspection-devel
    +BuildRequires: gettext
    +BuildRequires: gtk3-devel
    +BuildRequires: gtk-doc
    +BuildRequires: help2man
    +BuildRequires: libxslt
    +BuildRequires: lua-devel
    +BuildRequires: lua-lgi
    +BuildRequires: python3-devel
    +BuildRequires: python3-gobject
    +BuildRequires: /usr/lib64/pkgconfig/pygobject-3.0.pc
    +
    +%package -n libgplugin0
    +Summary: A GObject based library that implements a reusable plugin system
    +Group: Development/Libraries
    +
    +%package devel
    +Summary: A GObject based library that implements a reusable plugin system
    +Group: Development/Libraries
    +Requires: %{name}%{?_isa} = %{version}-%{release}
    +
    +%package gtk3
    +Summary: A GObject based library that implements a reusable plugin system
    +Group: Development/Libraries
    +
    +%package gtk3-devel
    +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
    +
    +%package python3
    +Summary: A GObject based library that implements a reusable plugin system
    +Group: Development/Libraries
    +
    +
    +%description
    +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.
    +
    +%description -n libgplugin0
    +GPlugin is a GObject based library that implements a reusable plugin system
    +that supports loading plugins in other languages via loaders. GPlugin also
    +implements dependencies among the plugins.
    +
    +It was started due to the infamous "Plugin Problem" for Guifications 3, which
    +was that I needed plugins that could depend on each other, be able to be
    +written in other languages, have plugins that are loaded before the main load
    +phase, and allow plugins to register types into the GObject type system.
    +
    +%description devel
    +GPlugin is a GObject based library that implements a reusable plugin system
    +that supports loading plugins in other languages via loaders. GPlugin also
    +implements dependencies among the plugins.
    +
    +It was started due to the infamous "Plugin Problem" for Guifications 3, which
    +was that I needed plugins that could depend on each other, be able to be
    +written in other languages, have plugins that are loaded before the main load
    +phase, and allow plugins to register types into the GObject type system.
    +
    +This package contains all necessary include files and libraries needed
    +to develop applications that require these.
    +
    +%description gtk3
    +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 additional GTK3 dependencies for %{name} library.
    +
    +%description gtk3-devel
    +GPlugin is a GObject based library that implements a reusable plugin system
    +that supports loading plugins in other languages via loaders. GPlugin also
    +implements dependencies among the plugins.
    +
    +It was started due to the infamous "Plugin Problem" for Guifications 3, which
    +was that I needed plugins that could depend on each other, be able to be
    +written in other languages, have plugins that are loaded before the main load
    +phase, and allow plugins to register types into the GObject type system.
    +
    +This package contains all necessary include files and libraries needed
    +to develop GTK3 applications that require these.
    +
    +%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
    +implements dependencies among the plugins.
    +
    +It was started due to the infamous "Plugin Problem" for Guifications 3, which
    +was that I needed plugins that could depend on each other, be able to be
    +written in other languages, have plugins that are loaded before the main load
    +phase, and allow plugins to register types into the GObject type system.
    +
    +This package contains the Lua Loader for %{name} library.
    +
    +%description python3
    +GPlugin is a GObject based library that implements a reusable plugin system
    +that supports loading plugins in other languages via loaders. GPlugin also
    +implements dependencies among the plugins.
    +
    +It was started due to the infamous "Plugin Problem" for Guifications 3, which
    +was that I needed plugins that could depend on each other, be able to be
    +written in other languages, have plugins that are loaded before the main load
    +phase, and allow plugins to register types into the GObject type system.
    +
    +This package contains Python 3 loader for %{name} library.
    +
    +
    +%build
    +mkdir -p build
    +pushd build
    +
    +CFLAGS="%{optflags}" meson \
    + --prefix=%{_prefix} \
    + -Dlua=true \
    + -Dpython=true \
    + ..
    +
    +ninja %{?_smp_mflags}
    +
    +
    +%install
    +pushd build
    +
    +DESTDIR=%{buildroot} ninja install
    +
    +# Unneeded files
    +rm -rf %{buildroot}%{_datadir}/doc/gplugin/
    +
    +%post -n libgplugin0 -p /sbin/ldconfig
    +
    +%postun -n libgplugin0 -p /sbin/ldconfig
    +
    +%post -n gplugin-gtk3 -p /sbin/ldconfig
    +
    +%postun -n gplugin-gtk3 -p /sbin/ldconfig
    +
    +
    +%files
    +%defattr(-,root,root)
    +%doc README ChangeLog
    +%{_bindir}/gplugin-query
    +%{_libdir}/gplugin/
    +%{_mandir}/man1/gplugin-query.1*
    +
    +%files -n libgplugin0
    +%defattr(-,root,root)
    +%{_libdir}/libgplugin.so.0.1.0
    +
    +%files devel
    +%defattr(-,root,root)
    +%doc HACKING INSTALL README
    +%{_includedir}/gplugin-1.0/
    +%{_libdir}/libgplugin.so
    +%{_libdir}/libgplugin.so.0
    +%{_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
    +%{_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
    +%{_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/
    +
    +%files lua
    +%defattr(-,root,root)
    +%doc README
    +%license COPYING
    +%{_libdir}/gplugin/gplugin-lua.so
    +
    +%files python3
    +%defattr(-,root,root)
    +%doc README
    +%{_libdir}/gplugin/gplugin-python.so
    +
    +
    +%changelog
    +* Sun May 15 2016 Gary Kramlich <grim@reaperworld.com>
    +- Updates and pulled upstream
    +
    +* Mon May 4 2015 Elliott Sales de Andrade <quantum.analyst@gmail.com> - 0.0.18-1
    +- Initial package release
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/packaging/meson.build Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,4 @@
    +configure_file(
    + input : 'gplugin.spec.in',
    + output : 'gplugin.spec',
    + configuration : version_conf)
    --- a/perl/CMakeLists.txt Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,54 +0,0 @@
    -option(
    - BUILD_PERL
    - "Whether or not to build the Perl plugin loader"
    - "Off"
    -)
    -
    -if(BUILD_PERL)
    - if(NOT BUILD_GIR)
    - message(FATAL_ERROR "Perl plugin requires GObject Introspection.")
    - endif(NOT BUILD_GIR)
    -
    - find_package(PerlLibs)
    -
    - if(PERLLIBS_FOUND)
    - set(GPLUGIN_PERL_SOURCES
    - gplugin-perl-core.c
    - gplugin-perl-loader.c
    - gplugin-perl-plugin.c
    - )
    -
    - set(GPLUGIN_PERL_HEADERS
    - gplugin-perl-loader.h
    - gplugin-perl-plugin.h
    - )
    -
    - add_library(gplugin-perl MODULE
    - ${GPLUGIN_PERL_SOURCES}
    - ${GPLUGIN_PERL_HEADERS}
    - )
    -
    - execute_process(COMMAND ${PERL_EXECUTABLE} -MExtUtils::Embed -e ccopts
    - OUTPUT_VARIABLE PERL_CFLAGS)
    - add_definitions(${PERL_EXTRA_C_FLAGS} ${PERL_CFLAGS})
    -
    - execute_process(COMMAND ${PERL_EXECUTABLE} -V:lddlflags
    - OUTPUT_VARIABLE PERL_LDFLAGS)
    - string(REGEX REPLACE "lddlflags='(.+)'" "\\1" PERL_LDFLAGS ${PERL_LDFLAGS})
    - string(STRIP ${PERL_LDFLAGS} PERL_LDFLAGS)
    - set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${PERL_LDFLAGS}")
    -
    - message(STATUS "PERL_CFLAGS " ${PERL_CFLAGS})
    - message(STATUS "PERL_LDFLAGS " ${PERL_LDFLAGS})
    -
    - set_target_properties(gplugin-perl PROPERTIES PREFIX "")
    -
    - include_directories(${PERL_INCLUDE_PATH})
    - target_link_libraries(gplugin-perl ${PERL_LIBRARY})
    -
    - install(TARGETS gplugin-perl DESTINATION ${CMAKE_INSTALL_LIBDIR}/gplugin)
    - else(PERLLIBS_FOUND)
    - message(FATAL_ERROR "Failed to find the Perl libraries")
    - endif(PERLLIBS_FOUND)
    -endif(BUILD_PERL)
    -
    --- a/perl/gplugin-perl-loader.c Mon Apr 18 22:32:13 2016 -0500
    +++ b/perl/gplugin-perl-loader.c Tue Jan 22 22:50:20 2019 -0600
    @@ -132,7 +132,7 @@
    * API
    *****************************************************************************/
    void
    -gplugin_perl_loader_register(GPluginNativePlugin *plugin) {
    +gplugin_perl_plugin_loader_register(GPluginNativePlugin *plugin) {
    if(g_once_init_enter(&type_real)) {
    GType type = 0;
    @@ -154,7 +154,7 @@
    }
    GType
    -gplugin_perl_loader_get_type(void) {
    +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");
    --- a/perl/gplugin-perl-plugin.c Mon Apr 18 22:32:13 2016 -0500
    +++ b/perl/gplugin-perl-plugin.c Tue Jan 22 22:50:20 2019 -0600
    @@ -30,15 +30,6 @@
    (G_TYPE_INSTANCE_GET_PRIVATE((obj), GPLUGIN_TYPE_PERL_PLUGIN, GPluginPerlPluginPrivate))
    /******************************************************************************
    - * Enums
    - *****************************************************************************/
    -enum {
    - PROP_ZERO,
    - PROP_INTERPRETER,
    - PROP_LAST,
    -};
    -
    -/******************************************************************************
    * Typedefs
    *****************************************************************************/
    typedef struct {
    @@ -46,8 +37,15 @@
    } GPluginPerlPluginPrivate;
    /******************************************************************************
    - * Globals
    + * Enums
    *****************************************************************************/
    +enum {
    + PROP_ZERO,
    + PROP_INTERPRETER,
    + N_PROPERTIES,
    +};
    +static GParamSpec *properties[N_PROPERTIES] = {NULL,};
    +
    static GObjectClass *parent_class = NULL;
    static volatile GType type_real = 0;
    @@ -122,11 +120,13 @@
    obj_class->set_property = gplugin_perl_plugin_set_property;
    obj_class->finalize = gplugin_perl_plugin_finalize;
    - g_object_class_install_property(obj_class, PROP_INTERPRETER,
    - g_param_spec_pointer("interpreter", "interpreter",
    - "The PERL interpreter for this plugin",
    - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
    - G_PARAM_STATIC_STRINGS));
    + properties[PROP_INTERPRETER] = g_param_spec_pointer(
    + "interpreter", "interpreter",
    + "The PERL interpreter for this plugin",
    + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS
    + );
    +
    + g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
    }
    /******************************************************************************
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/perl/meson.build Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,37 @@
    +if get_option('perl')
    + if not get_option('gobject-introspection')
    + error('Perl plugin requires GObject Introspection.')
    + endif
    +
    + GPLUGIN_PERL_SOURCES = [
    + 'gplugin-perl-core.c',
    + 'gplugin-perl-loader.c',
    + 'gplugin-perl-plugin.c',
    + ]
    +
    + GPLUGIN_PERL_HEADERS = [
    + 'gplugin-perl-loader.h',
    + 'gplugin-perl-plugin.h',
    + ]
    +
    + PERL = find_program('perl')
    + PERL_CFLAGS = run_command(PERL, '-MExtUtils::Embed', '-e', 'ccopts').stdout()
    + PERL_LDFLAGS = run_command(PERL, '-MExtUtils::Embed', '-e', 'ldopts').stdout()
    +
    + message('PERL_CFLAGS ' + PERL_CFLAGS)
    + message('PERL_LDFLAGS ' + PERL_LDFLAGS)
    +
    + PERL_CFLAGS = PERL_CFLAGS.split()
    + PERL_LDFLAGS = PERL_LDFLAGS.split()
    +
    + shared_library('gplugin-perl',
    + GPLUGIN_PERL_SOURCES,
    + GPLUGIN_PERL_HEADERS,
    + c_args : PERL_CFLAGS,
    + link_args : PERL_LDFLAGS,
    + name_prefix : '',
    + dependencies : [gplugin_dep],
    + install : true,
    + install_dir : join_paths(get_option('libdir'), 'gplugin')
    + )
    +endif # perl
    --- a/plugins/CMakeLists.txt Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,9 +0,0 @@
    -macro(add_plugin plugin)
    - add_library(${plugin} MODULE ${plugin}.c)
    - set_target_properties(${plugin} PROPERTIES PREFIX "")
    - target_link_libraries(${plugin} gplugin)
    - install(TARGETS ${plugin} DESTINATION ${CMAKE_INSTALL_LIBDIR}/gplugin)
    -endmacro(add_plugin)
    -
    -add_plugin(gplugin-license-check)
    -
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/plugins/meson.build Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,6 @@
    +shared_library('gplugin-license-check',
    + 'gplugin-license-check.c',
    + name_prefix : '',
    + dependencies : [gplugin_dep],
    + install : true,
    + install_dir : join_paths(get_option('libdir'), 'gplugin'))
    --- a/po/CMakeLists.txt Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,4 +0,0 @@
    -if(NLS)
    - GETTEXTIZE_TRANSLATIONS(UPDATE)
    -endif(NLS)
    -
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/po/meson.build Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,3 @@
    +if get_option('nls')
    +# GETTEXTIZE_TRANSLATIONS(UPDATE)
    +endif
    --- a/python/CMakeLists.txt Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,110 +0,0 @@
    -option(
    - BUILD_PYTHON
    - "Whether or not to build the Python 3.x plugin loader"
    - "On"
    -)
    -
    -if(BUILD_PYTHON)
    - if(NOT BUILD_GIR)
    - message(FATAL_ERROR "Python plugin requires GObject Introspection.")
    - endif(NOT BUILD_GIR)
    -
    - set(GPLUGIN_PYTHON_SOURCES
    - gplugin-python-core.c
    - gplugin-python-loader.c
    - gplugin-python-plugin.c
    - gplugin-python-utils.c
    - )
    -
    - set(GPLUGIN_PYTHON_HEADERS
    - gplugin-python-loader.h
    - gplugin-python-plugin.h
    - gplugin-python-utils.h
    - )
    -
    - pkg_check_modules(PYTHON3 REQUIRED python3)
    -
    - pkg_check_modules(PYGOBJECT REQUIRED pygobject-3.0>=3.0.0)
    -
    - include_directories(
    - ${CMAKE_CURRENT_SOURCE_DIR}
    - ${PYTHON3_INCLUDE_DIRS}
    - ${PYGOBJECT_INCLUDE_DIRS}
    - )
    -
    - message(STATUS "checking if pygobject works with python3")
    -
    - set(GPLUGIN_PYTHON_TEST_PYGOBJECT_INCLUDES)
    - foreach(INCLUDE_PATH ${GLIB_INCLUDE_DIRS} ${PYTHON3_INCLUDE_DIRS} ${PYGOBJECT_INCLUDE_DIRS})
    - set(GPLUGIN_PYTHON_TEST_PYGOBJECT_INCLUDES "${GPLUGIN_PYTHON_TEST_PYGOBJECT_INCLUDES}\;${INCLUDE_PATH}")
    - endforeach(INCLUDE_PATH)
    -
    - set(GPLUGIN_PYTHON_TEST_PYGOBJECT_LIBRARIES)
    - foreach(LIBRARY ${GLIB_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYGOBJECT_LDFLAGS})
    - set(GPLUGIN_PYTHON_TEST_PYGOBJECT_LIBRARIES "${GPLUGIN_PYTHON_TEST_PYGOBJECT_LIBRARIES}\;${LIBRARY}")
    - endforeach(LIBRARY)
    -
    - set(GPLUGIN_PYTHON_TEST_PYGOBJECT_LIBRARY_DIRS)
    - foreach(LIBRARY_DIR ${GLIB_LIBRARY_DIRS} ${PYTHON3_LIBRARY_DIRS} ${PYGOBJECT_LIBRARY_DIRS})
    - set(GPLUGIN_PYTHON_TEST_PYGOBJECT_LIBRARY_DIRS "${GPLUGIN_PYTHON_TEST_PYGOBJECT_LIBRARY_DIRS}\;${LIBRARY_DIR}")
    - endforeach(LIBRARY_DIR)
    -
    - # compile our python-gi test program
    - try_compile(PYTHON_GI_COMPILE
    - ${CMAKE_CURRENT_BINARY_DIR}
    - ${CMAKE_CURRENT_SOURCE_DIR}/gplugin-python-test-pygobject.c
    - CMAKE_FLAGS
    - -DINCLUDE_DIRECTORIES:STRING=${GPLUGIN_PYTHON_TEST_PYGOBJECT_INCLUDES}
    - -DLINK_LIBRARIES:STRING=${GPLUGIN_PYTHON_TEST_PYGOBJECT_LIBRARIES}
    - -DLINK_DIRECTORIES:STRING=${GPLUGIN_PYTHON_TEST_PYGOBJECT_LIBRARY_DIRS}
    - OUTPUT_VARIABLE OUTPUT
    - COPY_FILE ${CMAKE_CURRENT_BINARY_DIR}/gplugin-python-test-pygobject
    - )
    - if(NOT ${PYTHON_GI_COMPILE})
    - message(STATUS ${OUTPUT})
    - message(FATAL_ERROR "Failed to compile the pygobject test")
    - endif(NOT ${PYTHON_GI_COMPILE})
    -
    - # run the test program now
    - execute_process(
    - COMMAND ${CMAKE_CURRENT_BINARY_DIR}/gplugin-python-test-pygobject
    - RESULT_VARIABLE PYTHON_GI_FOUND
    - )
    - if(${PYTHON_GI_FOUND} EQUAL 0)
    - message(STATUS " pygobject works with python3")
    - else(${PYTHON_GI_FOUND} EQUAL 0)
    - message(FATAL_ERROR " pygobject does not work with python3")
    - endif(${PYTHON_GI_FOUND} EQUAL 0)
    -
    - # Now add our libraries
    - add_library(gplugin-python MODULE
    - ${GPLUGIN_PYTHON_SOURCES}
    - ${GPLUGIN_PYTHON_HEADERS}
    - )
    -
    - add_library(gplugin-python-static STATIC
    - ${GPLUGIN_PYTHON_SOURCES}
    - ${GPLUGIN_PYTHON_HEADERS}
    - )
    -
    - set_target_properties(gplugin-python PROPERTIES PREFIX "")
    -
    - target_link_libraries(gplugin-python
    - ${PYTHON3_LIBRARIES}
    - ${PYGOBJECT_LIBRARIES}
    - gplugin
    - )
    -
    - target_link_libraries(gplugin-python-static
    - ${PYTHON3_LIBRARIES}
    - ${PYGOBJECT_LIBRARIES}
    - gplugin
    - )
    -
    - install(TARGETS gplugin-python DESTINATION ${CMAKE_INSTALL_LIBDIR}/gplugin)
    -endif(BUILD_PYTHON)
    -
    -if(TESTING_ENABLED)
    - add_subdirectory(tests)
    -endif(TESTING_ENABLED)
    -
    --- a/python/gplugin-python-loader.c Mon Apr 18 22:32:13 2016 -0500
    +++ b/python/gplugin-python-loader.c Tue Jan 22 22:50:20 2019 -0600
    @@ -28,25 +28,21 @@
    #include <pygobject.h>
    -#define GPLUGIN_PYTHON_LOADER_GET_PRIVATE(obj) \
    - (G_TYPE_INSTANCE_GET_PRIVATE((obj), GPLUGIN_TYPE_PYTHON_LOADER, GPluginPythonLoaderPrivate))
    -
    -/******************************************************************************
    - * Typedefs
    - *****************************************************************************/
    typedef struct {
    PyThreadState *py_thread_state;
    guint gc_id;
    } GPluginPythonLoaderPrivate;
    -/******************************************************************************
    - * Globals
    - *****************************************************************************/
    -static GObjectClass *parent_class = NULL;
    -static GType type_real = 0;
    +G_DEFINE_DYNAMIC_TYPE_EXTENDED(
    + GPluginPythonLoader,
    + gplugin_python_loader,
    + GPLUGIN_TYPE_LOADER,
    + 0,
    + G_ADD_PRIVATE_DYNAMIC(GPluginPythonLoader)
    +);
    /******************************************************************************
    - * GPluginLoaderInterface API
    + * GPluginLoader Implementation
    *****************************************************************************/
    static GSList *
    gplugin_python_loader_class_supported_extensions(GPLUGIN_UNUSED const GPluginLoaderClass *klass) {
    @@ -325,11 +321,14 @@
    len = mbstowcs(argv[0], program, len + 1);
    if(len == (size_t)-1) {
    g_warning("Could not convert program name to wchar_t string.");
    +
    + g_free(argv[0]);
    +
    return FALSE;
    }
    /* setup sys.path according to
    - * http://docs.python.org/3/c-api/init.html#PySys_SetArgvEx
    + * https://docs.python.org/3/c-api/init.html#PySys_SetArgvEx
    */
    #if PY_VERSION_HEX < 0x03010300
    PySys_SetArgv(1, argv);
    @@ -354,26 +353,16 @@
    * Object Stuff
    *****************************************************************************/
    static void
    -gplugin_python_loader_finalize(GObject *obj) {
    -#if 0
    - GPluginPythonLoaderPrivate *priv =
    - GPLUGIN_PYTHON_LOADER_GET_PRIVATE(obj);
    -#endif
    +gplugin_python_loader_init(GPluginPythonLoader *loader) {
    +}
    - G_OBJECT_CLASS(parent_class)->finalize(obj);
    +static void
    +gplugin_python_loader_class_finalize(GPluginPythonLoaderClass *klass) {
    }
    static void
    gplugin_python_loader_class_init(GPluginPythonLoaderClass *klass) {
    - GObjectClass *obj_class = G_OBJECT_CLASS(klass);
    - GPluginLoaderClass *loader_class =
    - GPLUGIN_LOADER_CLASS(klass);
    -
    - parent_class = g_type_class_peek_parent(klass);
    -
    - g_type_class_add_private(klass, sizeof(GPluginPythonLoaderPrivate));
    -
    - obj_class->finalize = gplugin_python_loader_finalize;
    + GPluginLoaderClass *loader_class = GPLUGIN_LOADER_CLASS(klass);
    loader_class->supported_extensions =
    gplugin_python_loader_class_supported_extensions;
    @@ -386,35 +375,9 @@
    * API
    *****************************************************************************/
    void
    -gplugin_python_loader_register(GPluginNativePlugin *plugin) {
    - if(g_once_init_enter(&type_real)) {
    - GType type = 0;
    -
    - static const GTypeInfo info = {
    - .class_size = sizeof(GPluginPythonLoaderClass),
    - .class_init = (GClassInitFunc)gplugin_python_loader_class_init,
    - .instance_size = sizeof(GPluginPythonLoader),
    - };
    +gplugin_python_loader_register(GPluginNativePlugin *native) {
    + gplugin_python_loader_register_type(G_TYPE_MODULE(native));
    - type = gplugin_native_plugin_register_type(plugin,
    - GPLUGIN_TYPE_LOADER,
    - "GPluginPythonLoader",
    - &info,
    - 0);
    -
    - gplugin_python_loader_init_python();
    -
    - g_once_init_leave(&type_real, type);
    - }
    + gplugin_python_loader_init_python();
    }
    -GType
    -gplugin_python_loader_get_type(void) {
    - if(G_UNLIKELY(type_real == 0)) {
    - g_warning("gplugin_python_loader_get_type was called before "
    - "the type was registered!\n");
    - }
    -
    - return type_real;
    -}
    -
    --- a/python/gplugin-python-loader.h Mon Apr 18 22:32:13 2016 -0500
    +++ b/python/gplugin-python-loader.h Tue Jan 22 22:50:20 2019 -0600
    @@ -32,26 +32,22 @@
    #include <gplugin-native.h>
    struct _GPluginPythonLoader {
    + /*< private >*/
    GPluginLoader parent;
    - void (*_gplugin_reserved_1)(void);
    - void (*_gplugin_reserved_2)(void);
    - void (*_gplugin_reserved_3)(void);
    - void (*_gplugin_reserved_4)(void);
    + gpointer reserved[4];
    };
    struct _GPluginPythonLoaderClass {
    + /*< private >*/
    GPluginLoaderClass parent;
    - 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
    -void gplugin_python_loader_register(GPluginNativePlugin *plugin);
    +void gplugin_python_loader_register(GPluginNativePlugin *native);
    GType gplugin_python_loader_get_type(void);
    G_END_DECLS
    --- a/python/gplugin-python-plugin.c Mon Apr 18 22:32:13 2016 -0500
    +++ b/python/gplugin-python-plugin.c Tue Jan 22 22:50:20 2019 -0600
    @@ -21,9 +21,6 @@
    #include <pygobject.h>
    -#define GPLUGIN_PYTHON_PLUGIN_GET_PRIVATE(obj) \
    - (G_TYPE_INSTANCE_GET_PRIVATE((obj), GPLUGIN_TYPE_PYTHON_PLUGIN, GPluginPythonPluginPrivate))
    -
    /******************************************************************************
    * Typedefs
    *****************************************************************************/
    @@ -32,6 +29,12 @@
    PyObject *query;
    PyObject *load;
    PyObject *unload;
    +
    + /* overrides */
    + gchar *filename;
    + GPluginLoader *loader;
    + GPluginPluginInfo *info;
    + GPluginPluginState state;
    } GPluginPythonPluginPrivate;
    /******************************************************************************
    @@ -42,25 +45,44 @@
    PROP_MODULE,
    PROP_LOAD_FUNC,
    PROP_UNLOAD_FUNC,
    - PROP_LAST,
    + N_PROPERTIES,
    + /* overrides */
    + PROP_FILENAME = N_PROPERTIES,
    + PROP_LOADER,
    + PROP_INFO,
    + PROP_STATE
    };
    +static GParamSpec *properties[N_PROPERTIES] = {NULL,};
    +
    +/* I hate forward declarations... */
    +static void gplugin_python_plugin_iface_init(GPluginPluginInterface *iface);
    +
    +G_DEFINE_DYNAMIC_TYPE_EXTENDED(
    + GPluginPythonPlugin,
    + gplugin_python_plugin,
    + G_TYPE_OBJECT,
    + 0,
    + G_ADD_PRIVATE_DYNAMIC(GPluginPythonPlugin)
    + G_IMPLEMENT_INTERFACE(GPLUGIN_TYPE_PLUGIN, gplugin_python_plugin_iface_init)
    +);
    /******************************************************************************
    - * Globals
    + * GPluginPlugin Implementation
    *****************************************************************************/
    -static GObjectClass *parent_class = NULL;
    -static GType type_real = 0;
    +static void
    +gplugin_python_plugin_iface_init(GPluginPluginInterface *iface) {
    +}
    /******************************************************************************
    * Private Stuff
    *****************************************************************************/
    static PyObject *
    -gplugin_python_plugin_get_module(const GPluginPythonPlugin *plugin) {
    +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_PRIVATE(plugin);
    + priv = gplugin_python_plugin_get_instance_private(plugin);
    return priv->module;
    }
    @@ -74,7 +96,7 @@
    g_return_if_fail(GPLUGIN_IS_PLUGIN(plugin));
    g_return_if_fail(module);
    - priv = GPLUGIN_PYTHON_PLUGIN_GET_PRIVATE(plugin);
    + priv = gplugin_python_plugin_get_instance_private(plugin);
    if(priv->module)
    Py_DECREF(priv->module);
    @@ -86,12 +108,12 @@
    }
    static gpointer
    -gplugin_python_plugin_get_load_func(const GPluginPythonPlugin *plugin) {
    +gplugin_python_plugin_get_load_func(GPluginPythonPlugin *plugin) {
    GPluginPythonPluginPrivate *priv = NULL;
    g_return_val_if_fail(GPLUGIN_IS_PYTHON_PLUGIN(plugin), NULL);
    - priv = GPLUGIN_PYTHON_PLUGIN_GET_PRIVATE(plugin);
    + priv = gplugin_python_plugin_get_instance_private(plugin);
    return priv->load;
    }
    @@ -105,7 +127,7 @@
    g_return_if_fail(GPLUGIN_IS_PYTHON_PLUGIN(plugin));
    g_return_if_fail(func != NULL);
    - priv = GPLUGIN_PYTHON_PLUGIN_GET_PRIVATE(plugin);
    + priv = gplugin_python_plugin_get_instance_private(plugin);
    if(priv->load)
    Py_DECREF(priv->load);
    @@ -116,12 +138,12 @@
    }
    static gpointer
    -gplugin_python_plugin_get_unload_func(const GPluginPythonPlugin *plugin) {
    +gplugin_python_plugin_get_unload_func(GPluginPythonPlugin *plugin) {
    GPluginPythonPluginPrivate *priv = NULL;
    g_return_val_if_fail(GPLUGIN_IS_PYTHON_PLUGIN(plugin), NULL);
    - priv = GPLUGIN_PYTHON_PLUGIN_GET_PRIVATE(plugin);
    + priv = gplugin_python_plugin_get_instance_private(plugin);
    return priv->unload;
    }
    @@ -135,7 +157,7 @@
    g_return_if_fail(GPLUGIN_IS_PYTHON_PLUGIN(plugin));
    g_return_if_fail(func != NULL);
    - priv = GPLUGIN_PYTHON_PLUGIN_GET_PRIVATE(plugin);
    + priv = gplugin_python_plugin_get_instance_private(plugin);
    if(priv->unload)
    Py_DECREF(priv->unload);
    @@ -153,6 +175,7 @@
    GParamSpec *pspec)
    {
    GPluginPythonPlugin *plugin = GPLUGIN_PYTHON_PLUGIN(obj);
    + GPluginPythonPluginPrivate *priv = gplugin_python_plugin_get_instance_private(plugin);
    switch(param_id) {
    case PROP_MODULE:
    @@ -167,6 +190,21 @@
    g_value_set_pointer(value,
    gplugin_python_plugin_get_unload_func(plugin));
    break;
    +
    + /* overrides */
    + case PROP_FILENAME:
    + g_value_set_string(value, priv->filename);
    + break;
    + case PROP_LOADER:
    + g_value_set_object(value, priv->loader);
    + break;
    + case PROP_INFO:
    + g_value_set_object(value, priv->info);
    + break;
    + case PROP_STATE:
    + g_value_set_enum(value, priv->state);
    + break;
    +
    default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
    break;
    @@ -178,6 +216,7 @@
    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:
    @@ -192,6 +231,21 @@
    gplugin_python_plugin_set_unload_func(plugin,
    g_value_get_pointer(value));
    break;
    +
    + /* overrides */
    + case PROP_FILENAME:
    + priv->filename = g_strdup(g_value_get_string(value));
    + break;
    + case PROP_LOADER:
    + priv->loader = g_object_ref(g_value_get_object(value));
    + break;
    + case PROP_INFO:
    + priv->info = g_object_ref(g_value_get_object(value));
    + break;
    + case PROP_STATE:
    + priv->state = g_value_get_enum(value);
    + break;
    +
    default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
    break;
    @@ -200,8 +254,7 @@
    static void
    gplugin_python_plugin_finalize(GObject *obj) {
    - GPluginPythonPluginPrivate *priv =
    - GPLUGIN_PYTHON_PLUGIN_GET_PRIVATE(obj);
    + GPluginPythonPluginPrivate *priv = gplugin_python_plugin_get_instance_private(GPLUGIN_PYTHON_PLUGIN(obj));
    if(priv->module)
    Py_DECREF(priv->module);
    @@ -210,68 +263,60 @@
    if(priv->unload)
    Py_DECREF(priv->unload);
    - G_OBJECT_CLASS(parent_class)->finalize(obj);
    + g_free(priv->filename);
    + g_object_unref(G_OBJECT(priv->loader));
    + g_object_unref(G_OBJECT(priv->info));
    +
    + G_OBJECT_CLASS(gplugin_python_plugin_parent_class)->finalize(obj);
    +}
    +
    +static void
    +gplugin_python_plugin_init(GPluginPythonPlugin *plugin) {
    +}
    +
    +static void
    +gplugin_python_plugin_class_finalize(GPluginPythonPluginClass *klass) {
    }
    static void
    gplugin_python_plugin_class_init(GPluginPythonPluginClass *klass) {
    GObjectClass *obj_class = G_OBJECT_CLASS(klass);
    - parent_class = g_type_class_peek_parent(klass);
    -
    - g_type_class_add_private(klass, sizeof(GPluginPythonPluginPrivate));
    -
    obj_class->get_property = gplugin_python_plugin_get_property;
    obj_class->set_property = gplugin_python_plugin_set_property;
    obj_class->finalize = gplugin_python_plugin_finalize;
    - g_object_class_install_property(obj_class, PROP_MODULE,
    - g_param_spec_pointer("module", "module",
    - "The python module object",
    - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
    + properties[PROP_MODULE] = g_param_spec_pointer(
    + "module", "module",
    + "The python module object",
    + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
    + );
    +
    + properties[PROP_LOAD_FUNC] = g_param_spec_pointer(
    + "load-func", "load-func",
    + "The python load function",
    + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
    + );
    - g_object_class_install_property(obj_class, PROP_LOAD_FUNC,
    - g_param_spec_pointer("load-func", "load-func",
    - "The python load function",
    - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
    + properties[PROP_UNLOAD_FUNC] = g_param_spec_pointer(
    + "unload-func", "unload-func",
    + "The python unload function",
    + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
    + );
    - g_object_class_install_property(obj_class, PROP_UNLOAD_FUNC,
    - g_param_spec_pointer("unload-func", "unload-func",
    - "The python unload function",
    - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
    + g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
    +
    + /* add our overrides */
    + g_object_class_override_property(obj_class, PROP_FILENAME, "filename");
    + g_object_class_override_property(obj_class, PROP_LOADER, "loader");
    + g_object_class_override_property(obj_class, PROP_INFO, "info");
    + g_object_class_override_property(obj_class, PROP_STATE, "state");
    }
    /******************************************************************************
    * API
    *****************************************************************************/
    void
    -gplugin_python_plugin_register(GPluginNativePlugin *plugin) {
    - if(g_once_init_enter(&type_real)) {
    - GType type = 0;
    -
    - static const GTypeInfo info = {
    - .class_size = sizeof(GPluginPythonPluginClass),
    - .class_init = (GClassInitFunc)gplugin_python_plugin_class_init,
    - .instance_size = sizeof(GPluginPythonPlugin),
    - };
    -
    - type = gplugin_native_plugin_register_type(plugin,
    - GPLUGIN_TYPE_PLUGIN,
    - "GPluginPythonPlugin",
    - &info,
    - 0);
    -
    - g_once_init_leave(&type_real, type);
    - }
    +gplugin_python_plugin_register(GPluginNativePlugin *native) {
    + gplugin_python_plugin_register_type(G_TYPE_MODULE(native));
    }
    -
    -GType
    -gplugin_python_plugin_get_type(void) {
    - if(G_UNLIKELY(type_real == 0)) {
    - g_warning("gplugin_python_plugin_get_type was called before "
    - "the type was registered!\n");
    - }
    -
    - return type_real;
    -}
    -
    --- a/python/gplugin-python-plugin.h Mon Apr 18 22:32:13 2016 -0500
    +++ b/python/gplugin-python-plugin.h Tue Jan 22 22:50:20 2019 -0600
    @@ -32,21 +32,22 @@
    #include <gplugin-native.h>
    struct _GPluginPythonPlugin {
    - GPluginPlugin parent;
    + /*< private >*/
    + GObject parent;
    +
    + gpointer reserved[4];
    };
    struct _GPluginPythonPluginClass {
    - GPluginPluginClass parent;
    + /*< private >*/
    + GObjectClass parent;
    - 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
    -void gplugin_python_plugin_register(GPluginNativePlugin *plugin);
    +void gplugin_python_plugin_register(GPluginNativePlugin *native);
    GType gplugin_python_plugin_get_type(void);
    G_END_DECLS
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/python/meson.build Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,57 @@
    +if get_option('python')
    + if not get_option('gobject-introspection')
    + error('Python plugin requires GObject Introspection.')
    + endif
    +
    + GPLUGIN_PYTHON_SOURCES = [
    + 'gplugin-python-core.c',
    + 'gplugin-python-loader.c',
    + 'gplugin-python-plugin.c',
    + 'gplugin-python-utils.c',
    + ]
    +
    + GPLUGIN_PYTHON_HEADERS = [
    + 'gplugin-python-loader.h',
    + 'gplugin-python-plugin.h',
    + 'gplugin-python-utils.h',
    + ]
    +
    + PYTHON3 = dependency('python3')
    +
    + PYGOBJECT = dependency('pygobject-3.0', version : '>=3.0.0')
    +
    + # Compile and run our python-gi test program
    + python_gi_test = compiler.run(files('gplugin-python-test-pygobject.c'),
    + dependencies : [GLIB, PYTHON3, PYGOBJECT],
    + name : 'Python GI')
    + if not python_gi_test.compiled() or python_gi_test.returncode() != 0
    + error('pygobject does not work with python3')
    + endif
    +
    + # Now add our libraries
    + gplugin_python_inc = include_directories('.')
    + gplugin_python = shared_library('gplugin-python',
    + GPLUGIN_PYTHON_SOURCES,
    + GPLUGIN_PYTHON_HEADERS,
    + name_prefix : '',
    + dependencies : [PYTHON3, PYGOBJECT, gplugin_dep],
    + install : true,
    + install_dir : join_paths(get_option('libdir'), 'gplugin')
    + )
    + gplugin_python_dep = declare_dependency(
    + include_directories : gplugin_python_inc,
    + link_with : gplugin_python,
    + )
    +
    + gplugin_python_static = static_library('gplugin-python-static',
    + GPLUGIN_PYTHON_SOURCES,
    + GPLUGIN_PYTHON_HEADERS,
    + dependencies : [PYTHON3, PYGOBJECT, gplugin_dep],
    + )
    + gplugin_python_static_dep = declare_dependency(
    + include_directories : gplugin_python_inc,
    + link_with : gplugin_python_static,
    + )
    +endif # python
    +
    +subdir('tests')
    --- a/python/tests/CMakeLists.txt Mon Apr 18 22:32:13 2016 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,65 +0,0 @@
    -if(BUILD_PYTHON)
    -
    -macro(add_python_gtest target)
    - add_executable(${target} ${target}.c)
    - target_link_libraries(${target}
    - ${GLIB_LIBRARIES} ${PYTHON3_LIBRARIES} ${PYGOBJECT_LIBRARIES} gplugin)
    - add_dependencies(${target} gplugin-python)
    -
    - get_target_property(_output_name ${target} RUNTIME_OUTPUT_NAME)
    - if(NOT ${_output_name})
    - get_target_property(_output_name ${target} LOCATION)
    - endif(NOT ${_output_name})
    -
    - list(APPEND PYTHON_TESTS ${_output_name})
    -
    - set_property(TARGET ${target} APPEND PROPERTY COMPILE_DEFINITIONS
    - PYTHON_LOADER_DIR="${CMAKE_BINARY_DIR}/python"
    - PYTHON_PLUGIN_DIR="${CMAKE_CURRENT_SOURCE_DIR}/plugins"
    - )
    -
    - set_property(TARGET ${target} APPEND PROPERTY INCLUDE_DIRECTORIES
    - "${CMAKE_SOURCE_DIR}/python"
    - ${PYTHON3_INCLUDE_DIRS}
    - ${PYGOBJECT_INCLUDE_DIRS}
    - )
    -endmacro(add_python_gtest)
    -
    -list(APPEND GPLUGIN_PYTHON_LOADER gplugin-python)
    -
    -add_python_gtest(test-python-loader)
    -target_link_libraries(test-python-loader gplugin-loader-tests)
    -
    -# we can't see the symbols in gplugin-python externally, so use the static
    -# version for testing
    -add_python_gtest(test-python-utils)
    -add_dependencies(test-python-utils gplugin-python-static)
    -target_link_libraries(test-python-utils gplugin-python-static)
    -
    -set(GTESTER_PYTHON_TESTS "${PYTHON_TESTS}")
    -set(GTESTER_PYTHON_LOG "test-gplugin-python.xml")
    -set(GTESTER_PYTHON_JUNIT "test-gplugin-python-junit.xml")
    -
    -add_custom_command(
    - COMMAND ${GTESTER} -k --verbose -o ${GTESTER_PYTHON_LOG} ${PYTHON_TESTS}
    - OUTPUT ${GTESTER_PYTHON_LOG}
    - DEPENDS gplugin ${GPLUGIN_GIR_TARGETS} ${GPLUGIN_PYTHON_LOADER}
    - ${PYTHON_TESTS} ${CMAKE_CURRENT_SOURCE_DIR}/plugins
    - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
    -)
    -
    -add_custom_command(
    - COMMAND ${XSLTPROC} -o ${GTESTER_PYTHON_JUNIT} --nonet
    - ${CMAKE_SOURCE_DIR}/xsl/gtester-junit.xsl
    - ${GTESTER_PYTHON_LOG}
    - OUTPUT ${GTESTER_PYTHON_JUNIT}
    - DEPENDS ${GTESTER_PYTHON_LOG}
    - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
    -)
    -
    -add_custom_target(python-tests ALL
    - DEPENDS ${GTESTER_PYTHON_LOG} ${GTESTER_PYTHON_JUNIT} ${PYTHON_TESTS}
    -)
    -
    -endif(BUILD_PYTHON)
    -
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/python/tests/meson.build Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,26 @@
    +if get_option('python')
    +
    +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_PLUGIN_DIR="@0@/plugins"'.format(meson.current_source_dir()),
    + ],
    + link_with : gplugin_loader_tests,
    + dependencies : [GLIB, GOBJECT, PYTHON3, PYGOBJECT, gplugin_dep])
    +test('Python loader', e)
    +
    +# we can't see the symbols in gplugin-python externally, so use the static
    +# version for testing
    +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_PLUGIN_DIR="@0@/plugins"'.format(meson.current_source_dir()),
    + ],
    + link_with : [gplugin_loader_tests],
    + dependencies : [GLIB, GOBJECT, PYTHON3, PYGOBJECT,
    + gplugin_python_static_dep])
    +test('Python utils', e)
    +
    +endif # python
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/tcc/gplugin-tcc-core.c Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,67 @@
    +/*
    + * 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.h>
    +#include <gplugin-native.h>
    +
    +#include "gplugin-tcc-loader.h"
    +#include "gplugin-tcc-plugin.h"
    +
    +
    +G_MODULE_EXPORT GPluginPluginInfo *
    +gplugin_query(GPLUGIN_UNUSED GError **error) {
    + const gchar * const authors[] = {
    + "Eion Robb <eion@robbmob.com>",
    + NULL
    + };
    +
    + return gplugin_plugin_info_new(
    + "gplugin/tcc-loader",
    + GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
    + "internal", TRUE,
    + "load-on-query", TRUE,
    + "name", "C source plugin loader",
    + "version", GPLUGIN_VERSION,
    + "license-id", "LGPL2",
    + "summary", "A plugin that can load C source plugins",
    + "description", "This plugin allows the loading of plugins written in C.",
    + "authors", authors,
    + "website", GPLUGIN_WEBSITE,
    + "category", "loaders",
    + NULL
    + );
    +}
    +
    +G_MODULE_EXPORT gboolean
    +gplugin_load(GPluginNativePlugin *plugin,
    + GPLUGIN_UNUSED GError **error)
    +{
    + gplugin_tcc_loader_register(plugin);
    + gplugin_tcc_plugin_register(plugin);
    +
    + gplugin_manager_register_loader(gplugin_tcc_loader_get_type());
    +
    + return TRUE;
    +}
    +
    +G_MODULE_EXPORT gboolean
    +gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    + GPLUGIN_UNUSED GError **error)
    +{
    + return FALSE;
    +}
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/tcc/gplugin-tcc-loader.c Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,203 @@
    +/*
    + * 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-tcc-loader.h"
    +
    +#include "gplugin-tcc-plugin.h"
    +
    +#include <glib/gi18n.h>
    +
    +#include <libtcc.h>
    +
    +/******************************************************************************
    + * Globals
    + *****************************************************************************/
    +static GObjectClass *parent_class = NULL;
    +static GType type_real = 0;
    +
    +/******************************************************************************
    + * GPluginLoaderInterface API
    + *****************************************************************************/
    +static GSList *
    +gplugin_tcc_loader_class_supported_extensions(GPLUGIN_UNUSED const GPluginLoaderClass *klass) {
    + GSList *exts = NULL;
    +
    + exts = g_slist_append(exts, "c");
    +
    + return exts;
    +}
    +
    +static GPluginPlugin *
    +gplugin_tcc_loader_query(GPluginLoader *loader, const gchar *filename,
    + GError **error)
    +{
    + GPluginPlugin *plugin = NULL;
    + GPluginPluginInfo *info = NULL;
    + TCCState *s = NULL;
    + gpointer memneeded = NULL;
    + int memsize = -1;
    +
    + GPluginTccPluginQueryFunc gplugin_query = NULL;
    +
    + s = tcc_new();
    +
    + 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);
    +
    + tcc_delete(s);
    +
    + return NULL;
    + }
    +
    + /* 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");
    +
    + tcc_delete(s);
    + return NULL;
    + }
    +
    + 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");
    +
    + tcc_delete(s);
    + g_free(memneeded);
    + return NULL;
    + }
    +
    + 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");
    +
    + tcc_delete(s);
    + g_free(memneeded);
    + return NULL;
    + }
    +
    + info = gplugin_query(error);
    + if(info == NULL) {
    + tcc_delete(s);
    + g_free(memneeded);
    + return NULL;
    + }
    +
    + plugin = g_object_new(GPLUGIN_TYPE_TCC_PLUGIN,
    + "filename", filename,
    + "loader", loader,
    + "state", s,
    + "memory", memneeded,
    + "info", info,
    + NULL);
    +
    + return plugin;
    +}
    +
    +static gboolean
    +gplugin_tcc_loader_load(GPLUGIN_UNUSED GPluginLoader *loader,
    + GPluginPlugin *plugin,
    + GError **error)
    +{
    + GPluginTccPluginLoadFunc gplugin_load = NULL;
    + TCCState *s = gplugin_tcc_plugin_get_state(GPLUGIN_TCC_PLUGIN(plugin));
    +
    + gplugin_load = (GPluginTccPluginLoadFunc) tcc_get_symbol(s, "gplugin_load");
    + if (gplugin_load == NULL) {
    + if(error)
    + *error = g_error_new(GPLUGIN_DOMAIN, 0, "no gplugin_load function found");
    +
    + return FALSE;
    + }
    +
    + return gplugin_load(GPLUGIN_NATIVE_PLUGIN(plugin), error);
    +}
    +
    +static gboolean
    +gplugin_tcc_loader_unload(GPLUGIN_UNUSED GPluginLoader *loader,
    + GPluginPlugin *plugin,
    + GError **error)
    +{
    + GPluginTccPluginLoadFunc gplugin_unload = NULL;
    + TCCState *s = gplugin_tcc_plugin_get_state(GPLUGIN_TCC_PLUGIN(plugin));
    +
    + gplugin_unload = (GPluginTccPluginUnloadFunc) tcc_get_symbol(s, "gplugin_unload");
    + if (gplugin_unload == NULL) {
    + if(error)
    + *error = g_error_new(GPLUGIN_DOMAIN, 0, "no gplugin_unload function found");
    +
    + return FALSE;
    + }
    +
    + return gplugin_unload(GPLUGIN_NATIVE_PLUGIN(plugin), error);
    +}
    +
    +/******************************************************************************
    + * GObject Stuff
    + *****************************************************************************/
    +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;
    + loader_class->load = gplugin_tcc_loader_load;
    + loader_class->unload = gplugin_tcc_loader_unload;
    +}
    +
    +/******************************************************************************
    + * API
    + *****************************************************************************/
    +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);
    + }
    +}
    +
    +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;
    +}
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/tcc/gplugin-tcc-loader.h Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,59 @@
    +/*
    + * 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_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
    +
    +void gplugin_tcc_loader_register(GPluginNativePlugin *plugin);
    +GType gplugin_tcc_loader_get_type(void);
    +
    +G_END_DECLS
    +
    +#endif /* GPLUGIN_TCC_LOADER_H */
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/tcc/gplugin-tcc-plugin.c Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,185 @@
    +/*
    + * 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-tcc-plugin.h"
    +
    +#include <libtcc.h>
    +
    +#define GPLUGIN_TCC_PLUGIN_GET_PRIVATE(obj) \
    + (G_TYPE_INSTANCE_GET_PRIVATE((obj), GPLUGIN_TYPE_TCC_PLUGIN, GPluginTccPluginPrivate))
    +
    +/******************************************************************************
    + * Typedefs
    + *****************************************************************************/
    +typedef struct {
    + TCCState *s;
    + gpointer mem;
    +} GPluginTccPluginPrivate;
    +
    +/******************************************************************************
    + * Enums
    + *****************************************************************************/
    +enum {
    + PROP_ZERO,
    + PROP_STATE,
    + PROP_MEM,
    + N_PROPERTIES,
    +};
    +static GParamSpec *properties[N_PROPERTIES] = {NULL,};
    +
    +static GObjectClass *parent_class = NULL;
    +static GType type_real = 0;
    +
    +/******************************************************************************
    + * Private Stuff
    + *****************************************************************************/
    +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;
    +}
    +
    +/******************************************************************************
    + * Object Stuff
    + *****************************************************************************/
    +static void
    +gplugin_tcc_plugin_get_property(GObject *obj, guint param_id, GValue *value,
    + GParamSpec *pspec)
    +{
    + GPluginTccPlugin *plugin = GPLUGIN_TCC_PLUGIN(obj);
    +
    + switch(param_id) {
    + case PROP_STATE:
    + g_value_set_pointer(value,
    + gplugin_tcc_plugin_get_state(plugin));
    + break;
    + default:
    + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
    + break;
    + }
    +}
    +
    +static void
    +gplugin_tcc_plugin_set_property(GObject *obj, guint param_id,
    + const GValue *value, GParamSpec *pspec)
    +{
    + GPluginTccPlugin *plugin = GPLUGIN_TCC_PLUGIN(obj);
    +
    + switch(param_id) {
    + case PROP_STATE:
    + gplugin_tcc_plugin_set_state(plugin,
    + g_value_get_pointer(value));
    + break;
    + case PROP_MEM:
    + gplugin_tcc_plugin_set_memory(plugin,
    + g_value_get_pointer(value));
    + break;
    + default:
    + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
    + break;
    + }
    +}
    +
    +static void
    +gplugin_tcc_plugin_finalize(GObject *obj) {
    + GPluginTccPluginPrivate *priv = GPLUGIN_TCC_PLUGIN_GET_PRIVATE(obj);
    +
    + if(priv->s)
    + tcc_delete(priv->s);
    +
    + if(priv->mem)
    + g_free(priv->mem);
    +
    + G_OBJECT_CLASS(parent_class)->finalize(obj);
    +}
    +
    +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",
    + "The TCC compilation context for the plugin",
    + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
    + );
    +
    + 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);
    +}
    +
    +/******************************************************************************
    + * 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;
    +}
    +
    +TCCState *
    +gplugin_tcc_plugin_get_state(const GPluginTccPlugin *plugin) {
    + GPluginTccPluginPrivate *priv = GPLUGIN_TCC_PLUGIN_GET_PRIVATE(plugin);
    +
    + return priv->s;
    +}
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/tcc/gplugin-tcc-plugin.h Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,62 @@
    +/*
    + * 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_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);
    +
    +TCCState *gplugin_tcc_plugin_get_state(const GPluginTccPlugin *plugin);
    +
    +typedef GPluginPluginInfo *(*GPluginTccPluginQueryFunc)(GError **error);
    +typedef gboolean (*GPluginTccPluginLoadFunc)(GPluginNativePlugin *plugin, GError **error);
    +typedef gboolean (*GPluginTccPluginUnloadFunc)(GPluginNativePlugin *plugin, GError **error);
    +
    +G_END_DECLS
    +
    +#endif /* GPLUGIN_TCC_PLUGIN_H */
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/tcc/meson.build Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,28 @@
    +if get_option('tcc')
    + GPLUGIN_TCC_SOURCES = [
    + 'gplugin-tcc-core.c',
    + 'gplugin-tcc-loader.c',
    + 'gplugin-tcc-plugin.c',
    + ]
    +
    + GPLUGIN_TCC_HEADERS = [
    + 'gplugin-tcc-loader.h',
    + 'gplugin-tcc-plugin.h',
    + ]
    +
    + if not compiler.has_header('libtcc.h')
    + error('LibTcc header not found')
    + endif
    + TCC = compiler.find_library('tcc')
    +
    + gplugin_tcc = shared_library('gplugin-tcc',
    + GPLUGIN_TCC_SOURCES,
    + GPLUGIN_TCC_HEADERS,
    + name_prefix : '',
    + dependencies : [TCC, gplugin_dep],
    + install : true,
    + install_dir : join_paths(get_option('libdir'), 'gplugin')
    + )
    +endif # tcc
    +
    +subdir('tests')
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/tcc/tests/meson.build Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,13 @@
    +if get_option('tcc')
    +
    +e = executable('test-tcc-loader', 'test-tcc-loader.c',
    + c_args : [
    + '-DTCC_LOADER_DIR="@0@/tcc"'.format(meson.build_root()),
    + '-DTCC_PLUGIN_DIR="@0@/plugins"'.format(
    + meson.current_source_dir()),
    + ],
    + link_with : gplugin_loader_tests,
    + dependencies : [GLIB, GOBJECT, TCC, gplugin_dep])
    +test('TCC Loader', e)
    +
    +endif # tcc
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/tcc/tests/plugins/basic-plugin.c Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,55 @@
    +/*
    + * 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.h>
    +#include <gplugin-native.h>
    +
    +G_MODULE_EXPORT GPluginPluginInfo *
    +gplugin_query(GPLUGIN_UNUSED GError **error) {
    + const gchar * const authors[] = {
    + "author1",
    + NULL
    + };
    +
    + return gplugin_plugin_info_new(
    + "gplugin/native-basic-plugin",
    + 0x01020304,
    + "name", "basic plugin",
    + "category", "test",
    + "version", "version",
    + "summary", "summary",
    + "license-id", "license",
    + "description", "description",
    + "authors", authors,
    + "website", "website",
    + NULL
    + );
    +}
    +
    +G_MODULE_EXPORT gboolean
    +gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    + GPLUGIN_UNUSED GError **error)
    +{
    + return TRUE;
    +}
    +
    +G_MODULE_EXPORT gboolean
    +gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    + GPLUGIN_UNUSED GError **error)
    +{
    + return TRUE;
    +}
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/tcc/tests/plugins/dependent.c Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,49 @@
    +/*
    + * 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.h>
    +#include <gplugin-native.h>
    +
    +G_MODULE_EXPORT GPluginPluginInfo *
    +gplugin_query(GPLUGIN_UNUSED GError **error) {
    + const gchar * const dependencies[] = {
    + "dependency1",
    + "dependency2",
    + NULL
    + };
    +
    + return gplugin_plugin_info_new(
    + "gplugin/native-dependent-plugin",
    + GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
    + "dependencies", dependencies,
    + NULL
    + );
    +}
    +
    +G_MODULE_EXPORT gboolean
    +gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    + GPLUGIN_UNUSED GError **error)
    +{
    + return TRUE;
    +}
    +
    +G_MODULE_EXPORT gboolean
    +gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    + GPLUGIN_UNUSED GError **error)
    +{
    + return TRUE;
    +}
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/tcc/tests/plugins/load-exception.c Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,42 @@
    +/*
    + * 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.h>
    +#include <gplugin-native.h>
    +
    +G_MODULE_EXPORT GPluginPluginInfo *
    +gplugin_query(GPLUGIN_UNUSED GError **error) {
    + return gplugin_plugin_info_new(
    + "gplugin/native-load-exception",
    + GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
    + NULL
    + );
    +}
    +
    +G_MODULE_EXPORT gboolean
    +gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    + GPLUGIN_UNUSED GError **error)
    +{
    + return FALSE;
    +}
    +
    +G_MODULE_EXPORT gboolean
    +gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    + GPLUGIN_UNUSED GError **error)
    +{
    + return TRUE;
    +}
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/tcc/tests/plugins/load-failed.c Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,43 @@
    +/*
    + * 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.h>
    +#include <gplugin-native.h>
    +
    +G_MODULE_EXPORT GPluginPluginInfo *
    +gplugin_query(GPLUGIN_UNUSED GError **error) {
    + return gplugin_plugin_info_new(
    + "gplugin/native-load-failed",
    + GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
    + NULL
    + );
    +}
    +
    +G_MODULE_EXPORT gboolean
    +gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin, GError **error) {
    + if(error)
    + *error = g_error_new(GPLUGIN_DOMAIN, 0, "expected error");
    +
    + return FALSE;
    +}
    +
    +G_MODULE_EXPORT gboolean
    +gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    + GPLUGIN_UNUSED GError **error)
    +{
    + return TRUE;
    +}
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/tcc/tests/plugins/unload-failed.c Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,43 @@
    +/*
    + * 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.h>
    +#include <gplugin-native.h>
    +
    +G_MODULE_EXPORT GPluginPluginInfo *
    +gplugin_query(GPLUGIN_UNUSED GError **error) {
    + return gplugin_plugin_info_new(
    + "gplugin/native-unload-failed",
    + GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
    + NULL
    + );
    +}
    +
    +G_MODULE_EXPORT gboolean
    +gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
    + GPLUGIN_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");
    +
    + return FALSE;
    +}
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/tcc/tests/test-tcc-loader.c Tue Jan 22 22:50:20 2019 -0600
    @@ -0,0 +1,31 @@
    +/*
    + * 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 <glib.h>
    +#include <gplugin.h>
    +
    +#include <gplugin/gplugin-loader-tests.h>
    +
    +gint
    +main(gint argc, gchar **argv) {
    + g_test_init(&argc, &argv, NULL);
    +
    + gplugin_loader_tests_main(TCC_LOADER_DIR, TCC_PLUGIN_DIR, "c");
    +
    + return g_test_run();
    +}
    +
    --- a/xsl/gtester-junit.xsl Mon Apr 18 22:32:13 2016 -0500
    +++ b/xsl/gtester-junit.xsl Tue Jan 22 22:50:20 2019 -0600
    @@ -1,6 +1,6 @@
    <?xml version="1.0" encoding="utf-8"?>
    <!--
    - Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
    + 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
    @@ -36,7 +36,7 @@
    <!-- match the gtester root tag -->
    <xsl:template match="/gtester">
    - <xsl:element name="testsuit">
    + <xsl:element name="testsuite">
    <!-- add the number of tests as the test attribute -->
    <xsl:attribute name="tests">
    <xsl:value-of select="count(//testcase)"/>