Imported Upstream version 2.67.1 upstream/2.67.1
authorDongHun Kwak <dh0128.kwak@samsung.com>
Fri, 29 Oct 2021 01:31:18 +0000 (10:31 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Fri, 29 Oct 2021 01:31:18 +0000 (10:31 +0900)
238 files changed:
.gitlab-ci.yml
.gitlab-ci/check-todos.py
.gitlab-ci/debian-stable.Dockerfile
.gitlab-ci/meson-junit-report.py
.gitlab-ci/run-black.sh [new file with mode: 0755]
.gitlab-ci/run-docker.sh
.gitlab-ci/run-flake8.sh [new file with mode: 0755]
.gitlab-ci/run-shellcheck.sh [new file with mode: 0755]
NEWS
check-abis.sh
clang-format-diff.py
docs/reference/gio/concat-files-helper.py
docs/reference/gio/gdbus-codegen.xml
docs/reference/gio/gdbus-object-manager-example/gdbus-object-manager-example-docs.xml
docs/reference/gio/gdbus.xml
docs/reference/gio/meson.build
docs/reference/gio/migrating-gdbus.xml
docs/reference/gio/overview.xml
docs/reference/glib/building.xml
docs/reference/glib/glib-sections.txt
docs/reference/glib/gvariant-varargs.xml
docs/reference/gobject/glib-mkenums.xml
docs/reference/gobject/gobject-sections.txt
docs/reference/gobject/tut_gobject.xml
docs/reference/gobject/tut_gtype.xml
docs/reference/gobject/tut_howto.xml
fuzzing/driver.c
gio/data-to-c.py
gio/gaction.c
gio/gactionmap.c
gio/gappinfo.c
gio/gapplication.c
gio/gapplicationcommandline.c
gio/gapplicationimpl-dbus.c
gio/gbytesicon.c
gio/gdbus-2.0/codegen/__init__.py
gio/gdbus-2.0/codegen/codegen.py
gio/gdbus-2.0/codegen/codegen_docbook.py
gio/gdbus-2.0/codegen/codegen_main.py
gio/gdbus-2.0/codegen/dbustypes.py
gio/gdbus-2.0/codegen/parser.py
gio/gdbus-2.0/codegen/utils.py
gio/gdbus-tool.c
gio/gdbusauthmechanismsha1.c
gio/gdbusconnection.c
gio/gdbuserror.c
gio/gdbusinterface.c
gio/gdbusinterfaceskeleton.c
gio/gdbusintrospection.c
gio/gdbusintrospection.h
gio/gdbusmessage.c
gio/gdbusmethodinvocation.c
gio/gdbusnameowning.c
gio/gdbusnamewatching.c
gio/gdbusobject.c
gio/gdbusprivate.c
gio/gdbusserver.c
gio/gdbusutils.c
gio/gdesktopappinfo.c
gio/gfileicon.c
gio/gfileinfo.c
gio/gfileiostream.c
gio/gfilenamecompleter.c
gio/gfileoutputstream.c
gio/gicon.c
gio/gio-querymodules-wrapper.py
gio/gioenumtypes.c.template
gio/giomodule.c
gio/giowin32-priv.h
gio/gkeyfilesettingsbackend.c
gio/glocalfile.c
gio/glocalfileinfo.c
gio/gmemorymonitor.c
gio/gmenu.c
gio/gmenumodel.c
gio/gmountoperation.c
gio/gnetworkaddress.c
gio/gnetworking.c
gio/gnetworkmonitor.c
gio/gproxy.c
gio/gproxyaddress.c
gio/gproxyresolver.c
gio/gresource.c
gio/gsettingsbackend.c
gio/gsettingsschema.c
gio/gsocketclient.c
gio/gsubprocess.c
gio/gsubprocesslauncher.c
gio/gtask.c
gio/gtestdbus.c
gio/gtlsbackend.c
gio/gtlscertificate.c
gio/gtlsclientconnection.c
gio/gunixmounts.c
gio/gvfs.c
gio/gvolumemonitor.c
gio/gwin32appinfo.c
gio/gzlibcompressor.c
gio/gzlibdecompressor.c
gio/kqueue/kqueue-missing.c
gio/meson.build
gio/tests/appmonitor.c
gio/tests/codegen.py
gio/tests/desktop-app-info.c
gio/tests/empty.txt [new file with mode: 0644]
gio/tests/g-file-info.c
gio/tests/gdbus-connection-flush.c
gio/tests/gdbus-connection.c
gio/tests/gdbus-overflow.c
gio/tests/gdbus-peer.c
gio/tests/gdbus-serialization.c
gio/tests/gen-big-test-resource.py
gio/tests/gengiotypefuncs.py
gio/tests/gsettings.c
gio/tests/gsocketclient-slow.c
gio/tests/live-g-file.c
gio/tests/proxy.c
gio/tests/resolver.c
gio/tests/resources.c
gio/tests/socket-service.c
gio/tests/static-link.py
gio/tests/taptestrunner.py
gio/tests/task.c
gio/tests/test.gresource.xml
gio/tests/x-content/unix-software/autorun.sh
glib/gatomic.c
glib/gatomic.h
glib/gdatetime.c
glib/ghostutils.c
glib/gkeyfile.c
glib/glib_gdb.py
glib/gmacros.h
glib/gmain.c
glib/gmarkup.c
glib/gmessages.h
glib/gnulib/gl_cv_func_frexpl_works/meson.build
glib/goption.c
glib/gprintf.c
glib/gregex.c
glib/gscanner.c
glib/gsequence.c
glib/gspawn.c
glib/gstrfuncs.c
glib/gtestutils.c
glib/gtestutils.h
glib/gthread-win32.c
glib/gthread.c
glib/gtimezone.c
glib/gtimezone.h
glib/gtrace-private.h
glib/gtrace.c
glib/gtypes.h
glib/guri.c
glib/guri.h
glib/gutils.h
glib/gvariant-serialiser.c
glib/gvariant.c
glib/gvarianttype.c
glib/meson.build
glib/tests/642026.c
glib/tests/atomic.c
glib/tests/autoptr.c
glib/tests/cond.c
glib/tests/fileutils.c
glib/tests/gdatetime.c
glib/tests/gvariant.c
glib/tests/gwakeuptest.c
glib/tests/hash.c
glib/tests/hostutils.c
glib/tests/logging.c
glib/tests/mainloop.c
glib/tests/markup-collect.c
glib/tests/markup-escape.c
glib/tests/markup-subparser.c
glib/tests/node.c
glib/tests/once.c
glib/tests/option-context.c
glib/tests/pattern.c
glib/tests/protocol.c
glib/tests/queue.c
glib/tests/rcbox.c
glib/tests/regex.c
glib/tests/scannerapi.c
glib/tests/sequence.c
glib/tests/shell.c
glib/tests/slice.c
glib/tests/spawn-multithreaded.c
glib/tests/spawn-singlethread.c
glib/tests/strfuncs.c
glib/tests/testing-helper.c
glib/tests/testing.c
glib/tests/timeout.c
glib/tests/timer.c
glib/tests/tree.c
glib/tests/uri.c
glib/update-gtranslit.py
glib/update-pcre/update.sh
gobject/gatomicarray.c
gobject/gatomicarray.h
gobject/gbinding.c
gobject/gbinding.h
gobject/gboxed.c
gobject/gclosure.c
gobject/gclosure.h
gobject/glib-enumtypes.c.template
gobject/gobject.c
gobject/gobject.h
gobject/gobject_gdb.py
gobject/gsourceclosure.c
gobject/gtype.c
gobject/gtype.h
gobject/gtypeplugin.c
gobject/gtypeplugin.h
gobject/gvalue.c
gobject/tests/binding.c
gobject/tests/genmarshal.py
gobject/tests/mkenums.py
gobject/tests/qdata.c
gobject/tests/signals.c
gobject/tests/taptestrunner.py
gobject/tests/threadtests.c
gobject/tests/type.c
gobject/tests/value.c
meson.build
msvc_recommended_pragmas.h
po/cs.po
po/es.po
po/uk.po
sanity_check [deleted file]
subprojects/sysprof.wrap
tests/gen-casefold-txt.py
tests/gen-casemap-txt.py
tests/gobject/performance-threaded.c
tests/gobject/performance.c
tests/onceinit.c
tests/refcount/objects.c
tests/refcount/properties3.c
tests/run-assert-msg-test.sh

index a89211a..e79a667 100644 (file)
@@ -12,7 +12,7 @@ cache:
 variables:
   FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/glib/fedora:v9"
   COVERITY_IMAGE: "registry.gitlab.gnome.org/gnome/glib/coverity:v1"
-  DEBIAN_IMAGE: "registry.gitlab.gnome.org/gnome/glib/debian-stable:v6"
+  DEBIAN_IMAGE: "registry.gitlab.gnome.org/gnome/glib/debian-stable:v7"
   ANDROID_IMAGE: "registry.gitlab.gnome.org/gnome/glib/android-ndk:v3"
   MINGW_IMAGE: "registry.gitlab.gnome.org/gnome/glib/mingw:v2"
   MESON_TEST_TIMEOUT_MULTIPLIER: 2
@@ -47,6 +47,9 @@ style-check-diff:
   allow_failure: true
   script:
     - .gitlab-ci/run-style-check-diff.sh
+    - .gitlab-ci/run-shellcheck.sh
+    - .gitlab-ci/run-black.sh
+    - .gitlab-ci/run-flake8.sh
 
 check-todos:
   extends: .only-default
index 83b3eee..915ee28 100755 (executable)
@@ -23,18 +23,18 @@ import sys
 # that’s conventionally used as a way of marking a workaround which needs to
 # be merged for now, but is to be grepped for and reverted or reworked later.
 BANNED_KEYWORDS = [
-    'TO' + 'DO',
-    'X' + 'XX',
-    'W' + 'IP',
+    "TO" + "DO",
+    "X" + "XX",
+    "W" + "IP",
 ]
 
 
 def main():
     parser = argparse.ArgumentParser(
-        description='Check a range of commits to ensure they don’t contain '
-                    'banned keywords.')
-    parser.add_argument('commits',
-                        help='SHA to diff from, or range of commits to diff')
+        description="Check a range of commits to ensure they don’t contain "
+        "banned keywords."
+    )
+    parser.add_argument("commits", help="SHA to diff from, or range of commits to diff")
     args = parser.parse_args()
 
     banned_words_seen = set()
@@ -43,47 +43,55 @@ def main():
 
     # Check the log messages for banned words.
     log_process = subprocess.run(
-        ['git', 'log', '--no-color', args.commits + '..HEAD'],
-        stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8',
-        check=True)
-    log_lines = log_process.stdout.strip().split('\n')
+        ["git", "log", "--no-color", args.commits + "..HEAD"],
+        stdout=subprocess.PIPE,
+        stderr=subprocess.PIPE,
+        encoding="utf-8",
+        check=True,
+    )
+    log_lines = log_process.stdout.strip().split("\n")
 
     for line in log_lines:
         for keyword in BANNED_KEYWORDS:
-            if re.search('(^|\W+){}(\W+|$)'.format(keyword), line):
+            if re.search(r"(^|\W+){}(\W+|$)".format(keyword), line):
                 banned_words_seen.add(keyword)
                 seen_in_log = True
 
     # Check the diff for banned words.
     diff_process = subprocess.run(
-        ['git', 'diff', '-U0', '--no-color', args.commits],
-        stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8',
-        check=True)
-    diff_lines = diff_process.stdout.strip().split('\n')
+        ["git", "diff", "-U0", "--no-color", args.commits],
+        stdout=subprocess.PIPE,
+        stderr=subprocess.PIPE,
+        encoding="utf-8",
+        check=True,
+    )
+    diff_lines = diff_process.stdout.strip().split("\n")
 
     for line in diff_lines:
-        if not line.startswith('+ '):
+        if not line.startswith("+ "):
             continue
 
         for keyword in BANNED_KEYWORDS:
-            if re.search('(^|\W+){}(\W+|$)'.format(keyword), line):
+            if re.search(r"(^|\W+){}(\W+|$)".format(keyword), line):
                 banned_words_seen.add(keyword)
                 seen_in_diff = True
 
     if banned_words_seen:
         if seen_in_log and seen_in_diff:
-            where = 'commit message and diff'
+            where = "commit message and diff"
         elif seen_in_log:
-            where = 'commit message'
+            where = "commit message"
         elif seen_in_diff:
-            where = 'commit diff'
-
-        print('Saw banned keywords in a {}: {}. '
-              'This indicates the branch is a work in progress and should not '
-              'be merged in its current '
-              'form.'.format(where, ', '.join(banned_words_seen)))
+            where = "commit diff"
+
+        print(
+            "Saw banned keywords in a {}: {}. "
+            "This indicates the branch is a work in progress and should not "
+            "be merged in its current "
+            "form.".format(where, ", ".join(banned_words_seen))
+        )
         sys.exit(1)
 
 
-if __name__ == '__main__':
+if __name__ == "__main__":
     main()
index 54d2d8c..38758fc 100644 (file)
@@ -2,6 +2,7 @@ FROM debian:buster
 
 RUN apt-get update -qq && apt-get install --no-install-recommends -qq -y \
     bindfs \
+    black \
     clang \
     clang-tools-7 \
     clang-format-7 \
@@ -9,6 +10,7 @@ RUN apt-get update -qq && apt-get install --no-install-recommends -qq -y \
     desktop-file-utils \
     elfutils \
     findutils \
+    flake8 \
     fuse \
     gcc \
     g++ \
@@ -36,6 +38,7 @@ RUN apt-get update -qq && apt-get install --no-install-recommends -qq -y \
     python3-setuptools \
     python3-wheel \
     shared-mime-info \
+    shellcheck \
     systemtap-sdt-dev \
     unzip \
     wget \
index 90939ff..1855b49 100755 (executable)
 import argparse
 import datetime
 import json
-import os
 import sys
 import xml.etree.ElementTree as ET
 
-aparser = argparse.ArgumentParser(description='Turns a Meson test log into a JUnit report')
-aparser.add_argument('--project-name', metavar='NAME',
-                     help='The project name',
-                     default='unknown')
-aparser.add_argument('--job-id', metavar='ID',
-                     help='The job ID for the report',
-                     default='Unknown')
-aparser.add_argument('--branch', metavar='NAME',
-                     help='Branch of the project being tested',
-                     default='master')
-aparser.add_argument('--output', metavar='FILE',
-                     help='The output file, stdout by default',
-                     type=argparse.FileType('w', encoding='UTF-8'),
-                     default=sys.stdout)
-aparser.add_argument('infile', metavar='FILE',
-                     help='The input testlog.json, stdin by default',
-                     type=argparse.FileType('r', encoding='UTF-8'),
-                     default=sys.stdin)
+aparser = argparse.ArgumentParser(
+    description="Turns a Meson test log into a JUnit report"
+)
+aparser.add_argument(
+    "--project-name", metavar="NAME", help="The project name", default="unknown"
+)
+aparser.add_argument(
+    "--job-id", metavar="ID", help="The job ID for the report", default="Unknown"
+)
+aparser.add_argument(
+    "--branch",
+    metavar="NAME",
+    help="Branch of the project being tested",
+    default="master",
+)
+aparser.add_argument(
+    "--output",
+    metavar="FILE",
+    help="The output file, stdout by default",
+    type=argparse.FileType("w", encoding="UTF-8"),
+    default=sys.stdout,
+)
+aparser.add_argument(
+    "infile",
+    metavar="FILE",
+    help="The input testlog.json, stdin by default",
+    type=argparse.FileType("r", encoding="UTF-8"),
+    default=sys.stdin,
+)
 
 args = aparser.parse_args()
 
 outfile = args.output
 
-testsuites = ET.Element('testsuites')
-testsuites.set('id', '{}/{}'.format(args.job_id, args.branch))
-testsuites.set('package', args.project_name)
-testsuites.set('timestamp', datetime.datetime.utcnow().isoformat())
+testsuites = ET.Element("testsuites")
+testsuites.set("id", "{}/{}".format(args.job_id, args.branch))
+testsuites.set("package", args.project_name)
+testsuites.set("timestamp", datetime.datetime.utcnow().isoformat())
 
 suites = {}
 for line in args.infile:
     data = json.loads(line)
-    (full_suite, unit_name) = data['name'].split(' / ')
+    (full_suite, unit_name) = data["name"].split(" / ")
     try:
-        (project_name, suite_name) = full_suite.split(':')
+        (project_name, suite_name) = full_suite.split(":")
     except ValueError:
         project_name = full_suite
         suite_name = full_suite
 
-    duration = data['duration']
-    return_code = data['returncode']
-    log = data['stdout']
-    log_stderr = data.get('stderr', '')
+    duration = data["duration"]
+    return_code = data["returncode"]
+    log = data["stdout"]
+    log_stderr = data.get("stderr", "")
 
     unit = {
-        'suite': suite_name,
-        'name': unit_name,
-        'duration': duration,
-        'returncode': return_code,
-        'stdout': log,
-        'stderr': log_stderr,
+        "suite": suite_name,
+        "name": unit_name,
+        "duration": duration,
+        "returncode": return_code,
+        "stdout": log,
+        "stderr": log_stderr,
     }
 
     units = suites.setdefault(suite_name, [])
     units.append(unit)
 
 for name, units in suites.items():
-    print('Processing suite {} (units: {})'.format(name, len(units)))
+    print("Processing suite {} (units: {})".format(name, len(units)))
 
     def if_failed(unit):
-        if unit['returncode'] != 0:
+        if unit["returncode"] != 0:
             return True
         return False
 
     def if_succeded(unit):
-        if unit['returncode'] == 0:
+        if unit["returncode"] == 0:
             return True
         return False
 
     successes = list(filter(if_succeded, units))
     failures = list(filter(if_failed, units))
-    print(' - {}: {} pass, {} fail'.format(name, len(successes), len(failures)))
+    print(" - {}: {} pass, {} fail".format(name, len(successes), len(failures)))
 
-    testsuite = ET.SubElement(testsuites, 'testsuite')
-    testsuite.set('name', '{}/{}'.format(args.project_name, name))
-    testsuite.set('tests', str(len(units)))
-    testsuite.set('errors', str(len(failures)))
-    testsuite.set('failures', str(len(failures)))
+    testsuite = ET.SubElement(testsuites, "testsuite")
+    testsuite.set("name", "{}/{}".format(args.project_name, name))
+    testsuite.set("tests", str(len(units)))
+    testsuite.set("errors", str(len(failures)))
+    testsuite.set("failures", str(len(failures)))
 
     for unit in successes:
-        testcase = ET.SubElement(testsuite, 'testcase')
-        testcase.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
-        testcase.set('name', unit['name'])
-        testcase.set('time', str(unit['duration']))
+        testcase = ET.SubElement(testsuite, "testcase")
+        testcase.set("classname", "{}/{}".format(args.project_name, unit["suite"]))
+        testcase.set("name", unit["name"])
+        testcase.set("time", str(unit["duration"]))
 
     for unit in failures:
-        testcase = ET.SubElement(testsuite, 'testcase')
-        testcase.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
-        testcase.set('name', unit['name'])
-        testcase.set('time', str(unit['duration']))
-
-        failure = ET.SubElement(testcase, 'failure')
-        failure.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
-        failure.set('name', unit['name'])
-        failure.set('type', 'error')
-        failure.text = unit['stdout'] + '\n' + unit['stderr']
-
-output = ET.tostring(testsuites, encoding='unicode')
+        testcase = ET.SubElement(testsuite, "testcase")
+        testcase.set("classname", "{}/{}".format(args.project_name, unit["suite"]))
+        testcase.set("name", unit["name"])
+        testcase.set("time", str(unit["duration"]))
+
+        failure = ET.SubElement(testcase, "failure")
+        failure.set("classname", "{}/{}".format(args.project_name, unit["suite"]))
+        failure.set("name", unit["name"])
+        failure.set("type", "error")
+        failure.text = unit["stdout"] + "\n" + unit["stderr"]
+
+output = ET.tostring(testsuites, encoding="unicode")
 outfile.write(output)
diff --git a/.gitlab-ci/run-black.sh b/.gitlab-ci/run-black.sh
new file mode 100755 (executable)
index 0000000..fdeaf16
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+set -e
+
+# shellcheck disable=SC2046
+black --diff --check $(git ls-files '*.py')
index 6299c55..56b2b0a 100755 (executable)
@@ -46,7 +46,7 @@ while (($# > 0)); do
                 --base|-b) read_arg base "$@" || shift;;
                 --base-version) read_arg base_version "$@" || shift;;
                 --no-login) no_login=1;;
-                *) echo -e "\e[1;31mERROR\e[0m: Unknown option '$1'"; exit 1;;
+                *) echo -e "\\e[1;31mERROR\\e[0m: Unknown option '$1'"; exit 1;;
         esac
         shift
 done
@@ -75,7 +75,7 @@ if [ $list == 1 ]; then
                 filename=$( basename -- "$f" )
                 basename="${filename%.*}"
 
-                echo -e "  \e[1;39m$basename\e[0m"
+                echo -e "  \\e[1;39m$basename\\e[0m"
         done
         exit 0
 fi
@@ -87,7 +87,7 @@ if [ -z "${base}" ]; then
 fi
 
 if [ ! -f "$base.Dockerfile" ]; then
-        echo -e "\e[1;31mERROR\e[0m: Dockerfile for '$base' not found"
+        echo -e "\\e[1;31mERROR\\e[0m: Dockerfile for '$base' not found"
         exit 1
 fi
 
@@ -100,7 +100,7 @@ fi
 TAG="registry.gitlab.gnome.org/gnome/glib/${base}:${base_version}"
 
 if [ $build == 1 ]; then
-        echo -e "\e[1;32mBUILDING\e[0m: ${base} as ${TAG}"
+        echo -e "\\e[1;32mBUILDING\\e[0m: ${base} as ${TAG}"
         $SUDO_CMD docker build \
                 --build-arg HOST_USER_ID="$UID" \
                 --build-arg COVERITY_SCAN_PROJECT_NAME="${COVERITY_SCAN_PROJECT_NAME}" \
@@ -111,7 +111,7 @@ if [ $build == 1 ]; then
 fi
 
 if [ $push == 1 ]; then
-        echo -e "\e[1;32mPUSHING\e[0m: ${base} as ${TAG}"
+        echo -e "\\e[1;32mPUSHING\\e[0m: ${base} as ${TAG}"
 
         if [ $no_login == 0 ]; then
                 $SUDO_CMD docker login registry.gitlab.gnome.org
@@ -122,7 +122,7 @@ if [ $push == 1 ]; then
 fi
 
 if [ $run == 1 ]; then
-        echo -e "\e[1;32mRUNNING\e[0m: ${base} as ${TAG}"
+        echo -e "\\e[1;32mRUNNING\\e[0m: ${base} as ${TAG}"
         $SUDO_CMD docker run \
                 --rm \
                 --volume "$(pwd)/..:/home/user/app" \
diff --git a/.gitlab-ci/run-flake8.sh b/.gitlab-ci/run-flake8.sh
new file mode 100755 (executable)
index 0000000..5675a01
--- /dev/null
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+set -e
+
+# Disable formatting warnings in flake8, as we use `black` to handle that.
+formatting_warnings=E101,E111,E114,E115,E116,E117,E12,E13,E2,E3,E401,E5,E70,W1,W2,W3,W5
+
+# shellcheck disable=SC2046
+flake8 --max-line-length=88 --ignore="$formatting_warnings" $(git ls-files '*.py')
diff --git a/.gitlab-ci/run-shellcheck.sh b/.gitlab-ci/run-shellcheck.sh
new file mode 100755 (executable)
index 0000000..abf2e5e
--- /dev/null
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+set -e
+
+# Ignoring third-party directories that we don't want to parse
+# shellcheck disable=SC2046
+shellcheck $(git ls-files '*.sh' | grep -Ev "glib/libcharset|glib/dirent")
diff --git a/NEWS b/NEWS
index 3426e7b..f6925a4 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,98 @@
+Overview of changes in GLib 2.67.1
+==================================
+
+* Deprecate `g_time_zone_new()` in favour of `g_time_zone_new_identifier()`,
+  which makes error checking easier (#553)
+
+* Remove `volatile` from various public APIs, including `G_DEFINE_*`. You should
+  adjust your code to not use `volatile` for atomic variables, `GOnce`
+  variables, or mostly anything else (see
+  http://isvolatileusefulwiththreads.in/c/). (#600)
+
+* Support passing file handles to `gdbus` command line tool (work by
+  Norbert Pocs and Tim Waugh) (#961)
+
+* Add `g_assert_cmpstrv()` test convenience function (work by Niels De Graef) (#2015)
+
+* Changes to the behaviour of the `G_URI_FLAGS_SCHEME_NORMALIZE` scheme
+  normalization flag in `GUri` (work by Carlos Garcia Campos) (#2257, !1716)
+
+* Add new `--run-prefix` and `--skip-prefix` options to GTest, to allow running
+  or skipping test suites by prefix (work by Frederic Martinsons) (!1738)
+
+* Fix thread-safety of `GBinding`; see the updated documentation for
+  `g_object_bind_property()` for full details — if your code uses `GBinding`
+  across threads, you should re-check it against the latest documentation, use
+  `g_binding_unbind()` rather than implicitly dropping the binding with your
+  last `g_object_unref()` call, and use `g_binding_dup_source()`/`g_binding_dup_target()`
+  instead of `g_binding_get_source()`/`g_binding_get_target()`
+  (work by Sebastian Dröge) (!1745)
+
+* Bugs fixed:
+ - #553 Improved error-handling when timezone lookup fails
+ - #600 Remove "volatile" from G_DEFINE_*
+ - #961 gdbus tool: file handle passing doesn't work
+ - #994 mark g_assert_* as "noreturn" also on MSVC
+ - #1560 Can't get data for empty compressed resources
+ - #1592 Main loop ignores GPollFD sources when there is at least one source ready with priority higher than default one
+ - #1833 meson: reconsider G_DISABLE_CAST_CHECKS handling
+ - #1849 Documentation of g_set_object(): can object_ptr be null?
+ - #1963 Follow-up from "gdbusmessage: Limit recursion of variants in D-Bus messages"
+ - #2015 Add g_assert_cmpstrv() test utility
+ - #2046 Add pylint and shellcheck CI checks
+ - #2074 Big dbus writes with a FD list fail
+ - #2076 g_type_register_fundamental() and g_type_add_interface_static() should not trigger valgrind leak warnings
+ - #2150 Add URI parsing tests from GstURI to GUri
+ - #2221 GLib-GIO:ERROR:../gio/tests/gsocketclient-slow.c:99:on_event: 'connection' should be NULL
+ - #2223 Documentation of g_strrstr_len is misleading; suggested fix
+ - #2233 GSocketClient crashes on connection failure
+ - #2236 Docs: gdbus-codegen example links broken
+ - #2253 In gspawn.c, use sysconf() system call on Mac OS, instead of default maxfiles limit of 4096
+ - #2257 GUri: apply scheme normalization flag consistently
+ - !1251 Improve support for interface types
+ - !1385 gobject: allocate parameter list for g_object_new_valist() entirely on stack
+ - !1629 Add some tracing to GTask
+ - !1699 Fix signedness warnings
+ - !1701 gio: Fix some remaining DocBook syntax in a documentation comment
+ - !1708 gio: Add missing nullable annotations
+ - !1716 guri: Normalize uri segments if they are encoded and add a flag to do scheme-based normalization
+ - !1722 gio: Fix various typos of the name ‘D-Bus’
+ - !1724 glib/tests/fileutils: Fix expectations when running as root
+ - !1726 gdbus: Document the intended semantics of handles and fdsTim Waugh
+ - !1731 Make more use of g_assert_no_errno()
+ - !1733 gdbusauthmechanismsha1: Don’t create keyring dir when running as setuid
+ - !1734 glocalfileinfo: Use a single timeout source at a time for hidden file cache
+ - !1735 gobject: Standardise on the term ‘instantiatable’
+ - !1737 gscanner: Avoid undefined behaviour copying between union members
+ - !1738 Extend the usage of -p option for glib test framework
+ - !1740 Fix more warnings
+ - !1745 Make GBinding thread-safe (alternative approach)
+ - !1746 gkeyfilesettingsbackend: improve error-checking
+ - !1747 Fix broken link syntax in g_vasprintf docs
+ - !1748 Fix minor Coverity return value warnings
+ - !1750 Fix warnings
+ - !1754 GWin32AppInfo: Use a thread pool for async appinfo tree rebuilds
+ - !1755 Minor Coverity fixes
+ - !1756 shellcheck fixes
+ - !1757 Python formatting improvements
+ - !1758 Fix warnings
+ - !1765 Fix more warnings
+ - !1766 Fix some gdatetime annotations
+ - !1767 tests: Fix GDateTime tests on FreeBSD
+ - !1769 gfileicon: Fix unused-but-set variable with G_DISABLE_ASSERT
+ - !1770 Minor scan-build fixes
+ - !1771 macos: fix frexpl checks in cross-compilation
+ - !1776 gio: ‘security_context_t’ is deprecated
+ - !1780 Minor Coverity fixes
+ - !1781 gspawn: Handle ENOSYS from close_range()
+ - !1782 ghostutils: Abandon hostname conversion early if it’s too long
+
+* Translation updates:
+ - Czech
+ - Spanish
+ - Ukrainian
+
+
 Overview of changes in GLib 2.67.0
 ==================================
 
index a18103b..5340f31 100755 (executable)
@@ -1,11 +1,11 @@
 #!/bin/sh -e
 
 list_leaked_symbols () {
-       nm -D "$1" | grep ' T ' | cut -f 3 -d ' ' | egrep -v "$2"
+       nm -D "$1" | grep ' T ' | cut -f 3 -d ' ' | grep -E -v "$2"
 }
 
 check_symbols () {
-       if [ "`list_leaked_symbols "$1" "$2" | wc -l`" -ne 0 ]; then
+       if [ "$(list_leaked_symbols "$1" "$2" | wc -l)" -ne 0 ]; then
                echo File "$1" possibly leaking symbols:
                list_leaked_symbols "$1" "$2"
                exit 1
index 3fb776c..4eb1910 100755 (executable)
@@ -33,50 +33,76 @@ else:
 
 def main():
     parser = argparse.ArgumentParser(
-        description=__doc__,
-        formatter_class=argparse.RawDescriptionHelpFormatter)
-    parser.add_argument('-i', action='store_true', default=False,
-                        help='apply edits to files instead of displaying a '
-                             'diff')
-    parser.add_argument('-p', metavar='NUM', default=0,
-                        help='strip the smallest prefix containing P slashes')
-    parser.add_argument('-regex', metavar='PATTERN', default=None,
-                        help='custom pattern selecting file paths to reformat '
-                        '(case sensitive, overrides -iregex)')
-    parser.add_argument('-iregex', metavar='PATTERN',
-                        default=r'.*\.(cpp|cc|c\+\+|cxx|c|cl|h|hh|hpp|m|mm|inc'
-                                r'|js|ts|proto|protodevel|java|cs)',
-                        help='custom pattern selecting file paths to reformat '
-                             '(case insensitive, overridden by -regex)')
-    parser.add_argument('-sort-includes', action='store_true', default=False,
-                        help='let clang-format sort include blocks')
-    parser.add_argument('-v', '--verbose', action='store_true',
-                        help='be more verbose, ineffective without -i')
-    parser.add_argument('-style',
-                        help='formatting style to apply (LLVM, Google, '
-                        'Chromium, Mozilla, WebKit)')
-    parser.add_argument('-binary', default='clang-format',
-                        help='location of binary to use for clang-format')
+        description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
+    )
+    parser.add_argument(
+        "-i",
+        action="store_true",
+        default=False,
+        help="apply edits to files instead of displaying a " "diff",
+    )
+    parser.add_argument(
+        "-p",
+        metavar="NUM",
+        default=0,
+        help="strip the smallest prefix containing P slashes",
+    )
+    parser.add_argument(
+        "-regex",
+        metavar="PATTERN",
+        default=None,
+        help="custom pattern selecting file paths to reformat "
+        "(case sensitive, overrides -iregex)",
+    )
+    parser.add_argument(
+        "-iregex",
+        metavar="PATTERN",
+        default=r".*\.(cpp|cc|c\+\+|cxx|c|cl|h|hh|hpp|m|mm|inc"
+        r"|js|ts|proto|protodevel|java|cs)",
+        help="custom pattern selecting file paths to reformat "
+        "(case insensitive, overridden by -regex)",
+    )
+    parser.add_argument(
+        "-sort-includes",
+        action="store_true",
+        default=False,
+        help="let clang-format sort include blocks",
+    )
+    parser.add_argument(
+        "-v",
+        "--verbose",
+        action="store_true",
+        help="be more verbose, ineffective without -i",
+    )
+    parser.add_argument(
+        "-style",
+        help="formatting style to apply (LLVM, Google, " "Chromium, Mozilla, WebKit)",
+    )
+    parser.add_argument(
+        "-binary",
+        default="clang-format",
+        help="location of binary to use for clang-format",
+    )
     args = parser.parse_args()
 
     # Extract changed lines for each file.
     filename = None
     lines_by_file = {}
     for line in sys.stdin:
-        match = re.search(r'^\+\+\+\ (.*?/){%s}(\S*)' % args.p, line)
+        match = re.search(r"^\+\+\+\ (.*?/){%s}(\S*)" % args.p, line)
         if match:
             filename = match.group(2)
         if filename is None:
             continue
 
         if args.regex is not None:
-            if not re.match('^%s$' % args.regex, filename):
+            if not re.match("^%s$" % args.regex, filename):
                 continue
         else:
-            if not re.match('^%s$' % args.iregex, filename, re.IGNORECASE):
+            if not re.match("^%s$" % args.iregex, filename, re.IGNORECASE):
                 continue
 
-        match = re.search(r'^@@.*\+(\d+)(,(\d+))?', line)
+        match = re.search(r"^@@.*\+(\d+)(,(\d+))?", line)
         if match:
             start_line = int(match.group(1))
             line_count = 1
@@ -86,7 +112,8 @@ def main():
                 continue
             end_line = start_line + line_count - 1
             lines_by_file.setdefault(filename, []).extend(
-                ['-lines', str(start_line) + ':' + str(end_line)])
+                ["-lines", str(start_line) + ":" + str(end_line)]
+            )
 
     # Reformat files containing changes in place.
     # We need to count amount of bytes generated in the output of
@@ -95,20 +122,22 @@ def main():
     format_line_counter = 0
     for filename, lines in lines_by_file.items():
         if args.i and args.verbose:
-            print('Formatting {}'.format(filename))
+            print("Formatting {}".format(filename))
         command = [args.binary, filename]
         if args.i:
-            command.append('-i')
+            command.append("-i")
         if args.sort_includes:
-            command.append('-sort-includes')
+            command.append("-sort-includes")
         command.extend(lines)
         if args.style:
-            command.extend(['-style', args.style])
-        p = subprocess.Popen(command,
-                             stdout=subprocess.PIPE,
-                             stderr=None,
-                             stdin=subprocess.PIPE,
-                             universal_newlines=True)
+            command.extend(["-style", args.style])
+        p = subprocess.Popen(
+            command,
+            stdout=subprocess.PIPE,
+            stderr=None,
+            stdin=subprocess.PIPE,
+            universal_newlines=True,
+        )
         stdout, _ = p.communicate()
         if p.returncode != 0:
             sys.exit(p.returncode)
@@ -117,11 +146,15 @@ def main():
             with open(filename) as f:
                 code = f.readlines()
             formatted_code = StringIO(stdout).readlines()
-            diff = difflib.unified_diff(code, formatted_code,
-                                        filename, filename,
-                                        '(before formatting)',
-                                        '(after formatting)')
-            diff_string = ''.join(diff)
+            diff = difflib.unified_diff(
+                code,
+                formatted_code,
+                filename,
+                filename,
+                "(before formatting)",
+                "(after formatting)",
+            )
+            diff_string = "".join(diff)
             if diff_string:
                 format_line_counter += sys.stdout.write(diff_string)
 
@@ -129,5 +162,5 @@ def main():
         sys.exit(1)
 
 
-if __name__ == '__main__':
+if __name__ == "__main__":
     main()
index 94d64c3..d434f9e 100644 (file)
 #
 # Author: Xavier Claessens <xavier.claessens@collabora.com>
 
+import os
 import sys
 
 if len(sys.argv) < 3:
-  print('Usage: {} <output file> <input file 1> ...'.format(os.path.basename(sys.argv[0])))
-  sys.exit(1)
+    print(
+        "Usage: {} <output file> <input file 1> ...".format(
+            os.path.basename(sys.argv[0])
+        )
+    )
+    sys.exit(1)
 
-with open(sys.argv[1], 'w') as outfile:
+with open(sys.argv[1], "w") as outfile:
     for fname in sys.argv[2:]:
         with open(fname) as infile:
             for line in infile:
index 25210c3..960b5ff 100644 (file)
@@ -90,7 +90,7 @@
     When generating C code, a
     #GInterface<!-- -->-derived type is generated for each D-Bus
     interface. Additionally, for every generated type,
-    <type>FooBar</type>, two concrete instantiable types,
+    <type>FooBar</type>, two concrete instantiatable types,
     <type>FooBarProxy</type> and <type>FooBarSkeleton</type>, implementing
     said interface are also generated. The former is derived from
     #GDBusProxy and intended for use on the client side
@@ -771,7 +771,7 @@ gdbus-codegen --generate-c-code myapp-generated       \
     <filename>myapp-generated.[ch]</filename> are
     generated. The files provide an abstract
     #GTypeInterface<!-- -->-derived type called
-    <type>MyAppFrobber</type> as well as two instantiable types with
+    <type>MyAppFrobber</type> as well as two instantiatable types with
     the same name but suffixed with <type>Proxy</type> and
     <type>Skeleton</type>. The generated file, roughly, contains the
     following facilities:
index 7b0d1ca..fd4c307 100644 (file)
@@ -5,13 +5,15 @@
 ]>
 <book lang="en" xmlns:xi="http://www.w3.org/2003/XInclude">
   <part>
-    <title>foo</title>
+    <title>GDBus ObjctManager Example</title>
     <chapter>
-      <title>bar</title>
+      <title>Interfaces</title>
       <xi:include href="xml/ExampleAnimal.xml"/>
       <xi:include href="xml/ExampleCat.xml"/>
       <xi:include href="xml/ExampleObject.xml"/>
       <xi:include href="xml/ExampleObjectManagerClient.xml"/>
     </chapter>
   </part>
+
+  <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
 </book>
index 0e6c14d..77fdfeb 100644 (file)
@@ -322,6 +322,18 @@ $ gdbus call --session \
 (uint32 12,)
 </programlisting>
 <para>
+  Call a method with file handle argument:
+</para>
+<programlisting>
+$ gdbus call --session \
+             --dest org.example.foo \
+             --object-path /org/example/foo \
+             --method SendFDs \
+             1 \
+             10 \
+             10&lt;file.foo
+</programlisting>
+<para>
   Monitoring all objects on a service:
 </para>
 <programlisting>
index a4e67ca..acdd5ec 100644 (file)
@@ -1,7 +1,5 @@
 if get_option('gtk_doc')
-  if installed_tests_enabled
-    subdir('gdbus-object-manager-example')
-  endif
+  subdir('gdbus-object-manager-example')
   subdir('xml')
 
   ignore_headers = [
@@ -178,13 +176,11 @@ if get_option('gtk_doc')
     'gdbus-codegen.xml',
   ]
 
-  if installed_tests_enabled
-    content_files += [
-      gdbus_example_objectmanager_xml,
-      gdbus_example_objectmanager_sources,
-      gdbus_object_manager_example_doc
-    ]
-  endif
+  content_files += [
+    gdbus_example_objectmanager_xml,
+    gdbus_example_objectmanager_sources,
+    gdbus_object_manager_example_doc
+  ]
 
   gnome.gtkdoc('gio',
     main_xml : 'gio-docs.xml',
index 5e2d464..dc4ee75 100644 (file)
@@ -254,7 +254,7 @@ on_name_acquired (GDBusConnection *connection,
       linkend="gdbus-codegen">gdbus-codegen</link></command> is used and like
       its counterpart, it also takes D-Bus Introspection XML as input:
     </para>
-    <example id="gdbus-example-codegen-input"><title>Example D-Bus Introspection XML</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../gdbus-example-objectmanager.xml"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
+    <example id="gdbus-example-codegen-input"><title>Example D-Bus Introspection XML</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../../gio/tests/gdbus-object-manager-example/gdbus-example-objectmanager.xml"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT: gdbus-example-objectmanager.xml</xi:fallback></xi:include></programlisting></example>
     <para>
       If this XML is processed like this
 <informalexample><programlisting><![CDATA[
@@ -291,18 +291,19 @@ gdbus-codegen --interface-prefix org.gtk.GDBus.Example.ObjectManager. \
       #ExampleObjectManagerClient pages for documentation.
     </para>
 
-    <example id="gdbus-example-codegen-server"><title>Server-side application using generated code</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../gdbus-example-objectmanager-server.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
+    <example id="gdbus-example-codegen-server"><title>Server-side application using generated code</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../../gio/tests/gdbus-example-objectmanager-server.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT: gdbus-example-objectmanager-server.c</xi:fallback></xi:include></programlisting></example>
 
-    <example id="gdbus-example-codegen-client"><title>Client-side application using generated code</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../gdbus-example-objectmanager-client.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
+    <example id="gdbus-example-codegen-client"><title>Client-side application using generated code</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../../gio/tests/gdbus-example-objectmanager-client.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT: gdbus-example-objectmanager-client.c</xi:fallback></xi:include></programlisting></example>
 
   </section>
 
-  <xi:include href="../../../../gio/tests/gdbus-object-manager-example/objectmanager-gen-org.gtk.GDBus.Example.ObjectManager.Animal.xml"/>
-  <xi:include href="../../../../gio/tests/gdbus-object-manager-example/objectmanager-gen-org.gtk.GDBus.Example.ObjectManager.Cat.xml"/>
-  <xi:include href="../gdbus-object-manager-example/xml/ExampleAnimal.xml"/>
-  <xi:include href="../gdbus-object-manager-example/xml/ExampleCat.xml"/>
-  <xi:include href="../gdbus-object-manager-example/xml/ExampleObject.xml"/>
-  <xi:include href="../gdbus-object-manager-example/xml/ExampleObjectManagerClient.xml"/>
+  <!-- All XInclude paths are relative to the html/ directory under the build root directory -->
+  <xi:include href="../../../../gio/tests/gdbus-object-manager-example/objectmanager-gen-org.gtk.GDBus.Example.ObjectManager.Animal.xml"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT: objectmanager-gen-org.gtk.GDBus.Example.ObjectManager.Animal.xml</xi:fallback></xi:include>
+  <xi:include href="../../../../gio/tests/gdbus-object-manager-example/objectmanager-gen-org.gtk.GDBus.Example.ObjectManager.Cat.xml"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT: objectmanager-gen-org.gtk.GDBus.Example.ObjectManager.Cat.xml</xi:fallback></xi:include>
+  <xi:include href="../gdbus-object-manager-example/xml/ExampleAnimal.xml"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT: ExampleAnimal.xml</xi:fallback></xi:include>
+  <xi:include href="../gdbus-object-manager-example/xml/ExampleCat.xml"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT: ExampleCat.xml</xi:fallback></xi:include>
+  <xi:include href="../gdbus-object-manager-example/xml/ExampleObject.xml"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT: ExampleObject.xml</xi:fallback></xi:include>
+  <xi:include href="../gdbus-object-manager-example/xml/ExampleObjectManagerClient.xml"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT: ExampleObjectManagerClient.xml</xi:fallback></xi:include>
 
   </section>
 
index 7817ab6..b442285 100644 (file)
@@ -370,7 +370,7 @@ Gvfs is also heavily distributed and relies on a session bus to be present.
         The #GVfs implementation for local files that is included in GIO
         has the name "local", the implementation in the gvfs module has
         the name "gvfs".  Most commonly, system software will set this to "local"
-       to avoid having `GFile` APIs perform unnecessary DBus calls.
+        to avoid having `GFile` APIs perform unnecessary D-Bus calls.
       </para><para>
         The special value <literal>help</literal> can be used to print a list of
         available implementations to standard output.
index 720a6ff..9ff2fbf 100644 (file)
         <literal>G_ENABLE_DEBUG</literal> will be defined and GLib will be built
         with additional debug code enabled.
       </para>
+      <para>
+        If the build type is <literal>plain</literal>, GLib will not enable any
+        optimization or debug options by default, and will leave it entirely to
+        the user to choose their options. To build with the options recommended
+        by GLib developers, choose <literal>release</literal>.
+      </para>
     </formalpara>
 
     <formalpara>
index 02bb2ba..690c0de 100644 (file)
@@ -469,6 +469,8 @@ G_ALIGNOF
 
 <SUBSECTION>
 G_CONST_RETURN
+G_NORETURN
+G_NORETURN_FUNCPTR
 
 <SUBSECTION>
 G_N_ELEMENTS
@@ -1939,6 +1941,7 @@ g_time_zone_unref
 g_time_zone_ref
 <SUBSECTION>
 g_time_zone_new
+g_time_zone_new_identifier
 g_time_zone_new_local
 g_time_zone_new_utc
 g_time_zone_new_offset
@@ -3547,6 +3550,7 @@ g_assert
 g_assert_not_reached
 
 g_assert_cmpstr
+g_assert_cmpstrv
 g_assert_cmpint
 g_assert_cmpuint
 g_assert_cmphex
index 8529a28..cd9002c 100644 (file)
@@ -532,8 +532,8 @@ value4 = g_variant_new ("x", G_GINT64_CONSTANT (998877665544332211));
     <link linkend='gchar'>gchar</link> *)</code> and makes a copy of it.
     <link linkend='NULL:CAPS'><literal>NULL</literal></link> is not a valid string; use
     <link linkend='gvariant-format-strings-maybe-types'>maybe types</link> to encode that.  If the '<literal>o</literal>' or
-    '<literal>g</literal>' characters are used, care must be taken to ensure that the passed string is a valid DBus
-    object path or DBus type signature, respectively.
+    '<literal>g</literal>' characters are used, care must be taken to ensure that the passed string is a valid D-Bus
+    object path or D-Bus type signature, respectively.
    </para>
    <para>
     Upon encounting '<literal>s</literal>', '<literal>o</literal>' or '<literal>g</literal>', <link
index 2200328..ce250a3 100644 (file)
@@ -480,9 +480,9 @@ A C source template file will typically look like this:
 GType
 @enum_name@_get_type (void)
 {
-  static volatile gsize g_@type@_type_id__volatile;
+  static gsize static_g_@type@_type_id;
 
-  if (g_once_init_enter (&amp;g_define_type_id__volatile))
+  if (g_once_init_enter (&amp;static_g_@type@_type_id))
     {
       static const G@Type@Value values[] = {
 /*** END value-header ***/
@@ -498,9 +498,9 @@ GType
       GType g_@type@_type_id =
         g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
 
-      g_once_init_leave (&amp;g_@type@_type_id__volatile, g_@type@_type_id);
+      g_once_init_leave (&amp;static_g_@type@_type_id, g_@type@_type_id);
     }
-  return g_@type@_type_id__volatile;
+  return static_g_@type@_type_id;
 }
 
 /*** END value-tail ***/
index f52d953..54fbcca 100644 (file)
@@ -65,6 +65,7 @@ g_type_default_interface_unref
 g_type_children
 g_type_interfaces
 g_type_interface_prerequisites
+g_type_interface_instantiatable_prerequisite
 g_type_set_qdata
 g_type_get_qdata
 g_type_query
@@ -977,8 +978,10 @@ g_io_condition_get_type
 GBinding
 GBindingFlags
 g_binding_get_source
+g_binding_dup_source
 g_binding_get_source_property
 g_binding_get_target
+g_binding_dup_target
 g_binding_get_target_property
 g_binding_get_flags
 g_binding_unbind
index fc7d6fe..d1cb41f 100644 (file)
@@ -12,7 +12,7 @@
   </para>
 
   <para>
-    <link linkend="GObject"><type>GObject</type></link> is a fundamental classed instantiable type. It implements:
+    <link linkend="GObject"><type>GObject</type></link> is a fundamental classed instantiatable type. It implements:
     <itemizedlist>
       <listitem><para>Memory management with reference counting</para></listitem>
       <listitem><para>Construction/Destruction of instances</para></listitem>
@@ -293,8 +293,8 @@ ViewerFile *file = g_object_new (VIEWER_TYPE_FILE, NULL);
         one of the <function>g_type_register_*</function> functions), the object's instance 
         memory will be freed or returned to the object pool for this type.
         Once the object has been freed, if it was the last instance of the type, the type's class
-        will be destroyed as described in <xref linkend="gtype-instantiable-classed"/> and 
-          <xref linkend="gtype-non-instantiable-classed"/>.
+        will be destroyed as described in <xref linkend="gtype-instantiatable-classed"/> and
+          <xref linkend="gtype-non-instantiatable-classed"/>.
       </para>
 
       <para>
index a1c6005..ee04288 100644 (file)
@@ -108,7 +108,7 @@ GType g_type_register_fundamental (GType                       type_id,
 
         <para>
           The major common point between <emphasis>all</emphasis> GLib types (fundamental and 
-          non-fundamental, classed and non-classed, instantiable and non-instantiable) is that
+          non-fundamental, classed and non-classed, instantiatable and non-instantiatable) is that
           they can all be manipulated through a single API to copy/assign them.
         </para>
 
@@ -300,11 +300,11 @@ GType viewer_file_get_type (void)
 
       </sect1>
 
-      <sect1 id="gtype-non-instantiable">
-        <title>Non-instantiable non-classed fundamental types</title>
+      <sect1 id="gtype-non-instantiatable">
+        <title>Non-instantiatable non-classed fundamental types</title>
 
         <para>
-          A lot of types are not instantiable by the type system and do not have
+          A lot of types are not instantiatable by the type system and do not have
           a class. Most of these types are fundamental trivial types such as <emphasis>gchar</emphasis>, 
           and are already registered by GLib.
         </para>
@@ -344,7 +344,7 @@ GType viewer_file_get_type (void)
 
 
         <para>
-          Having non-instantiable types might seem a bit useless: what good is a type
+          Having non-instantiatable types might seem a bit useless: what good is a type
           if you cannot instantiate an instance of that type ? Most of these types
           are used in conjunction with <link linkend="GValue"><type>GValue</type></link>s: a GValue is initialized
           with an integer or a string and it is passed around by using the registered 
@@ -354,8 +354,8 @@ GType viewer_file_get_type (void)
 
       </sect1>
 
-      <sect1 id="gtype-instantiable-classed">
-        <title>Instantiable classed types: objects</title>
+      <sect1 id="gtype-instantiatable-classed">
+        <title>Instantiatable classed types: objects</title>
 
         <para>
           This section covers the theory behind objects. See
@@ -364,10 +364,10 @@ GType viewer_file_get_type (void)
         </para>
 
         <para>
-          Types which are registered with a class and are declared instantiable are
+          Types which are registered with a class and are declared instantiatable are
           what most closely resembles an <emphasis>object</emphasis>. 
           Although <link linkend="GObject"><type>GObject</type></link>s (detailed in <xref linkend="chapter-gobject"/>) 
-          are the most well known type of instantiable
+          are the most well known type of instantiatable
           classed types, other kinds of similar objects used as the base of an inheritance 
           hierarchy have been externally developed and they are all built on the fundamental
           features described below.
@@ -498,7 +498,7 @@ B *b;
 </programlisting></informalexample>
         </para>
 
-        <sect2 id="gtype-instantiable-classed-init-done">
+        <sect2 id="gtype-instantiatable-classed-init-done">
           <title>Initialization and Destruction</title>
 
           <para>
@@ -599,7 +599,7 @@ B *b;
                   <row>
                     <!--entry>First call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> for target type</entry-->
                     <entry>interface initialization, see 
-                      <xref linkend="gtype-non-instantiable-classed-init"/></entry>
+                      <xref linkend="gtype-non-instantiatable-classed-init"/></entry>
                     <entry></entry>
                   </row>
                   <row>
@@ -610,7 +610,7 @@ B *b;
                   <row>
                     <entry morerows="2">Last call to <function><link linkend="g-type-free-instance">g_type_free_instance</link></function> for target type</entry>
                     <entry>interface destruction, see
-                      <xref linkend="gtype-non-instantiable-classed-dest"/></entry>
+                      <xref linkend="gtype-non-instantiatable-classed-dest"/></entry>
                     <entry></entry>
                   </row>
                   <row>
@@ -633,8 +633,8 @@ B *b;
 
       </sect1>
 
-      <sect1 id="gtype-non-instantiable-classed">
-        <title>Non-instantiable classed types: interfaces</title>
+      <sect1 id="gtype-non-instantiatable-classed">
+        <title>Non-instantiatable classed types: interfaces</title>
 
         <para>
           This section covers the theory behind interfaces. See
@@ -648,7 +648,7 @@ B *b;
           Imagine the play, pause and stop buttons on hi-fi equipment — those can
           be seen as a playback interface. Once you know what they do, you can
           control your CD player, MP3 player or anything that uses these symbols.
-          To declare an interface you have to register a non-instantiable
+          To declare an interface you have to register a non-instantiatable
           classed type which derives from 
           <link linkend="GTypeInterface"><type>GTypeInterface</type></link>. The following piece of code declares such an interface.
 <informalexample><programlisting>
@@ -792,14 +792,14 @@ struct _GInterfaceInfo
 </programlisting></informalexample>
         </para>
 
-        <sect2 id="gtype-non-instantiable-classed-init">
+        <sect2 id="gtype-non-instantiatable-classed-init">
           <title>Interface Initialization</title>
 
           <para>
-            When an instantiable classed type which implements an interface
+            When an instantiatable classed type which implements an interface
             (either directly or by inheriting an implementation from a superclass)
             is created for the first time, its class structure is initialized
-            following the process described in <xref linkend="gtype-instantiable-classed"/>.
+            following the process described in <xref linkend="gtype-instantiatable-classed"/>.
             After that, the interface implementations associated with
             the type are initialized.
           </para>
@@ -852,7 +852,7 @@ viewer_editable_default_init (ViewerEditableInterface *iface)
 GType
 viewer_editable_get_type (void)
 {
-  static volatile gsize type_id = 0;
+  static gsize type_id = 0;
   if (g_once_init_enter (&amp;type_id)) {
     const GTypeInfo info = {
       sizeof (ViewerEditableInterface),
@@ -937,11 +937,11 @@ viewer_editable_default_init (ViewerEditableInterface *iface)
         
         </sect2>
         
-        <sect2 id="gtype-non-instantiable-classed-dest">
+        <sect2 id="gtype-non-instantiatable-classed-dest">
           <title>Interface Destruction</title>
 
           <para>
-            When the last instance of an instantiable type which registered 
+            When the last instance of an instantiatable type which registered
             an interface implementation is destroyed, the interface's 
             implementations associated to the type are destroyed.
           </para>
@@ -955,7 +955,7 @@ viewer_editable_default_init (ViewerEditableInterface *iface)
 
           <para>
             Again, it is important to understand, as in 
-            <xref linkend="gtype-non-instantiable-classed-init"/>,
+            <xref linkend="gtype-non-instantiatable-classed-init"/>,
               that both <function>interface_finalize</function> and <function>base_finalize</function>
               are invoked exactly once for the destruction of each implementation of an interface. Thus,
               if you were to use one of these functions, you would need to use a static integer variable
index bfb8d95..b61a328 100644 (file)
@@ -854,7 +854,7 @@ b_method_to_call (B *obj, gint some_param)
   
   <para>
     The theory behind how GObject interfaces work is given in
-    <xref linkend="gtype-non-instantiable-classed"/>; this section covers how to
+    <xref linkend="gtype-non-instantiatable-classed"/>; this section covers how to
     define and implement an interface.
   </para>
 
index 99e965b..f6d2396 100644 (file)
@@ -10,6 +10,7 @@ int
 main (int argc, char **argv)
 {
   FILE *f;
+  long tell_result;
   size_t n_read, len;
   unsigned char *buf;
 
@@ -19,7 +20,9 @@ main (int argc, char **argv)
   f = fopen (argv[1], "r");
   assert (f);
   fseek (f, 0, SEEK_END);
-  len = ftell (f);
+  tell_result = ftell (f);
+  assert (tell_result >= 0);
+  len = (size_t) tell_result;
   fseek (f, 0, SEEK_SET);
   buf = (unsigned char*) malloc (len);
   n_read = fread (buf, 1, len, f);
index f226220..d8854b4 100755 (executable)
@@ -3,14 +3,14 @@
 import sys
 
 if len(sys.argv) < 4:
-    print('Usage: {0} <filename> <variable> <output>')
+    print("Usage: {0} <filename> <variable> <output>")
 
-with open(sys.argv[1], 'rb') as f:
-    in_data = f.read().decode('utf-8', 'backslashreplace')
-b = [r'\x{:02x}'.format(ord(c)) for c in in_data]
+with open(sys.argv[1], "rb") as f:
+    in_data = f.read().decode("utf-8", "backslashreplace")
+b = [r"\x{:02x}".format(ord(c)) for c in in_data]
 
-out_data = "const char {0}[] = \"".format(sys.argv[2])
-out_data += "".join(b) + "\";"
+out_data = 'const char {0}[] = "'.format(sys.argv[2])
+out_data += "".join(b) + '";'
 
-with open(sys.argv[3], 'w') as f:
+with open(sys.argv[3], "w") as f:
     f.write(out_data)
index c3748a9..645eb26 100644 (file)
@@ -224,7 +224,7 @@ g_action_change_state (GAction  *action,
  * The return value (if non-%NULL) should be freed with
  * g_variant_unref() when it is no longer required.
  *
- * Returns: (transfer full): the current state of the action
+ * Returns: (nullable) (transfer full): the current state of the action
  *
  * Since: 2.28
  **/
index bfcda8d..077e3cf 100644 (file)
@@ -76,7 +76,7 @@ g_action_map_default_init (GActionMapInterface *iface)
  *
  * If no such action exists, returns %NULL.
  *
- * Returns: (transfer none): a #GAction, or %NULL
+ * Returns: (nullable) (transfer none): a #GAction, or %NULL
  *
  * Since: 2.32
  */
index 6b00925..0303c61 100644 (file)
@@ -138,7 +138,7 @@ g_app_info_dup (GAppInfo *appinfo)
  *
  * Checks if two #GAppInfos are equal.
  *
- * Note that the check <emphasis>may not</emphasis> compare each individual
+ * Note that the check *may not* compare each individual
  * field, and only does an identity check. In case detecting changes in the 
  * contents is needed, program code must additionally compare relevant fields.
  *
@@ -173,7 +173,7 @@ g_app_info_equal (GAppInfo *appinfo1,
  * Note that the returned ID may be %NULL, depending on how
  * the @appinfo has been constructed.
  *
- * Returns: a string containing the application's ID.
+ * Returns: (nullable): a string containing the application's ID.
  **/
 const char *
 g_app_info_get_id (GAppInfo *appinfo)
@@ -240,7 +240,7 @@ g_app_info_get_display_name (GAppInfo *appinfo)
  * 
  * Gets a human-readable description of an installed application.
  *
- * Returns: a string containing a description of the 
+ * Returns: (nullable): a string containing a description of the 
  * application @appinfo, or %NULL if none. 
  **/
 const char *
@@ -284,7 +284,7 @@ g_app_info_get_executable (GAppInfo *appinfo)
  * Gets the commandline with which the application will be
  * started.  
  *
- * Returns: (type filename): a string containing the @appinfo's commandline,
+ * Returns: (nullable) (type filename): a string containing the @appinfo's commandline,
  *     or %NULL if this information is not available
  *
  * Since: 2.20
@@ -518,7 +518,7 @@ g_app_info_get_supported_types (GAppInfo *appinfo)
  * 
  * Gets the icon for the application.
  *
- * Returns: (transfer none): the default #GIcon for @appinfo or %NULL
+ * Returns: (nullable) (transfer none): the default #GIcon for @appinfo or %NULL
  * if there is no default icon.
  **/
 GIcon *
@@ -1279,7 +1279,7 @@ g_app_launch_context_get_environment (GAppLaunchContext *context)
  * applications are started on the same display as the launching
  * application, by setting the `DISPLAY` environment variable.
  *
- * Returns: a display string for the display.
+ * Returns: (nullable): a display string for the display.
  */
 char *
 g_app_launch_context_get_display (GAppLaunchContext *context,
@@ -1311,7 +1311,7 @@ g_app_launch_context_get_display (GAppLaunchContext *context,
  * Startup notification IDs are defined in the 
  * [FreeDesktop.Org Startup Notifications standard](http://standards.freedesktop.org/startup-notification-spec/startup-notification-latest.txt).
  *
- * Returns: a startup notification ID for the application, or %NULL if
+ * Returns: (nullable): a startup notification ID for the application, or %NULL if
  *     not supported.
  **/
 char *
index b78fd9a..8a473e6 100644 (file)
@@ -1793,7 +1793,7 @@ g_application_new (const gchar       *application_id,
  *
  * Gets the unique identifier for @application.
  *
- * Returns: the identifier for @application, owned by @application
+ * Returns: (nullable): the identifier for @application, owned by @application
  *
  * Since: 2.28
  **/
@@ -2084,7 +2084,7 @@ g_application_get_is_remote (GApplication *application)
  * This function must not be called before the application has been
  * registered.  See g_application_get_is_registered().
  *
- * Returns: (transfer none): a #GDBusConnection, or %NULL
+ * Returns: (nullable) (transfer none): a #GDBusConnection, or %NULL
  *
  * Since: 2.34
  **/
@@ -2116,7 +2116,7 @@ g_application_get_dbus_connection (GApplication *application)
  * This function must not be called before the application has been
  * registered.  See g_application_get_is_registered().
  *
- * Returns: the object path, or %NULL
+ * Returns: (nullable): the object path, or %NULL
  *
  * Since: 2.34
  **/
@@ -2743,7 +2743,7 @@ static GApplication *default_app;
  *
  * If there is no default application then %NULL is returned.
  *
- * Returns: (transfer none): the default application for this process, or %NULL
+ * Returns: (nullable) (transfer none): the default application for this process, or %NULL
  *
  * Since: 2.32
  **/
index d6c5c45..7d3f0e6 100644 (file)
@@ -523,13 +523,13 @@ g_application_command_line_get_options_dict (GApplicationCommandLine *cmdline)
  * The #GInputStream can be used to read data passed to the standard
  * input of the invoking process.
  * This doesn't work on all platforms.  Presently, it is only available
- * on UNIX when using a DBus daemon capable of passing file descriptors.
+ * on UNIX when using a D-Bus daemon capable of passing file descriptors.
  * If stdin is not available then %NULL will be returned.  In the
  * future, support may be expanded to other platforms.
  *
  * You must only call this function once per commandline invocation.
  *
- * Returns: (transfer full): a #GInputStream for stdin
+ * Returns: (nullable) (transfer full): a #GInputStream for stdin
  *
  * Since: 2.34
  **/
@@ -610,7 +610,7 @@ g_application_command_line_get_environ (GApplicationCommandLine *cmdline)
  * The return value should not be modified or freed and is valid for as
  * long as @cmdline exists.
  *
- * Returns: the value of the variable, or %NULL if unset or unsent
+ * Returns: (nullable): the value of the variable, or %NULL if unset or unsent
  *
  * Since: 2.28
  **/
index fd9d046..6f02788 100644 (file)
@@ -43,7 +43,7 @@
 #include "gunixfdlist.h"
 #endif
 
-/* DBus Interface definition {{{1 */
+/* D-Bus Interface definition {{{1 */
 
 /* For documentation of these interfaces, see
  * https://wiki.gnome.org/Projects/GLib/GApplication/DBusAPI
@@ -640,7 +640,7 @@ g_application_impl_register (GApplication        *application,
 
   /* We are non-primary.  Try to get the primary's list of actions.
    * This also serves as a mechanism to ensure that the primary exists
-   * (ie: DBus service files installed correctly, etc).
+   * (ie: D-Bus service files installed correctly, etc).
    */
   actions = g_dbus_action_group_get (impl->session_bus, impl->bus_name, impl->object_path);
   if (!g_dbus_action_group_sync (actions, cancellable, error))
index ca78be1..b2323d9 100644 (file)
@@ -165,7 +165,7 @@ g_bytes_icon_new (GBytes *bytes)
  *
  * Gets the #GBytes associated with the given @icon.
  *
- * Returns: (transfer none): a #GBytes, or %NULL.
+ * Returns: (transfer none): a #GBytes.
  *
  * Since: 2.38
  **/
index f876f04..ed324d7 100644 (file)
@@ -21,7 +21,9 @@
 
 import os
 
-builddir = os.environ.get('UNINSTALLED_GLIB_BUILDDIR')
+builddir = os.environ.get("UNINSTALLED_GLIB_BUILDDIR")
 
 if builddir is not None:
-    __path__.append(os.path.abspath(os.path.join(builddir, 'gio', 'gdbus-2.0', 'codegen')))
+    __path__.append(
+        os.path.abspath(os.path.join(builddir, "gio", "gdbus-2.0", "codegen"))
+    )
index cda0471..04bf44a 100644 (file)
 #
 # Author: David Zeuthen <davidz@redhat.com>
 
-import sys
-
 from . import config
 from . import utils
 from . import dbustypes
 from .utils import print_error
 
-LICENSE_STR = '''/*
+LICENSE_STR = """/*
  * This file is generated by gdbus-codegen, do not modify it.
  *
  * The license of this code is the same as for the D-Bus interface description
  * it was derived from. Note that it links to GLib, so must comply with the
  * LGPL linking clauses.
- */\n'''
+ */\n"""
+
+
+# Disable line length warnings as wrapping the C code templates would be hard
+# flake8: noqa: E501
+
 
 def generate_namespace(namespace):
     ns = namespace
     if len(namespace) > 0:
         if utils.is_ugly_case(namespace):
-            ns = namespace.replace('_', '')
-            ns_upper = namespace.upper() + '_'
-            ns_lower = namespace.lower() + '_'
+            ns = namespace.replace("_", "")
+            ns_upper = namespace.upper() + "_"
+            ns_lower = namespace.lower() + "_"
         else:
-            ns_upper = utils.camel_case_to_uscore(namespace).upper() + '_'
-            ns_lower = utils.camel_case_to_uscore(namespace).lower() + '_'
+            ns_upper = utils.camel_case_to_uscore(namespace).upper() + "_"
+            ns_lower = utils.camel_case_to_uscore(namespace).lower() + "_"
     else:
-        ns_upper = ''
-        ns_lower = ''
+        ns_upper = ""
+        ns_lower = ""
 
     return (ns, ns_upper, ns_lower)
 
+
 def generate_header_guard(header_name):
     # There might be more characters that are safe to use than these, but lets
     # stay conservative.
     safe_valid_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-    return ''.join(map(lambda c: c if c in safe_valid_chars else '_',
-                       header_name.upper()))
+    return "".join(
+        map(lambda c: c if c in safe_valid_chars else "_", header_name.upper())
+    )
+
 
 class HeaderCodeGenerator:
-    def __init__(self, ifaces, namespace, generate_objmanager,
-                 generate_autocleanup, header_name, input_files_basenames,
-                 use_pragma, glib_min_required,
-                 symbol_decorator, symbol_decorator_header, outfile):
+    def __init__(
+        self,
+        ifaces,
+        namespace,
+        generate_objmanager,
+        generate_autocleanup,
+        header_name,
+        input_files_basenames,
+        use_pragma,
+        glib_min_required,
+        symbol_decorator,
+        symbol_decorator_header,
+        outfile,
+    ):
         self.ifaces = ifaces
         self.namespace, self.ns_upper, self.ns_lower = generate_namespace(namespace)
         self.generate_objmanager = generate_objmanager
@@ -79,84 +95,106 @@ class HeaderCodeGenerator:
     # ----------------------------------------------------------------------------------------------------
 
     def generate_header_preamble(self):
-        basenames = ', '.join(self.input_files_basenames)
+        basenames = ", ".join(self.input_files_basenames)
         self.outfile.write(LICENSE_STR.format(config.VERSION, basenames))
-        self.outfile.write('\n')
+        self.outfile.write("\n")
 
         if self.use_pragma:
-            self.outfile.write('#pragma once\n')
+            self.outfile.write("#pragma once\n")
         else:
-            self.outfile.write('#ifndef __{!s}__\n'.format(self.header_guard))
-            self.outfile.write('#define __{!s}__\n'.format(self.header_guard))
+            self.outfile.write("#ifndef __{!s}__\n".format(self.header_guard))
+            self.outfile.write("#define __{!s}__\n".format(self.header_guard))
 
         if self.symbol_decorator_header is not None:
-            self.outfile.write('\n')
+            self.outfile.write("\n")
             self.outfile.write('#include "%s"\n' % self.symbol_decorator_header)
 
-        self.outfile.write('\n')
-        self.outfile.write('#include <gio/gio.h>\n')
-        self.outfile.write('\n')
-        self.outfile.write('G_BEGIN_DECLS\n')
-        self.outfile.write('\n')
+        self.outfile.write("\n")
+        self.outfile.write("#include <gio/gio.h>\n")
+        self.outfile.write("\n")
+        self.outfile.write("G_BEGIN_DECLS\n")
+        self.outfile.write("\n")
 
     # ----------------------------------------------------------------------------------------------------
 
     def declare_types(self):
         for i in self.ifaces:
-            self.outfile.write('\n')
-            self.outfile.write('/* ------------------------------------------------------------------------ */\n')
-            self.outfile.write('/* Declarations for %s */\n'%i.name)
-            self.outfile.write('\n')
+            self.outfile.write("\n")
+            self.outfile.write(
+                "/* ------------------------------------------------------------------------ */\n"
+            )
+            self.outfile.write("/* Declarations for %s */\n" % i.name)
+            self.outfile.write("\n")
 
             # First the GInterface
-            self.outfile.write('#define %sTYPE_%s (%s_get_type ())\n'%(i.ns_upper, i.name_upper, i.name_lower))
-            self.outfile.write('#define %s%s(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_%s, %s))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
-            self.outfile.write('#define %sIS_%s(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_%s))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper))
-            self.outfile.write('#define %s%s_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), %sTYPE_%s, %sIface))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
-            self.outfile.write('\n')
-            self.outfile.write('struct _%s;\n'%(i.camel_name))
-            self.outfile.write('typedef struct _%s %s;\n'%(i.camel_name, i.camel_name))
-            self.outfile.write('typedef struct _%sIface %sIface;\n'%(i.camel_name, i.camel_name))
-            self.outfile.write('\n')
-            self.outfile.write('struct _%sIface\n'%(i.camel_name))
-            self.outfile.write('{\n')
-            self.outfile.write('  GTypeInterface parent_iface;\n')
+            self.outfile.write(
+                "#define %sTYPE_%s (%s_get_type ())\n"
+                % (i.ns_upper, i.name_upper, i.name_lower)
+            )
+            self.outfile.write(
+                "#define %s%s(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_%s, %s))\n"
+                % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name)
+            )
+            self.outfile.write(
+                "#define %sIS_%s(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_%s))\n"
+                % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper)
+            )
+            self.outfile.write(
+                "#define %s%s_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), %sTYPE_%s, %sIface))\n"
+                % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name)
+            )
+            self.outfile.write("\n")
+            self.outfile.write("struct _%s;\n" % (i.camel_name))
+            self.outfile.write(
+                "typedef struct _%s %s;\n" % (i.camel_name, i.camel_name)
+            )
+            self.outfile.write(
+                "typedef struct _%sIface %sIface;\n" % (i.camel_name, i.camel_name)
+            )
+            self.outfile.write("\n")
+            self.outfile.write("struct _%sIface\n" % (i.camel_name))
+            self.outfile.write("{\n")
+            self.outfile.write("  GTypeInterface parent_iface;\n")
 
             function_pointers = {}
 
             # vfuncs for methods
             if len(i.methods) > 0:
-                self.outfile.write('\n')
+                self.outfile.write("\n")
                 for m in i.methods:
-                    key = (m.since, '_method_%s'%m.name_lower)
-                    value  = '  gboolean (*handle_%s) (\n'%(m.name_lower)
-                    value += '    %s *object,\n'%(i.camel_name)
-                    value += '    GDBusMethodInvocation *invocation'%()
+                    key = (m.since, "_method_%s" % m.name_lower)
+                    value = "  gboolean (*handle_%s) (\n" % (m.name_lower)
+                    value += "    %s *object,\n" % (i.camel_name)
+                    value += "    GDBusMethodInvocation *invocation"
                     if m.unix_fd:
-                        value += ',\n    GUnixFDList *fd_list'
+                        value += ",\n    GUnixFDList *fd_list"
                     for a in m.in_args:
-                        value += ',\n    %sarg_%s'%(a.ctype_in, a.name)
-                    value += ');\n\n'
+                        value += ",\n    %sarg_%s" % (a.ctype_in, a.name)
+                    value += ");\n\n"
                     function_pointers[key] = value
 
             # vfuncs for signals
             if len(i.signals) > 0:
-                self.outfile.write('\n')
+                self.outfile.write("\n")
                 for s in i.signals:
-                    key = (s.since, '_signal_%s'%s.name_lower)
-                    value  = '  void (*%s) (\n'%(s.name_lower)
-                    value += '    %s *object'%(i.camel_name)
+                    key = (s.since, "_signal_%s" % s.name_lower)
+                    value = "  void (*%s) (\n" % (s.name_lower)
+                    value += "    %s *object" % (i.camel_name)
                     for a in s.args:
-                        value += ',\n    %sarg_%s'%(a.ctype_in, a.name)
-                    value += ');\n\n'
+                        value += ",\n    %sarg_%s" % (a.ctype_in, a.name)
+                    value += ");\n\n"
                     function_pointers[key] = value
 
             # vfuncs for properties
             if len(i.properties) > 0:
-                self.outfile.write('\n')
+                self.outfile.write("\n")
                 for p in i.properties:
-                    key = (p.since, '_prop_get_%s'%p.name_lower)
-                    value = '  %s (*get_%s) (%s *object);\n\n'%(p.arg.ctype_in, p.name_lower, i.camel_name)
+                    key = (p.since, "_prop_get_%s" % p.name_lower)
+                    value = "  %s (*get_%s) (%s *object);\n\n" % (
+                        p.arg.ctype_in,
+                        p.name_lower,
+                        i.camel_name,
+                    )
                     function_pointers[key] = value
 
             # Sort according to @since tag, then name.. this ensures
@@ -169,530 +207,799 @@ class HeaderCodeGenerator:
             # See https://bugzilla.gnome.org/show_bug.cgi?id=647577#c5
             # for discussion
             for key in sorted(function_pointers.keys(), key=utils.version_cmp_key):
-                self.outfile.write('%s'%function_pointers[key])
-
-            self.outfile.write('};\n')
-            self.outfile.write('\n')
-            if self.generate_autocleanup == 'all':
-                self.outfile.write('#if GLIB_CHECK_VERSION(2, 44, 0)\n')
-                self.outfile.write('G_DEFINE_AUTOPTR_CLEANUP_FUNC (%s, g_object_unref)\n' % (i.camel_name))
-                self.outfile.write('#endif\n')
-                self.outfile.write('\n')
+                self.outfile.write("%s" % function_pointers[key])
+
+            self.outfile.write("};\n")
+            self.outfile.write("\n")
+            if self.generate_autocleanup == "all":
+                self.outfile.write("#if GLIB_CHECK_VERSION(2, 44, 0)\n")
+                self.outfile.write(
+                    "G_DEFINE_AUTOPTR_CLEANUP_FUNC (%s, g_object_unref)\n"
+                    % (i.camel_name)
+                )
+                self.outfile.write("#endif\n")
+                self.outfile.write("\n")
             if self.symbol_decorator is not None:
-                self.outfile.write('%s\n' % self.symbol_decorator)
-            self.outfile.write('GType %s_get_type (void) G_GNUC_CONST;\n'%(i.name_lower))
-            self.outfile.write('\n')
+                self.outfile.write("%s\n" % self.symbol_decorator)
+            self.outfile.write(
+                "GType %s_get_type (void) G_GNUC_CONST;\n" % (i.name_lower)
+            )
+            self.outfile.write("\n")
             if self.symbol_decorator is not None:
-                self.outfile.write('%s\n' % self.symbol_decorator)
-            self.outfile.write('GDBusInterfaceInfo *%s_interface_info (void);\n'%(i.name_lower))
+                self.outfile.write("%s\n" % self.symbol_decorator)
+            self.outfile.write(
+                "GDBusInterfaceInfo *%s_interface_info (void);\n" % (i.name_lower)
+            )
             if self.symbol_decorator is not None:
-                self.outfile.write('%s\n' % self.symbol_decorator)
-            self.outfile.write('guint %s_override_properties (GObjectClass *klass, guint property_id_begin);\n'%(i.name_lower))
-            self.outfile.write('\n')
+                self.outfile.write("%s\n" % self.symbol_decorator)
+            self.outfile.write(
+                "guint %s_override_properties (GObjectClass *klass, guint property_id_begin);\n"
+                % (i.name_lower)
+            )
+            self.outfile.write("\n")
 
             # Then method call completion functions
             if len(i.methods) > 0:
-                self.outfile.write('\n')
-                self.outfile.write('/* D-Bus method call completion functions: */\n')
+                self.outfile.write("\n")
+                self.outfile.write("/* D-Bus method call completion functions: */\n")
                 for m in i.methods:
                     if self.symbol_decorator is not None:
-                        self.outfile.write('%s\n' % self.symbol_decorator)
+                        self.outfile.write("%s\n" % self.symbol_decorator)
                     if m.deprecated:
-                        self.outfile.write('G_GNUC_DEPRECATED ')
-                    self.outfile.write('void %s_complete_%s (\n'
-                                       '    %s *object,\n'
-                                       '    GDBusMethodInvocation *invocation'%(i.name_lower, m.name_lower, i.camel_name))
+                        self.outfile.write("G_GNUC_DEPRECATED ")
+                    self.outfile.write(
+                        "void %s_complete_%s (\n"
+                        "    %s *object,\n"
+                        "    GDBusMethodInvocation *invocation"
+                        % (i.name_lower, m.name_lower, i.camel_name)
+                    )
                     if m.unix_fd:
-                        self.outfile.write(',\n    GUnixFDList *fd_list')
+                        self.outfile.write(",\n    GUnixFDList *fd_list")
                     for a in m.out_args:
-                        self.outfile.write(',\n    %s%s'%(a.ctype_in, a.name))
-                    self.outfile.write(');\n')
-                    self.outfile.write('\n')
-                self.outfile.write('\n')
+                        self.outfile.write(",\n    %s%s" % (a.ctype_in, a.name))
+                    self.outfile.write(");\n")
+                    self.outfile.write("\n")
+                self.outfile.write("\n")
 
             # Then signal emission functions
             if len(i.signals) > 0:
-                self.outfile.write('\n')
-                self.outfile.write('/* D-Bus signal emissions functions: */\n')
+                self.outfile.write("\n")
+                self.outfile.write("/* D-Bus signal emissions functions: */\n")
                 for s in i.signals:
                     if self.symbol_decorator is not None:
-                        self.outfile.write('%s\n' % self.symbol_decorator)
+                        self.outfile.write("%s\n" % self.symbol_decorator)
                     if s.deprecated:
-                        self.outfile.write('G_GNUC_DEPRECATED ')
-                    self.outfile.write('void %s_emit_%s (\n'
-                                       '    %s *object'%(i.name_lower, s.name_lower, i.camel_name))
+                        self.outfile.write("G_GNUC_DEPRECATED ")
+                    self.outfile.write(
+                        "void %s_emit_%s (\n"
+                        "    %s *object" % (i.name_lower, s.name_lower, i.camel_name)
+                    )
                     for a in s.args:
-                        self.outfile.write(',\n    %sarg_%s'%(a.ctype_in, a.name))
-                    self.outfile.write(');\n')
-                    self.outfile.write('\n')
-                self.outfile.write('\n')
+                        self.outfile.write(",\n    %sarg_%s" % (a.ctype_in, a.name))
+                    self.outfile.write(");\n")
+                    self.outfile.write("\n")
+                self.outfile.write("\n")
 
             # Then method call declarations
             if len(i.methods) > 0:
-                self.outfile.write('\n')
-                self.outfile.write('/* D-Bus method calls: */\n')
+                self.outfile.write("\n")
+                self.outfile.write("/* D-Bus method calls: */\n")
                 for m in i.methods:
                     # async begin
                     if self.symbol_decorator is not None:
-                        self.outfile.write('%s\n' % self.symbol_decorator)
+                        self.outfile.write("%s\n" % self.symbol_decorator)
                     if m.deprecated:
-                        self.outfile.write('G_GNUC_DEPRECATED ')
-                    self.outfile.write('void %s_call_%s (\n'
-                                       '    %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
+                        self.outfile.write("G_GNUC_DEPRECATED ")
+                    self.outfile.write(
+                        "void %s_call_%s (\n"
+                        "    %s *proxy" % (i.name_lower, m.name_lower, i.camel_name)
+                    )
                     for a in m.in_args:
-                        self.outfile.write(',\n    %sarg_%s'%(a.ctype_in, a.name))
+                        self.outfile.write(",\n    %sarg_%s" % (a.ctype_in, a.name))
                     if self.glib_min_required >= (2, 64):
-                        self.outfile.write(',\n    GDBusCallFlags call_flags'
-                                           ',\n    gint timeout_msec')
+                        self.outfile.write(
+                            ",\n    GDBusCallFlags call_flags"
+                            ",\n    gint timeout_msec"
+                        )
                     if m.unix_fd:
-                        self.outfile.write(',\n    GUnixFDList *fd_list')
-                    self.outfile.write(',\n'
-                                       '    GCancellable *cancellable,\n'
-                                       '    GAsyncReadyCallback callback,\n'
-                                       '    gpointer user_data);\n')
-                    self.outfile.write('\n')
+                        self.outfile.write(",\n    GUnixFDList *fd_list")
+                    self.outfile.write(
+                        ",\n"
+                        "    GCancellable *cancellable,\n"
+                        "    GAsyncReadyCallback callback,\n"
+                        "    gpointer user_data);\n"
+                    )
+                    self.outfile.write("\n")
                     # async finish
                     if self.symbol_decorator is not None:
-                        self.outfile.write('%s\n' % self.symbol_decorator)
+                        self.outfile.write("%s\n" % self.symbol_decorator)
                     if m.deprecated:
-                        self.outfile.write('G_GNUC_DEPRECATED ')
-                    self.outfile.write('gboolean %s_call_%s_finish (\n'
-                                       '    %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
+                        self.outfile.write("G_GNUC_DEPRECATED ")
+                    self.outfile.write(
+                        "gboolean %s_call_%s_finish (\n"
+                        "    %s *proxy" % (i.name_lower, m.name_lower, i.camel_name)
+                    )
                     for a in m.out_args:
-                        self.outfile.write(',\n    %sout_%s'%(a.ctype_out, a.name))
+                        self.outfile.write(",\n    %sout_%s" % (a.ctype_out, a.name))
                     if m.unix_fd:
-                        self.outfile.write(',\n    GUnixFDList **out_fd_list')
-                    self.outfile.write(',\n'
-                                       '    GAsyncResult *res,\n'
-                                       '    GError **error);\n')
-                    self.outfile.write('\n')
+                        self.outfile.write(",\n    GUnixFDList **out_fd_list")
+                    self.outfile.write(
+                        ",\n" "    GAsyncResult *res,\n" "    GError **error);\n"
+                    )
+                    self.outfile.write("\n")
                     # sync
                     if self.symbol_decorator is not None:
-                        self.outfile.write('%s\n' % self.symbol_decorator)
+                        self.outfile.write("%s\n" % self.symbol_decorator)
                     if m.deprecated:
-                        self.outfile.write('G_GNUC_DEPRECATED ')
-                    self.outfile.write('gboolean %s_call_%s_sync (\n'
-                                       '    %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
+                        self.outfile.write("G_GNUC_DEPRECATED ")
+                    self.outfile.write(
+                        "gboolean %s_call_%s_sync (\n"
+                        "    %s *proxy" % (i.name_lower, m.name_lower, i.camel_name)
+                    )
                     for a in m.in_args:
-                        self.outfile.write(',\n    %sarg_%s'%(a.ctype_in, a.name))
+                        self.outfile.write(",\n    %sarg_%s" % (a.ctype_in, a.name))
                     if self.glib_min_required >= (2, 64):
-                        self.outfile.write(',\n    GDBusCallFlags call_flags'
-                                           ',\n    gint timeout_msec')
+                        self.outfile.write(
+                            ",\n    GDBusCallFlags call_flags"
+                            ",\n    gint timeout_msec"
+                        )
                     if m.unix_fd:
-                        self.outfile.write(',\n    GUnixFDList  *fd_list')
+                        self.outfile.write(",\n    GUnixFDList  *fd_list")
                     for a in m.out_args:
-                        self.outfile.write(',\n    %sout_%s'%(a.ctype_out, a.name))
+                        self.outfile.write(",\n    %sout_%s" % (a.ctype_out, a.name))
                     if m.unix_fd:
-                        self.outfile.write(',\n    GUnixFDList **out_fd_list')
-                    self.outfile.write(',\n'
-                                       '    GCancellable *cancellable,\n'
-                                       '    GError **error);\n')
-                    self.outfile.write('\n')
-                self.outfile.write('\n')
+                        self.outfile.write(",\n    GUnixFDList **out_fd_list")
+                    self.outfile.write(
+                        ",\n"
+                        "    GCancellable *cancellable,\n"
+                        "    GError **error);\n"
+                    )
+                    self.outfile.write("\n")
+                self.outfile.write("\n")
 
             # Then the property accessor declarations
             if len(i.properties) > 0:
-                self.outfile.write('\n')
-                self.outfile.write('/* D-Bus property accessors: */\n')
+                self.outfile.write("\n")
+                self.outfile.write("/* D-Bus property accessors: */\n")
                 for p in i.properties:
                     # getter
                     if self.symbol_decorator is not None:
-                        self.outfile.write('%s\n' % self.symbol_decorator)
+                        self.outfile.write("%s\n" % self.symbol_decorator)
                     if p.deprecated:
-                        self.outfile.write('G_GNUC_DEPRECATED ')
-                    self.outfile.write('%s%s_get_%s (%s *object);\n'%(p.arg.ctype_in, i.name_lower, p.name_lower, i.camel_name))
-                    if p.arg.free_func != None:
+                        self.outfile.write("G_GNUC_DEPRECATED ")
+                    self.outfile.write(
+                        "%s%s_get_%s (%s *object);\n"
+                        % (p.arg.ctype_in, i.name_lower, p.name_lower, i.camel_name)
+                    )
+                    if p.arg.free_func is not None:
                         if self.symbol_decorator is not None:
-                            self.outfile.write('%s\n' % self.symbol_decorator)
+                            self.outfile.write("%s\n" % self.symbol_decorator)
                         if p.deprecated:
-                            self.outfile.write('G_GNUC_DEPRECATED ')
-                        self.outfile.write('%s%s_dup_%s (%s *object);\n'%(p.arg.ctype_in_dup, i.name_lower, p.name_lower, i.camel_name))
+                            self.outfile.write("G_GNUC_DEPRECATED ")
+                        self.outfile.write(
+                            "%s%s_dup_%s (%s *object);\n"
+                            % (
+                                p.arg.ctype_in_dup,
+                                i.name_lower,
+                                p.name_lower,
+                                i.camel_name,
+                            )
+                        )
                     # setter
                     if self.symbol_decorator is not None:
-                        self.outfile.write('%s\n' % self.symbol_decorator)
+                        self.outfile.write("%s\n" % self.symbol_decorator)
                     if p.deprecated:
-                        self.outfile.write('G_GNUC_DEPRECATED ')
-                    self.outfile.write('void %s_set_%s (%s *object, %svalue);\n'%(i.name_lower, p.name_lower, i.camel_name, p.arg.ctype_in, ))
-                    self.outfile.write('\n')
+                        self.outfile.write("G_GNUC_DEPRECATED ")
+                    self.outfile.write(
+                        "void %s_set_%s (%s *object, %svalue);\n"
+                        % (i.name_lower, p.name_lower, i.camel_name, p.arg.ctype_in,)
+                    )
+                    self.outfile.write("\n")
 
             # Then the proxy
-            self.outfile.write('\n')
-            self.outfile.write('/* ---- */\n')
-            self.outfile.write('\n')
-            self.outfile.write('#define %sTYPE_%s_PROXY (%s_proxy_get_type ())\n'%(i.ns_upper, i.name_upper, i.name_lower))
-            self.outfile.write('#define %s%s_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_%s_PROXY, %sProxy))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
-            self.outfile.write('#define %s%s_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_%s_PROXY, %sProxyClass))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
-            self.outfile.write('#define %s%s_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_%s_PROXY, %sProxyClass))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
-            self.outfile.write('#define %sIS_%s_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_%s_PROXY))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper))
-            self.outfile.write('#define %sIS_%s_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_%s_PROXY))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper))
-            self.outfile.write('\n')
-            self.outfile.write('typedef struct _%sProxy %sProxy;\n'%(i.camel_name, i.camel_name))
-            self.outfile.write('typedef struct _%sProxyClass %sProxyClass;\n'%(i.camel_name, i.camel_name))
-            self.outfile.write('typedef struct _%sProxyPrivate %sProxyPrivate;\n'%(i.camel_name, i.camel_name))
-            self.outfile.write('\n')
-            self.outfile.write('struct _%sProxy\n'%(i.camel_name))
-            self.outfile.write('{\n')
-            self.outfile.write('  /*< private >*/\n')
-            self.outfile.write('  GDBusProxy parent_instance;\n')
-            self.outfile.write('  %sProxyPrivate *priv;\n'%(i.camel_name))
-            self.outfile.write('};\n')
-            self.outfile.write('\n')
-            self.outfile.write('struct _%sProxyClass\n'%(i.camel_name))
-            self.outfile.write('{\n')
-            self.outfile.write('  GDBusProxyClass parent_class;\n')
-            self.outfile.write('};\n')
-            self.outfile.write('\n')
+            self.outfile.write("\n")
+            self.outfile.write("/* ---- */\n")
+            self.outfile.write("\n")
+            self.outfile.write(
+                "#define %sTYPE_%s_PROXY (%s_proxy_get_type ())\n"
+                % (i.ns_upper, i.name_upper, i.name_lower)
+            )
+            self.outfile.write(
+                "#define %s%s_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_%s_PROXY, %sProxy))\n"
+                % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name)
+            )
+            self.outfile.write(
+                "#define %s%s_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_%s_PROXY, %sProxyClass))\n"
+                % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name)
+            )
+            self.outfile.write(
+                "#define %s%s_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_%s_PROXY, %sProxyClass))\n"
+                % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name)
+            )
+            self.outfile.write(
+                "#define %sIS_%s_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_%s_PROXY))\n"
+                % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper)
+            )
+            self.outfile.write(
+                "#define %sIS_%s_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_%s_PROXY))\n"
+                % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper)
+            )
+            self.outfile.write("\n")
+            self.outfile.write(
+                "typedef struct _%sProxy %sProxy;\n" % (i.camel_name, i.camel_name)
+            )
+            self.outfile.write(
+                "typedef struct _%sProxyClass %sProxyClass;\n"
+                % (i.camel_name, i.camel_name)
+            )
+            self.outfile.write(
+                "typedef struct _%sProxyPrivate %sProxyPrivate;\n"
+                % (i.camel_name, i.camel_name)
+            )
+            self.outfile.write("\n")
+            self.outfile.write("struct _%sProxy\n" % (i.camel_name))
+            self.outfile.write("{\n")
+            self.outfile.write("  /*< private >*/\n")
+            self.outfile.write("  GDBusProxy parent_instance;\n")
+            self.outfile.write("  %sProxyPrivate *priv;\n" % (i.camel_name))
+            self.outfile.write("};\n")
+            self.outfile.write("\n")
+            self.outfile.write("struct _%sProxyClass\n" % (i.camel_name))
+            self.outfile.write("{\n")
+            self.outfile.write("  GDBusProxyClass parent_class;\n")
+            self.outfile.write("};\n")
+            self.outfile.write("\n")
             if self.symbol_decorator is not None:
-                self.outfile.write('%s\n' % self.symbol_decorator)
-            self.outfile.write('GType %s_proxy_get_type (void) G_GNUC_CONST;\n'%(i.name_lower))
-            self.outfile.write('\n')
-            if self.generate_autocleanup in ('objects', 'all'):
-                self.outfile.write('#if GLIB_CHECK_VERSION(2, 44, 0)\n')
-                self.outfile.write('G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sProxy, g_object_unref)\n' % (i.camel_name))
-                self.outfile.write('#endif\n')
-                self.outfile.write('\n')
+                self.outfile.write("%s\n" % self.symbol_decorator)
+            self.outfile.write(
+                "GType %s_proxy_get_type (void) G_GNUC_CONST;\n" % (i.name_lower)
+            )
+            self.outfile.write("\n")
+            if self.generate_autocleanup in ("objects", "all"):
+                self.outfile.write("#if GLIB_CHECK_VERSION(2, 44, 0)\n")
+                self.outfile.write(
+                    "G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sProxy, g_object_unref)\n"
+                    % (i.camel_name)
+                )
+                self.outfile.write("#endif\n")
+                self.outfile.write("\n")
             if self.symbol_decorator is not None:
-                self.outfile.write('%s\n' % self.symbol_decorator)
+                self.outfile.write("%s\n" % self.symbol_decorator)
             if i.deprecated:
-                self.outfile.write('G_GNUC_DEPRECATED ')
-            self.outfile.write('void %s_proxy_new (\n'
-                               '    GDBusConnection     *connection,\n'
-                               '    GDBusProxyFlags      flags,\n'
-                               '    const gchar         *name,\n'
-                               '    const gchar         *object_path,\n'
-                               '    GCancellable        *cancellable,\n'
-                               '    GAsyncReadyCallback  callback,\n'
-                               '    gpointer             user_data);\n'
-                               %(i.name_lower))
+                self.outfile.write("G_GNUC_DEPRECATED ")
+            self.outfile.write(
+                "void %s_proxy_new (\n"
+                "    GDBusConnection     *connection,\n"
+                "    GDBusProxyFlags      flags,\n"
+                "    const gchar         *name,\n"
+                "    const gchar         *object_path,\n"
+                "    GCancellable        *cancellable,\n"
+                "    GAsyncReadyCallback  callback,\n"
+                "    gpointer             user_data);\n" % (i.name_lower)
+            )
             if self.symbol_decorator is not None:
-                self.outfile.write('%s\n' % self.symbol_decorator)
+                self.outfile.write("%s\n" % self.symbol_decorator)
             if i.deprecated:
-                self.outfile.write('G_GNUC_DEPRECATED ')
-            self.outfile.write('%s *%s_proxy_new_finish (\n'
-                               '    GAsyncResult        *res,\n'
-                               '    GError             **error);\n'
-                               %(i.camel_name, i.name_lower))
+                self.outfile.write("G_GNUC_DEPRECATED ")
+            self.outfile.write(
+                "%s *%s_proxy_new_finish (\n"
+                "    GAsyncResult        *res,\n"
+                "    GError             **error);\n" % (i.camel_name, i.name_lower)
+            )
             if self.symbol_decorator is not None:
-                self.outfile.write('%s\n' % self.symbol_decorator)
+                self.outfile.write("%s\n" % self.symbol_decorator)
             if i.deprecated:
-                self.outfile.write('G_GNUC_DEPRECATED ')
-            self.outfile.write('%s *%s_proxy_new_sync (\n'
-                               '    GDBusConnection     *connection,\n'
-                               '    GDBusProxyFlags      flags,\n'
-                               '    const gchar         *name,\n'
-                               '    const gchar         *object_path,\n'
-                               '    GCancellable        *cancellable,\n'
-                               '    GError             **error);\n'
-                               %(i.camel_name, i.name_lower))
-            self.outfile.write('\n')
+                self.outfile.write("G_GNUC_DEPRECATED ")
+            self.outfile.write(
+                "%s *%s_proxy_new_sync (\n"
+                "    GDBusConnection     *connection,\n"
+                "    GDBusProxyFlags      flags,\n"
+                "    const gchar         *name,\n"
+                "    const gchar         *object_path,\n"
+                "    GCancellable        *cancellable,\n"
+                "    GError             **error);\n" % (i.camel_name, i.name_lower)
+            )
+            self.outfile.write("\n")
             if self.symbol_decorator is not None:
-                self.outfile.write('%s\n' % self.symbol_decorator)
+                self.outfile.write("%s\n" % self.symbol_decorator)
             if i.deprecated:
-                self.outfile.write('G_GNUC_DEPRECATED ')
-            self.outfile.write('void %s_proxy_new_for_bus (\n'
-                               '    GBusType             bus_type,\n'
-                               '    GDBusProxyFlags      flags,\n'
-                               '    const gchar         *name,\n'
-                               '    const gchar         *object_path,\n'
-                               '    GCancellable        *cancellable,\n'
-                               '    GAsyncReadyCallback  callback,\n'
-                               '    gpointer             user_data);\n'
-                               %(i.name_lower))
+                self.outfile.write("G_GNUC_DEPRECATED ")
+            self.outfile.write(
+                "void %s_proxy_new_for_bus (\n"
+                "    GBusType             bus_type,\n"
+                "    GDBusProxyFlags      flags,\n"
+                "    const gchar         *name,\n"
+                "    const gchar         *object_path,\n"
+                "    GCancellable        *cancellable,\n"
+                "    GAsyncReadyCallback  callback,\n"
+                "    gpointer             user_data);\n" % (i.name_lower)
+            )
             if self.symbol_decorator is not None:
-                self.outfile.write('%s\n' % self.symbol_decorator)
+                self.outfile.write("%s\n" % self.symbol_decorator)
             if i.deprecated:
-                self.outfile.write('G_GNUC_DEPRECATED ')
-            self.outfile.write('%s *%s_proxy_new_for_bus_finish (\n'
-                               '    GAsyncResult        *res,\n'
-                               '    GError             **error);\n'
-                               %(i.camel_name, i.name_lower))
+                self.outfile.write("G_GNUC_DEPRECATED ")
+            self.outfile.write(
+                "%s *%s_proxy_new_for_bus_finish (\n"
+                "    GAsyncResult        *res,\n"
+                "    GError             **error);\n" % (i.camel_name, i.name_lower)
+            )
             if self.symbol_decorator is not None:
-                self.outfile.write('%s\n' % self.symbol_decorator)
+                self.outfile.write("%s\n" % self.symbol_decorator)
             if i.deprecated:
-                self.outfile.write('G_GNUC_DEPRECATED ')
-            self.outfile.write('%s *%s_proxy_new_for_bus_sync (\n'
-                               '    GBusType             bus_type,\n'
-                               '    GDBusProxyFlags      flags,\n'
-                               '    const gchar         *name,\n'
-                               '    const gchar         *object_path,\n'
-                               '    GCancellable        *cancellable,\n'
-                               '    GError             **error);\n'
-                               %(i.camel_name, i.name_lower))
-            self.outfile.write('\n')
+                self.outfile.write("G_GNUC_DEPRECATED ")
+            self.outfile.write(
+                "%s *%s_proxy_new_for_bus_sync (\n"
+                "    GBusType             bus_type,\n"
+                "    GDBusProxyFlags      flags,\n"
+                "    const gchar         *name,\n"
+                "    const gchar         *object_path,\n"
+                "    GCancellable        *cancellable,\n"
+                "    GError             **error);\n" % (i.camel_name, i.name_lower)
+            )
+            self.outfile.write("\n")
 
             # Then the skeleton
-            self.outfile.write('\n')
-            self.outfile.write('/* ---- */\n')
-            self.outfile.write('\n')
-            self.outfile.write('#define %sTYPE_%s_SKELETON (%s_skeleton_get_type ())\n'%(i.ns_upper, i.name_upper, i.name_lower))
-            self.outfile.write('#define %s%s_SKELETON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_%s_SKELETON, %sSkeleton))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
-            self.outfile.write('#define %s%s_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_%s_SKELETON, %sSkeletonClass))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
-            self.outfile.write('#define %s%s_SKELETON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_%s_SKELETON, %sSkeletonClass))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
-            self.outfile.write('#define %sIS_%s_SKELETON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_%s_SKELETON))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper))
-            self.outfile.write('#define %sIS_%s_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_%s_SKELETON))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper))
-            self.outfile.write('\n')
-            self.outfile.write('typedef struct _%sSkeleton %sSkeleton;\n'%(i.camel_name, i.camel_name))
-            self.outfile.write('typedef struct _%sSkeletonClass %sSkeletonClass;\n'%(i.camel_name, i.camel_name))
-            self.outfile.write('typedef struct _%sSkeletonPrivate %sSkeletonPrivate;\n'%(i.camel_name, i.camel_name))
-            self.outfile.write('\n')
-            self.outfile.write('struct _%sSkeleton\n'%(i.camel_name))
-            self.outfile.write('{\n')
-            self.outfile.write('  /*< private >*/\n')
-            self.outfile.write('  GDBusInterfaceSkeleton parent_instance;\n')
-            self.outfile.write('  %sSkeletonPrivate *priv;\n'%(i.camel_name))
-            self.outfile.write('};\n')
-            self.outfile.write('\n')
-            self.outfile.write('struct _%sSkeletonClass\n'%(i.camel_name))
-            self.outfile.write('{\n')
-            self.outfile.write('  GDBusInterfaceSkeletonClass parent_class;\n')
-            self.outfile.write('};\n')
-            self.outfile.write('\n')
+            self.outfile.write("\n")
+            self.outfile.write("/* ---- */\n")
+            self.outfile.write("\n")
+            self.outfile.write(
+                "#define %sTYPE_%s_SKELETON (%s_skeleton_get_type ())\n"
+                % (i.ns_upper, i.name_upper, i.name_lower)
+            )
+            self.outfile.write(
+                "#define %s%s_SKELETON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_%s_SKELETON, %sSkeleton))\n"
+                % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name)
+            )
+            self.outfile.write(
+                "#define %s%s_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_%s_SKELETON, %sSkeletonClass))\n"
+                % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name)
+            )
+            self.outfile.write(
+                "#define %s%s_SKELETON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_%s_SKELETON, %sSkeletonClass))\n"
+                % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name)
+            )
+            self.outfile.write(
+                "#define %sIS_%s_SKELETON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_%s_SKELETON))\n"
+                % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper)
+            )
+            self.outfile.write(
+                "#define %sIS_%s_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_%s_SKELETON))\n"
+                % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper)
+            )
+            self.outfile.write("\n")
+            self.outfile.write(
+                "typedef struct _%sSkeleton %sSkeleton;\n"
+                % (i.camel_name, i.camel_name)
+            )
+            self.outfile.write(
+                "typedef struct _%sSkeletonClass %sSkeletonClass;\n"
+                % (i.camel_name, i.camel_name)
+            )
+            self.outfile.write(
+                "typedef struct _%sSkeletonPrivate %sSkeletonPrivate;\n"
+                % (i.camel_name, i.camel_name)
+            )
+            self.outfile.write("\n")
+            self.outfile.write("struct _%sSkeleton\n" % (i.camel_name))
+            self.outfile.write("{\n")
+            self.outfile.write("  /*< private >*/\n")
+            self.outfile.write("  GDBusInterfaceSkeleton parent_instance;\n")
+            self.outfile.write("  %sSkeletonPrivate *priv;\n" % (i.camel_name))
+            self.outfile.write("};\n")
+            self.outfile.write("\n")
+            self.outfile.write("struct _%sSkeletonClass\n" % (i.camel_name))
+            self.outfile.write("{\n")
+            self.outfile.write("  GDBusInterfaceSkeletonClass parent_class;\n")
+            self.outfile.write("};\n")
+            self.outfile.write("\n")
             if self.symbol_decorator is not None:
-                self.outfile.write('%s\n' % self.symbol_decorator)
-            self.outfile.write('GType %s_skeleton_get_type (void) G_GNUC_CONST;\n'%(i.name_lower))
-            self.outfile.write('\n')
-            if self.generate_autocleanup in ('objects', 'all'):
-                self.outfile.write('#if GLIB_CHECK_VERSION(2, 44, 0)\n')
-                self.outfile.write('G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sSkeleton, g_object_unref)\n' % (i.camel_name))
-                self.outfile.write('#endif\n')
-                self.outfile.write('\n')
+                self.outfile.write("%s\n" % self.symbol_decorator)
+            self.outfile.write(
+                "GType %s_skeleton_get_type (void) G_GNUC_CONST;\n" % (i.name_lower)
+            )
+            self.outfile.write("\n")
+            if self.generate_autocleanup in ("objects", "all"):
+                self.outfile.write("#if GLIB_CHECK_VERSION(2, 44, 0)\n")
+                self.outfile.write(
+                    "G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sSkeleton, g_object_unref)\n"
+                    % (i.camel_name)
+                )
+                self.outfile.write("#endif\n")
+                self.outfile.write("\n")
             if self.symbol_decorator is not None:
-                self.outfile.write('%s\n' % self.symbol_decorator)
+                self.outfile.write("%s\n" % self.symbol_decorator)
             if i.deprecated:
-                self.outfile.write('G_GNUC_DEPRECATED ')
-            self.outfile.write('%s *%s_skeleton_new (void);\n'%(i.camel_name, i.name_lower))
+                self.outfile.write("G_GNUC_DEPRECATED ")
+            self.outfile.write(
+                "%s *%s_skeleton_new (void);\n" % (i.camel_name, i.name_lower)
+            )
 
-            self.outfile.write('\n')
+            self.outfile.write("\n")
 
         # Finally, the Object, ObjectProxy, ObjectSkeleton and ObjectManagerClient
         if self.generate_objmanager:
-            self.outfile.write('\n')
-            self.outfile.write('/* ---- */\n')
-            self.outfile.write('\n')
-            self.outfile.write('#define %sTYPE_OBJECT (%sobject_get_type ())\n'%(self.ns_upper, self.ns_lower))
-            self.outfile.write('#define %sOBJECT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT, %sObject))\n'%(self.ns_upper, self.ns_upper, self.namespace))
-            self.outfile.write('#define %sIS_OBJECT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT))\n'%(self.ns_upper, self.ns_upper))
-            self.outfile.write('#define %sOBJECT_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), %sTYPE_OBJECT, %sObject))\n'%(self.ns_upper, self.ns_upper, self.namespace))
-            self.outfile.write('\n')
-            self.outfile.write('struct _%sObject;\n'%(self.namespace))
-            self.outfile.write('typedef struct _%sObject %sObject;\n'%(self.namespace, self.namespace))
-            self.outfile.write('typedef struct _%sObjectIface %sObjectIface;\n'%(self.namespace, self.namespace))
-            self.outfile.write('\n')
-            self.outfile.write('struct _%sObjectIface\n'%(self.namespace))
-            self.outfile.write('{\n'
-                               '  GTypeInterface parent_iface;\n'
-                               '};\n'
-                               '\n')
+            self.outfile.write("\n")
+            self.outfile.write("/* ---- */\n")
+            self.outfile.write("\n")
+            self.outfile.write(
+                "#define %sTYPE_OBJECT (%sobject_get_type ())\n"
+                % (self.ns_upper, self.ns_lower)
+            )
+            self.outfile.write(
+                "#define %sOBJECT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT, %sObject))\n"
+                % (self.ns_upper, self.ns_upper, self.namespace)
+            )
+            self.outfile.write(
+                "#define %sIS_OBJECT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT))\n"
+                % (self.ns_upper, self.ns_upper)
+            )
+            self.outfile.write(
+                "#define %sOBJECT_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), %sTYPE_OBJECT, %sObject))\n"
+                % (self.ns_upper, self.ns_upper, self.namespace)
+            )
+            self.outfile.write("\n")
+            self.outfile.write("struct _%sObject;\n" % (self.namespace))
+            self.outfile.write(
+                "typedef struct _%sObject %sObject;\n"
+                % (self.namespace, self.namespace)
+            )
+            self.outfile.write(
+                "typedef struct _%sObjectIface %sObjectIface;\n"
+                % (self.namespace, self.namespace)
+            )
+            self.outfile.write("\n")
+            self.outfile.write("struct _%sObjectIface\n" % (self.namespace))
+            self.outfile.write("{\n" "  GTypeInterface parent_iface;\n" "};\n" "\n")
             if self.symbol_decorator is not None:
-                self.outfile.write('%s\n' % self.symbol_decorator)
-            self.outfile.write('GType %sobject_get_type (void) G_GNUC_CONST;\n'
-                               '\n'
-                               %(self.ns_lower))
-            if self.generate_autocleanup == 'all':
-                self.outfile.write('#if GLIB_CHECK_VERSION(2, 44, 0)\n')
-                self.outfile.write('G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sObject, g_object_unref)\n' % (self.namespace))
-                self.outfile.write('#endif\n')
-                self.outfile.write('\n')
+                self.outfile.write("%s\n" % self.symbol_decorator)
+            self.outfile.write(
+                "GType %sobject_get_type (void) G_GNUC_CONST;\n" "\n" % (self.ns_lower)
+            )
+            if self.generate_autocleanup == "all":
+                self.outfile.write("#if GLIB_CHECK_VERSION(2, 44, 0)\n")
+                self.outfile.write(
+                    "G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sObject, g_object_unref)\n"
+                    % (self.namespace)
+                )
+                self.outfile.write("#endif\n")
+                self.outfile.write("\n")
             for i in self.ifaces:
                 if self.symbol_decorator is not None:
-                    self.outfile.write('%s\n' % self.symbol_decorator)
+                    self.outfile.write("%s\n" % self.symbol_decorator)
                 if i.deprecated:
-                    self.outfile.write('G_GNUC_DEPRECATED ')
-                self.outfile.write('%s *%sobject_get_%s (%sObject *object);\n'
-                                   %(i.camel_name, self.ns_lower, i.name_upper.lower(), self.namespace))
+                    self.outfile.write("G_GNUC_DEPRECATED ")
+                self.outfile.write(
+                    "%s *%sobject_get_%s (%sObject *object);\n"
+                    % (
+                        i.camel_name,
+                        self.ns_lower,
+                        i.name_upper.lower(),
+                        self.namespace,
+                    )
+                )
             for i in self.ifaces:
                 if self.symbol_decorator is not None:
-                    self.outfile.write('%s\n' % self.symbol_decorator)
+                    self.outfile.write("%s\n" % self.symbol_decorator)
                 if i.deprecated:
-                    self.outfile.write('G_GNUC_DEPRECATED ')
-                self.outfile.write('%s *%sobject_peek_%s (%sObject *object);\n'
-                                   %(i.camel_name, self.ns_lower, i.name_upper.lower(), self.namespace))
-            self.outfile.write('\n')
-            self.outfile.write('#define %sTYPE_OBJECT_PROXY (%sobject_proxy_get_type ())\n'%(self.ns_upper, self.ns_lower))
-            self.outfile.write('#define %sOBJECT_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT_PROXY, %sObjectProxy))\n'%(self.ns_upper, self.ns_upper, self.namespace))
-            self.outfile.write('#define %sOBJECT_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_OBJECT_PROXY, %sObjectProxyClass))\n'%(self.ns_upper, self.ns_upper, self.namespace))
-            self.outfile.write('#define %sOBJECT_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_OBJECT_PROXY, %sObjectProxyClass))\n'%(self.ns_upper, self.ns_upper, self.namespace))
-            self.outfile.write('#define %sIS_OBJECT_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT_PROXY))\n'%(self.ns_upper, self.ns_upper))
-            self.outfile.write('#define %sIS_OBJECT_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_OBJECT_PROXY))\n'%(self.ns_upper, self.ns_upper))
-            self.outfile.write('\n')
-            self.outfile.write('typedef struct _%sObjectProxy %sObjectProxy;\n'%(self.namespace, self.namespace))
-            self.outfile.write('typedef struct _%sObjectProxyClass %sObjectProxyClass;\n'%(self.namespace, self.namespace))
-            self.outfile.write('typedef struct _%sObjectProxyPrivate %sObjectProxyPrivate;\n'%(self.namespace, self.namespace))
-            self.outfile.write('\n')
-            self.outfile.write('struct _%sObjectProxy\n'%(self.namespace))
-            self.outfile.write('{\n')
-            self.outfile.write('  /*< private >*/\n')
-            self.outfile.write('  GDBusObjectProxy parent_instance;\n')
-            self.outfile.write('  %sObjectProxyPrivate *priv;\n'%(self.namespace))
-            self.outfile.write('};\n')
-            self.outfile.write('\n')
-            self.outfile.write('struct _%sObjectProxyClass\n'%(self.namespace))
-            self.outfile.write('{\n')
-            self.outfile.write('  GDBusObjectProxyClass parent_class;\n')
-            self.outfile.write('};\n')
-            self.outfile.write('\n')
+                    self.outfile.write("G_GNUC_DEPRECATED ")
+                self.outfile.write(
+                    "%s *%sobject_peek_%s (%sObject *object);\n"
+                    % (
+                        i.camel_name,
+                        self.ns_lower,
+                        i.name_upper.lower(),
+                        self.namespace,
+                    )
+                )
+            self.outfile.write("\n")
+            self.outfile.write(
+                "#define %sTYPE_OBJECT_PROXY (%sobject_proxy_get_type ())\n"
+                % (self.ns_upper, self.ns_lower)
+            )
+            self.outfile.write(
+                "#define %sOBJECT_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT_PROXY, %sObjectProxy))\n"
+                % (self.ns_upper, self.ns_upper, self.namespace)
+            )
+            self.outfile.write(
+                "#define %sOBJECT_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_OBJECT_PROXY, %sObjectProxyClass))\n"
+                % (self.ns_upper, self.ns_upper, self.namespace)
+            )
+            self.outfile.write(
+                "#define %sOBJECT_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_OBJECT_PROXY, %sObjectProxyClass))\n"
+                % (self.ns_upper, self.ns_upper, self.namespace)
+            )
+            self.outfile.write(
+                "#define %sIS_OBJECT_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT_PROXY))\n"
+                % (self.ns_upper, self.ns_upper)
+            )
+            self.outfile.write(
+                "#define %sIS_OBJECT_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_OBJECT_PROXY))\n"
+                % (self.ns_upper, self.ns_upper)
+            )
+            self.outfile.write("\n")
+            self.outfile.write(
+                "typedef struct _%sObjectProxy %sObjectProxy;\n"
+                % (self.namespace, self.namespace)
+            )
+            self.outfile.write(
+                "typedef struct _%sObjectProxyClass %sObjectProxyClass;\n"
+                % (self.namespace, self.namespace)
+            )
+            self.outfile.write(
+                "typedef struct _%sObjectProxyPrivate %sObjectProxyPrivate;\n"
+                % (self.namespace, self.namespace)
+            )
+            self.outfile.write("\n")
+            self.outfile.write("struct _%sObjectProxy\n" % (self.namespace))
+            self.outfile.write("{\n")
+            self.outfile.write("  /*< private >*/\n")
+            self.outfile.write("  GDBusObjectProxy parent_instance;\n")
+            self.outfile.write("  %sObjectProxyPrivate *priv;\n" % (self.namespace))
+            self.outfile.write("};\n")
+            self.outfile.write("\n")
+            self.outfile.write("struct _%sObjectProxyClass\n" % (self.namespace))
+            self.outfile.write("{\n")
+            self.outfile.write("  GDBusObjectProxyClass parent_class;\n")
+            self.outfile.write("};\n")
+            self.outfile.write("\n")
             if self.symbol_decorator is not None:
-                self.outfile.write('%s\n' % self.symbol_decorator)
-            self.outfile.write('GType %sobject_proxy_get_type (void) G_GNUC_CONST;\n'%(self.ns_lower))
-            self.outfile.write('\n')
-            if self.generate_autocleanup in ('objects', 'all'):
-                self.outfile.write('#if GLIB_CHECK_VERSION(2, 44, 0)\n')
-                self.outfile.write('G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sObjectProxy, g_object_unref)\n' % (self.namespace))
-                self.outfile.write('#endif\n')
-                self.outfile.write('\n')
+                self.outfile.write("%s\n" % self.symbol_decorator)
+            self.outfile.write(
+                "GType %sobject_proxy_get_type (void) G_GNUC_CONST;\n" % (self.ns_lower)
+            )
+            self.outfile.write("\n")
+            if self.generate_autocleanup in ("objects", "all"):
+                self.outfile.write("#if GLIB_CHECK_VERSION(2, 44, 0)\n")
+                self.outfile.write(
+                    "G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sObjectProxy, g_object_unref)\n"
+                    % (self.namespace)
+                )
+                self.outfile.write("#endif\n")
+                self.outfile.write("\n")
             if self.symbol_decorator is not None:
-                self.outfile.write('%s\n' % self.symbol_decorator)
-            self.outfile.write('%sObjectProxy *%sobject_proxy_new (GDBusConnection *connection, const gchar *object_path);\n'%(self.namespace, self.ns_lower))
-            self.outfile.write('\n')
-            self.outfile.write('#define %sTYPE_OBJECT_SKELETON (%sobject_skeleton_get_type ())\n'%(self.ns_upper, self.ns_lower))
-            self.outfile.write('#define %sOBJECT_SKELETON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT_SKELETON, %sObjectSkeleton))\n'%(self.ns_upper, self.ns_upper, self.namespace))
-            self.outfile.write('#define %sOBJECT_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_OBJECT_SKELETON, %sObjectSkeletonClass))\n'%(self.ns_upper, self.ns_upper, self.namespace))
-            self.outfile.write('#define %sOBJECT_SKELETON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_OBJECT_SKELETON, %sObjectSkeletonClass))\n'%(self.ns_upper, self.ns_upper, self.namespace))
-            self.outfile.write('#define %sIS_OBJECT_SKELETON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT_SKELETON))\n'%(self.ns_upper, self.ns_upper))
-            self.outfile.write('#define %sIS_OBJECT_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_OBJECT_SKELETON))\n'%(self.ns_upper, self.ns_upper))
-            self.outfile.write('\n')
-            self.outfile.write('typedef struct _%sObjectSkeleton %sObjectSkeleton;\n'%(self.namespace, self.namespace))
-            self.outfile.write('typedef struct _%sObjectSkeletonClass %sObjectSkeletonClass;\n'%(self.namespace, self.namespace))
-            self.outfile.write('typedef struct _%sObjectSkeletonPrivate %sObjectSkeletonPrivate;\n'%(self.namespace, self.namespace))
-            self.outfile.write('\n')
-            self.outfile.write('struct _%sObjectSkeleton\n'%(self.namespace))
-            self.outfile.write('{\n')
-            self.outfile.write('  /*< private >*/\n')
-            self.outfile.write('  GDBusObjectSkeleton parent_instance;\n')
-            self.outfile.write('  %sObjectSkeletonPrivate *priv;\n'%(self.namespace))
-            self.outfile.write('};\n')
-            self.outfile.write('\n')
-            self.outfile.write('struct _%sObjectSkeletonClass\n'%(self.namespace))
-            self.outfile.write('{\n')
-            self.outfile.write('  GDBusObjectSkeletonClass parent_class;\n')
-            self.outfile.write('};\n')
-            self.outfile.write('\n')
+                self.outfile.write("%s\n" % self.symbol_decorator)
+            self.outfile.write(
+                "%sObjectProxy *%sobject_proxy_new (GDBusConnection *connection, const gchar *object_path);\n"
+                % (self.namespace, self.ns_lower)
+            )
+            self.outfile.write("\n")
+            self.outfile.write(
+                "#define %sTYPE_OBJECT_SKELETON (%sobject_skeleton_get_type ())\n"
+                % (self.ns_upper, self.ns_lower)
+            )
+            self.outfile.write(
+                "#define %sOBJECT_SKELETON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT_SKELETON, %sObjectSkeleton))\n"
+                % (self.ns_upper, self.ns_upper, self.namespace)
+            )
+            self.outfile.write(
+                "#define %sOBJECT_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_OBJECT_SKELETON, %sObjectSkeletonClass))\n"
+                % (self.ns_upper, self.ns_upper, self.namespace)
+            )
+            self.outfile.write(
+                "#define %sOBJECT_SKELETON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_OBJECT_SKELETON, %sObjectSkeletonClass))\n"
+                % (self.ns_upper, self.ns_upper, self.namespace)
+            )
+            self.outfile.write(
+                "#define %sIS_OBJECT_SKELETON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT_SKELETON))\n"
+                % (self.ns_upper, self.ns_upper)
+            )
+            self.outfile.write(
+                "#define %sIS_OBJECT_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_OBJECT_SKELETON))\n"
+                % (self.ns_upper, self.ns_upper)
+            )
+            self.outfile.write("\n")
+            self.outfile.write(
+                "typedef struct _%sObjectSkeleton %sObjectSkeleton;\n"
+                % (self.namespace, self.namespace)
+            )
+            self.outfile.write(
+                "typedef struct _%sObjectSkeletonClass %sObjectSkeletonClass;\n"
+                % (self.namespace, self.namespace)
+            )
+            self.outfile.write(
+                "typedef struct _%sObjectSkeletonPrivate %sObjectSkeletonPrivate;\n"
+                % (self.namespace, self.namespace)
+            )
+            self.outfile.write("\n")
+            self.outfile.write("struct _%sObjectSkeleton\n" % (self.namespace))
+            self.outfile.write("{\n")
+            self.outfile.write("  /*< private >*/\n")
+            self.outfile.write("  GDBusObjectSkeleton parent_instance;\n")
+            self.outfile.write("  %sObjectSkeletonPrivate *priv;\n" % (self.namespace))
+            self.outfile.write("};\n")
+            self.outfile.write("\n")
+            self.outfile.write("struct _%sObjectSkeletonClass\n" % (self.namespace))
+            self.outfile.write("{\n")
+            self.outfile.write("  GDBusObjectSkeletonClass parent_class;\n")
+            self.outfile.write("};\n")
+            self.outfile.write("\n")
             if self.symbol_decorator is not None:
-                self.outfile.write('%s\n' % self.symbol_decorator)
-            self.outfile.write('GType %sobject_skeleton_get_type (void) G_GNUC_CONST;\n'%(self.ns_lower))
-            self.outfile.write('\n')
-            if self.generate_autocleanup in ('objects', 'all'):
-                self.outfile.write('#if GLIB_CHECK_VERSION(2, 44, 0)\n')
-                self.outfile.write('G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sObjectSkeleton, g_object_unref)\n' % (self.namespace))
-                self.outfile.write('#endif\n')
-                self.outfile.write('\n')
+                self.outfile.write("%s\n" % self.symbol_decorator)
+            self.outfile.write(
+                "GType %sobject_skeleton_get_type (void) G_GNUC_CONST;\n"
+                % (self.ns_lower)
+            )
+            self.outfile.write("\n")
+            if self.generate_autocleanup in ("objects", "all"):
+                self.outfile.write("#if GLIB_CHECK_VERSION(2, 44, 0)\n")
+                self.outfile.write(
+                    "G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sObjectSkeleton, g_object_unref)\n"
+                    % (self.namespace)
+                )
+                self.outfile.write("#endif\n")
+                self.outfile.write("\n")
             if self.symbol_decorator is not None:
-                self.outfile.write('%s\n' % self.symbol_decorator)
-            self.outfile.write('%sObjectSkeleton *%sobject_skeleton_new (const gchar *object_path);\n'
-                               %(self.namespace, self.ns_lower))
+                self.outfile.write("%s\n" % self.symbol_decorator)
+            self.outfile.write(
+                "%sObjectSkeleton *%sobject_skeleton_new (const gchar *object_path);\n"
+                % (self.namespace, self.ns_lower)
+            )
             for i in self.ifaces:
                 if self.symbol_decorator is not None:
-                    self.outfile.write('%s\n' % self.symbol_decorator)
+                    self.outfile.write("%s\n" % self.symbol_decorator)
                 if i.deprecated:
-                    self.outfile.write('G_GNUC_DEPRECATED ')
-                self.outfile.write('void %sobject_skeleton_set_%s (%sObjectSkeleton *object, %s *interface_);\n'
-                                   %(self.ns_lower, i.name_upper.lower(), self.namespace, i.camel_name))
-            self.outfile.write('\n')
-
-            self.outfile.write('/* ---- */\n')
-            self.outfile.write('\n')
-            self.outfile.write('#define %sTYPE_OBJECT_MANAGER_CLIENT (%sobject_manager_client_get_type ())\n'%(self.ns_upper, self.ns_lower))
-            self.outfile.write('#define %sOBJECT_MANAGER_CLIENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT_MANAGER_CLIENT, %sObjectManagerClient))\n'%(self.ns_upper, self.ns_upper, self.namespace))
-            self.outfile.write('#define %sOBJECT_MANAGER_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_OBJECT_MANAGER_CLIENT, %sObjectManagerClientClass))\n'%(self.ns_upper, self.ns_upper, self.namespace))
-            self.outfile.write('#define %sOBJECT_MANAGER_CLIENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_OBJECT_MANAGER_CLIENT, %sObjectManagerClientClass))\n'%(self.ns_upper, self.ns_upper, self.namespace))
-            self.outfile.write('#define %sIS_OBJECT_MANAGER_CLIENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT_MANAGER_CLIENT))\n'%(self.ns_upper, self.ns_upper))
-            self.outfile.write('#define %sIS_OBJECT_MANAGER_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_OBJECT_MANAGER_CLIENT))\n'%(self.ns_upper, self.ns_upper))
-            self.outfile.write('\n')
-            self.outfile.write('typedef struct _%sObjectManagerClient %sObjectManagerClient;\n'%(self.namespace, self.namespace))
-            self.outfile.write('typedef struct _%sObjectManagerClientClass %sObjectManagerClientClass;\n'%(self.namespace, self.namespace))
-            self.outfile.write('typedef struct _%sObjectManagerClientPrivate %sObjectManagerClientPrivate;\n'%(self.namespace, self.namespace))
-            self.outfile.write('\n')
-            self.outfile.write('struct _%sObjectManagerClient\n'%(self.namespace))
-            self.outfile.write('{\n')
-            self.outfile.write('  /*< private >*/\n')
-            self.outfile.write('  GDBusObjectManagerClient parent_instance;\n')
-            self.outfile.write('  %sObjectManagerClientPrivate *priv;\n'%(self.namespace))
-            self.outfile.write('};\n')
-            self.outfile.write('\n')
-            self.outfile.write('struct _%sObjectManagerClientClass\n'%(self.namespace))
-            self.outfile.write('{\n')
-            self.outfile.write('  GDBusObjectManagerClientClass parent_class;\n')
-            self.outfile.write('};\n')
-            self.outfile.write('\n')
-            if self.generate_autocleanup in ('objects', 'all'):
-                self.outfile.write('#if GLIB_CHECK_VERSION(2, 44, 0)\n')
-                self.outfile.write('G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sObjectManagerClient, g_object_unref)\n' % (self.namespace))
-                self.outfile.write('#endif\n')
-                self.outfile.write('\n')
+                    self.outfile.write("G_GNUC_DEPRECATED ")
+                self.outfile.write(
+                    "void %sobject_skeleton_set_%s (%sObjectSkeleton *object, %s *interface_);\n"
+                    % (
+                        self.ns_lower,
+                        i.name_upper.lower(),
+                        self.namespace,
+                        i.camel_name,
+                    )
+                )
+            self.outfile.write("\n")
+
+            self.outfile.write("/* ---- */\n")
+            self.outfile.write("\n")
+            self.outfile.write(
+                "#define %sTYPE_OBJECT_MANAGER_CLIENT (%sobject_manager_client_get_type ())\n"
+                % (self.ns_upper, self.ns_lower)
+            )
+            self.outfile.write(
+                "#define %sOBJECT_MANAGER_CLIENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT_MANAGER_CLIENT, %sObjectManagerClient))\n"
+                % (self.ns_upper, self.ns_upper, self.namespace)
+            )
+            self.outfile.write(
+                "#define %sOBJECT_MANAGER_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_OBJECT_MANAGER_CLIENT, %sObjectManagerClientClass))\n"
+                % (self.ns_upper, self.ns_upper, self.namespace)
+            )
+            self.outfile.write(
+                "#define %sOBJECT_MANAGER_CLIENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_OBJECT_MANAGER_CLIENT, %sObjectManagerClientClass))\n"
+                % (self.ns_upper, self.ns_upper, self.namespace)
+            )
+            self.outfile.write(
+                "#define %sIS_OBJECT_MANAGER_CLIENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT_MANAGER_CLIENT))\n"
+                % (self.ns_upper, self.ns_upper)
+            )
+            self.outfile.write(
+                "#define %sIS_OBJECT_MANAGER_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_OBJECT_MANAGER_CLIENT))\n"
+                % (self.ns_upper, self.ns_upper)
+            )
+            self.outfile.write("\n")
+            self.outfile.write(
+                "typedef struct _%sObjectManagerClient %sObjectManagerClient;\n"
+                % (self.namespace, self.namespace)
+            )
+            self.outfile.write(
+                "typedef struct _%sObjectManagerClientClass %sObjectManagerClientClass;\n"
+                % (self.namespace, self.namespace)
+            )
+            self.outfile.write(
+                "typedef struct _%sObjectManagerClientPrivate %sObjectManagerClientPrivate;\n"
+                % (self.namespace, self.namespace)
+            )
+            self.outfile.write("\n")
+            self.outfile.write("struct _%sObjectManagerClient\n" % (self.namespace))
+            self.outfile.write("{\n")
+            self.outfile.write("  /*< private >*/\n")
+            self.outfile.write("  GDBusObjectManagerClient parent_instance;\n")
+            self.outfile.write(
+                "  %sObjectManagerClientPrivate *priv;\n" % (self.namespace)
+            )
+            self.outfile.write("};\n")
+            self.outfile.write("\n")
+            self.outfile.write(
+                "struct _%sObjectManagerClientClass\n" % (self.namespace)
+            )
+            self.outfile.write("{\n")
+            self.outfile.write("  GDBusObjectManagerClientClass parent_class;\n")
+            self.outfile.write("};\n")
+            self.outfile.write("\n")
+            if self.generate_autocleanup in ("objects", "all"):
+                self.outfile.write("#if GLIB_CHECK_VERSION(2, 44, 0)\n")
+                self.outfile.write(
+                    "G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sObjectManagerClient, g_object_unref)\n"
+                    % (self.namespace)
+                )
+                self.outfile.write("#endif\n")
+                self.outfile.write("\n")
             if self.symbol_decorator is not None:
-                self.outfile.write('%s\n' % self.symbol_decorator)
-            self.outfile.write('GType %sobject_manager_client_get_type (void) G_GNUC_CONST;\n'%(self.ns_lower))
-            self.outfile.write('\n')
+                self.outfile.write("%s\n" % self.symbol_decorator)
+            self.outfile.write(
+                "GType %sobject_manager_client_get_type (void) G_GNUC_CONST;\n"
+                % (self.ns_lower)
+            )
+            self.outfile.write("\n")
             if self.symbol_decorator is not None:
-                self.outfile.write('%s\n' % self.symbol_decorator)
-            self.outfile.write('GType %sobject_manager_client_get_proxy_type (GDBusObjectManagerClient *manager, const gchar *object_path, const gchar *interface_name, gpointer user_data);\n'%(self.ns_lower))
-            self.outfile.write('\n')
+                self.outfile.write("%s\n" % self.symbol_decorator)
+            self.outfile.write(
+                "GType %sobject_manager_client_get_proxy_type (GDBusObjectManagerClient *manager, const gchar *object_path, const gchar *interface_name, gpointer user_data);\n"
+                % (self.ns_lower)
+            )
+            self.outfile.write("\n")
             if self.symbol_decorator is not None:
-                self.outfile.write('%s\n' % self.symbol_decorator)
-            self.outfile.write('void %sobject_manager_client_new (\n'
-                               '    GDBusConnection        *connection,\n'
-                               '    GDBusObjectManagerClientFlags  flags,\n'
-                               '    const gchar            *name,\n'
-                               '    const gchar            *object_path,\n'
-                               '    GCancellable           *cancellable,\n'
-                               '    GAsyncReadyCallback     callback,\n'
-                               '    gpointer                user_data);\n'
-                               %(self.ns_lower))
+                self.outfile.write("%s\n" % self.symbol_decorator)
+            self.outfile.write(
+                "void %sobject_manager_client_new (\n"
+                "    GDBusConnection        *connection,\n"
+                "    GDBusObjectManagerClientFlags  flags,\n"
+                "    const gchar            *name,\n"
+                "    const gchar            *object_path,\n"
+                "    GCancellable           *cancellable,\n"
+                "    GAsyncReadyCallback     callback,\n"
+                "    gpointer                user_data);\n" % (self.ns_lower)
+            )
             if self.symbol_decorator is not None:
-                self.outfile.write('%s\n' % self.symbol_decorator)
-            self.outfile.write('GDBusObjectManager *%sobject_manager_client_new_finish (\n'
-                               '    GAsyncResult        *res,\n'
-                               '    GError             **error);\n'
-                               %(self.ns_lower))
+                self.outfile.write("%s\n" % self.symbol_decorator)
+            self.outfile.write(
+                "GDBusObjectManager *%sobject_manager_client_new_finish (\n"
+                "    GAsyncResult        *res,\n"
+                "    GError             **error);\n" % (self.ns_lower)
+            )
             if self.symbol_decorator is not None:
-                self.outfile.write('%s\n' % self.symbol_decorator)
-            self.outfile.write('GDBusObjectManager *%sobject_manager_client_new_sync (\n'
-                               '    GDBusConnection        *connection,\n'
-                               '    GDBusObjectManagerClientFlags  flags,\n'
-                               '    const gchar            *name,\n'
-                               '    const gchar            *object_path,\n'
-                               '    GCancellable           *cancellable,\n'
-                               '    GError                **error);\n'
-                               %(self.ns_lower))
-            self.outfile.write('\n')
+                self.outfile.write("%s\n" % self.symbol_decorator)
+            self.outfile.write(
+                "GDBusObjectManager *%sobject_manager_client_new_sync (\n"
+                "    GDBusConnection        *connection,\n"
+                "    GDBusObjectManagerClientFlags  flags,\n"
+                "    const gchar            *name,\n"
+                "    const gchar            *object_path,\n"
+                "    GCancellable           *cancellable,\n"
+                "    GError                **error);\n" % (self.ns_lower)
+            )
+            self.outfile.write("\n")
             if self.symbol_decorator is not None:
-                self.outfile.write('%s\n' % self.symbol_decorator)
-            self.outfile.write('void %sobject_manager_client_new_for_bus (\n'
-                               '    GBusType                bus_type,\n'
-                               '    GDBusObjectManagerClientFlags  flags,\n'
-                               '    const gchar            *name,\n'
-                               '    const gchar            *object_path,\n'
-                               '    GCancellable           *cancellable,\n'
-                               '    GAsyncReadyCallback     callback,\n'
-                               '    gpointer                user_data);\n'
-                               %(self.ns_lower))
+                self.outfile.write("%s\n" % self.symbol_decorator)
+            self.outfile.write(
+                "void %sobject_manager_client_new_for_bus (\n"
+                "    GBusType                bus_type,\n"
+                "    GDBusObjectManagerClientFlags  flags,\n"
+                "    const gchar            *name,\n"
+                "    const gchar            *object_path,\n"
+                "    GCancellable           *cancellable,\n"
+                "    GAsyncReadyCallback     callback,\n"
+                "    gpointer                user_data);\n" % (self.ns_lower)
+            )
             if self.symbol_decorator is not None:
-                self.outfile.write('%s\n' % self.symbol_decorator)
-            self.outfile.write('GDBusObjectManager *%sobject_manager_client_new_for_bus_finish (\n'
-                               '    GAsyncResult        *res,\n'
-                               '    GError             **error);\n'
-                               %(self.ns_lower))
+                self.outfile.write("%s\n" % self.symbol_decorator)
+            self.outfile.write(
+                "GDBusObjectManager *%sobject_manager_client_new_for_bus_finish (\n"
+                "    GAsyncResult        *res,\n"
+                "    GError             **error);\n" % (self.ns_lower)
+            )
             if self.symbol_decorator is not None:
-                self.outfile.write('%s\n' % self.symbol_decorator)
-            self.outfile.write('GDBusObjectManager *%sobject_manager_client_new_for_bus_sync (\n'
-                               '    GBusType                bus_type,\n'
-                               '    GDBusObjectManagerClientFlags  flags,\n'
-                               '    const gchar            *name,\n'
-                               '    const gchar            *object_path,\n'
-                               '    GCancellable           *cancellable,\n'
-                               '    GError                **error);\n'
-                               %(self.ns_lower))
-            self.outfile.write('\n')
+                self.outfile.write("%s\n" % self.symbol_decorator)
+            self.outfile.write(
+                "GDBusObjectManager *%sobject_manager_client_new_for_bus_sync (\n"
+                "    GBusType                bus_type,\n"
+                "    GDBusObjectManagerClientFlags  flags,\n"
+                "    const gchar            *name,\n"
+                "    const gchar            *object_path,\n"
+                "    GCancellable           *cancellable,\n"
+                "    GError                **error);\n" % (self.ns_lower)
+            )
+            self.outfile.write("\n")
 
     # ----------------------------------------------------------------------------------------------------
 
     def generate_header_postamble(self):
-        self.outfile.write('\n')
-        self.outfile.write('G_END_DECLS\n')
+        self.outfile.write("\n")
+        self.outfile.write("G_END_DECLS\n")
 
         if not self.use_pragma:
-            self.outfile.write('\n')
-            self.outfile.write('#endif /* __{!s}__ */\n'.format(self.header_guard))
+            self.outfile.write("\n")
+            self.outfile.write("#endif /* __{!s}__ */\n".format(self.header_guard))
 
     # ----------------------------------------------------------------------------------------------------
 
@@ -701,11 +1008,23 @@ class HeaderCodeGenerator:
         self.declare_types()
         self.generate_header_postamble()
 
+
 # ----------------------------------------------------------------------------------------------------
 
+
 class InterfaceInfoHeaderCodeGenerator:
-    def __init__(self, ifaces, namespace, header_name, input_files_basenames, use_pragma,
-                 glib_min_required, symbol_decorator, symbol_decorator_header, outfile):
+    def __init__(
+        self,
+        ifaces,
+        namespace,
+        header_name,
+        input_files_basenames,
+        use_pragma,
+        glib_min_required,
+        symbol_decorator,
+        symbol_decorator_header,
+        outfile,
+    ):
         self.ifaces = ifaces
         self.namespace, self.ns_upper, self.ns_lower = generate_namespace(namespace)
         self.header_guard = generate_header_guard(header_name)
@@ -714,49 +1033,51 @@ class InterfaceInfoHeaderCodeGenerator:
         self.glib_min_required = glib_min_required
         self.symbol_decorator = symbol_decorator
         if self.symbol_decorator is None:
-            self.symbol_decorator = ''
+            self.symbol_decorator = ""
         self.symbol_decorator_header = symbol_decorator_header
         self.outfile = outfile
 
     # ----------------------------------------------------------------------------------------------------
 
     def generate_header_preamble(self):
-        basenames = ', '.join(self.input_files_basenames)
+        basenames = ", ".join(self.input_files_basenames)
         self.outfile.write(LICENSE_STR.format(config.VERSION, basenames))
-        self.outfile.write('\n')
+        self.outfile.write("\n")
 
         if self.use_pragma:
-            self.outfile.write('#pragma once\n')
+            self.outfile.write("#pragma once\n")
         else:
-            self.outfile.write('#ifndef __{!s}__\n'.format(self.header_guard))
-            self.outfile.write('#define __{!s}__\n'.format(self.header_guard))
+            self.outfile.write("#ifndef __{!s}__\n".format(self.header_guard))
+            self.outfile.write("#define __{!s}__\n".format(self.header_guard))
 
         if self.symbol_decorator_header is not None:
-            self.outfile.write('\n')
+            self.outfile.write("\n")
             self.outfile.write('#include "%s"\n' % self.symbol_decorator_header)
 
-        self.outfile.write('\n')
-        self.outfile.write('#include <gio/gio.h>\n')
-        self.outfile.write('\n')
-        self.outfile.write('G_BEGIN_DECLS\n')
-        self.outfile.write('\n')
+        self.outfile.write("\n")
+        self.outfile.write("#include <gio/gio.h>\n")
+        self.outfile.write("\n")
+        self.outfile.write("G_BEGIN_DECLS\n")
+        self.outfile.write("\n")
 
     # ----------------------------------------------------------------------------------------------------
 
     def declare_infos(self):
         for i in self.ifaces:
-            self.outfile.write('extern %s const GDBusInterfaceInfo %s_interface;\n' %
-                               (self.symbol_decorator, i.name_lower))
+            self.outfile.write(
+                "extern %s const GDBusInterfaceInfo %s_interface;\n"
+                % (self.symbol_decorator, i.name_lower)
+            )
 
     # ----------------------------------------------------------------------------------------------------
 
     def generate_header_postamble(self):
-        self.outfile.write('\n')
-        self.outfile.write('G_END_DECLS\n')
+        self.outfile.write("\n")
+        self.outfile.write("G_END_DECLS\n")
 
         if not self.use_pragma:
-            self.outfile.write('\n')
-            self.outfile.write('#endif /* __{!s}__ */\n'.format(self.header_guard))
+            self.outfile.write("\n")
+            self.outfile.write("#endif /* __{!s}__ */\n".format(self.header_guard))
 
     # ----------------------------------------------------------------------------------------------------
 
@@ -765,11 +1086,21 @@ class InterfaceInfoHeaderCodeGenerator:
         self.declare_infos()
         self.generate_header_postamble()
 
+
 # ----------------------------------------------------------------------------------------------------
 
+
 class InterfaceInfoBodyCodeGenerator:
-    def __init__(self, ifaces, namespace, header_name, input_files_basenames,
-                 glib_min_required, symbol_decoration_define, outfile):
+    def __init__(
+        self,
+        ifaces,
+        namespace,
+        header_name,
+        input_files_basenames,
+        glib_min_required,
+        symbol_decoration_define,
+        outfile,
+    ):
         self.ifaces = ifaces
         self.namespace, self.ns_upper, self.ns_lower = generate_namespace(namespace)
         self.header_name = header_name
@@ -781,34 +1112,37 @@ class InterfaceInfoBodyCodeGenerator:
     # ----------------------------------------------------------------------------------------------------
 
     def generate_body_preamble(self):
-        basenames = ', '.join(self.input_files_basenames)
+        basenames = ", ".join(self.input_files_basenames)
         self.outfile.write(LICENSE_STR.format(config.VERSION, basenames))
 
         if self.symbol_decoration_define is not None:
-            self.outfile.write('\n')
-            self.outfile.write('#define %s\n' % self.symbol_decoration_define)
-
-        self.outfile.write('\n')
-        self.outfile.write('#ifdef HAVE_CONFIG_H\n'
-                           '#  include "config.h"\n'
-                           '#endif\n'
-                           '\n'
-                           '#include "%s"\n'
-                           '\n'
-                           '#include <string.h>\n'
-                           % (self.header_name))
-        self.outfile.write('\n')
+            self.outfile.write("\n")
+            self.outfile.write("#define %s\n" % self.symbol_decoration_define)
+
+        self.outfile.write("\n")
+        self.outfile.write(
+            "#ifdef HAVE_CONFIG_H\n"
+            '#  include "config.h"\n'
+            "#endif\n"
+            "\n"
+            '#include "%s"\n'
+            "\n"
+            "#include <string.h>\n" % (self.header_name)
+        )
+        self.outfile.write("\n")
 
     # ----------------------------------------------------------------------------------------------------
 
     def generate_array(self, array_name_lower, element_type, elements):
-        self.outfile.write('const %s * const %s[] =\n' % (element_type, array_name_lower))
-        self.outfile.write('{\n')
+        self.outfile.write(
+            "const %s * const %s[] =\n" % (element_type, array_name_lower)
+        )
+        self.outfile.write("{\n")
         for (_, name) in elements:
-            self.outfile.write('  &%s,\n' % name)
-        self.outfile.write('  NULL,\n')
-        self.outfile.write('};\n')
-        self.outfile.write('\n')
+            self.outfile.write("  &%s,\n" % name)
+        self.outfile.write("  NULL,\n")
+        self.outfile.write("};\n")
+        self.outfile.write("\n")
 
     def define_annotations(self, array_name_lower, annotations):
         if len(annotations) == 0:
@@ -818,28 +1152,37 @@ class InterfaceInfoBodyCodeGenerator:
 
         for a in annotations:
             # Skip internal annotations.
-            if a.key.startswith('org.gtk.GDBus'):
+            if a.key.startswith("org.gtk.GDBus"):
                 continue
 
-            self.define_annotations('%s__%s_annotations' % (array_name_lower, a.key_lower), a.annotations)
+            self.define_annotations(
+                "%s__%s_annotations" % (array_name_lower, a.key_lower), a.annotations
+            )
 
-            self.outfile.write('const GDBusAnnotationInfo %s__%s_annotation =\n' % (array_name_lower, a.key_lower))
-            self.outfile.write('{\n')
-            self.outfile.write('  -1,  /* ref count */\n')
+            self.outfile.write(
+                "const GDBusAnnotationInfo %s__%s_annotation =\n"
+                % (array_name_lower, a.key_lower)
+            )
+            self.outfile.write("{\n")
+            self.outfile.write("  -1,  /* ref count */\n")
             self.outfile.write('  (gchar *) "%s",\n' % a.key)
             self.outfile.write('  (gchar *) "%s",\n' % a.value)
             if len(a.annotations) > 0:
-                self.outfile.write('  (GDBusAnnotationInfo **) %s__%s_annotations,\n' % (array_name_lower, a.key_lower))
+                self.outfile.write(
+                    "  (GDBusAnnotationInfo **) %s__%s_annotations,\n"
+                    % (array_name_lower, a.key_lower)
+                )
             else:
-                self.outfile.write('  NULL,  /* no annotations */\n')
-            self.outfile.write('};\n')
-            self.outfile.write('\n')
+                self.outfile.write("  NULL,  /* no annotations */\n")
+            self.outfile.write("};\n")
+            self.outfile.write("\n")
 
-            key = (a.since, '%s__%s_annotation' % (array_name_lower, a.key_lower))
+            key = (a.since, "%s__%s_annotation" % (array_name_lower, a.key_lower))
             annotation_pointers.append(key)
 
-        self.generate_array(array_name_lower, 'GDBusAnnotationInfo',
-                            annotation_pointers)
+        self.generate_array(
+            array_name_lower, "GDBusAnnotationInfo", annotation_pointers
+        )
 
     def define_args(self, array_name_lower, args):
         if len(args) == 0:
@@ -848,93 +1191,154 @@ class InterfaceInfoBodyCodeGenerator:
         arg_pointers = []
 
         for a in args:
-            self.define_annotations('%s__%s_arg_annotations' % (array_name_lower, a.name), a.annotations)
-
-            self.outfile.write('const GDBusArgInfo %s__%s_arg =\n' % (array_name_lower, a.name))
-            self.outfile.write('{\n')
-            self.outfile.write('  -1,  /* ref count */\n')
+            self.define_annotations(
+                "%s__%s_arg_annotations" % (array_name_lower, a.name), a.annotations
+            )
+
+            self.outfile.write(
+                "const GDBusArgInfo %s__%s_arg =\n" % (array_name_lower, a.name)
+            )
+            self.outfile.write("{\n")
+            self.outfile.write("  -1,  /* ref count */\n")
             self.outfile.write('  (gchar *) "%s",\n' % a.name)
             self.outfile.write('  (gchar *) "%s",\n' % a.signature)
             if len(a.annotations) > 0:
-                self.outfile.write('  (GDBusAnnotationInfo **) %s__%s_arg_annotations,\n' % (array_name_lower, a.name))
+                self.outfile.write(
+                    "  (GDBusAnnotationInfo **) %s__%s_arg_annotations,\n"
+                    % (array_name_lower, a.name)
+                )
             else:
-                self.outfile.write('  NULL,  /* no annotations */\n')
-            self.outfile.write('};\n')
-            self.outfile.write('\n')
+                self.outfile.write("  NULL,  /* no annotations */\n")
+            self.outfile.write("};\n")
+            self.outfile.write("\n")
 
-            key = (a.since, '%s__%s_arg' % (array_name_lower, a.name))
+            key = (a.since, "%s__%s_arg" % (array_name_lower, a.name))
             arg_pointers.append(key)
 
-        self.generate_array(array_name_lower, 'GDBusArgInfo', arg_pointers)
+        self.generate_array(array_name_lower, "GDBusArgInfo", arg_pointers)
 
     def define_infos(self):
         for i in self.ifaces:
-            self.outfile.write('/* ------------------------------------------------------------------------ */\n')
-            self.outfile.write('/* Definitions for %s */\n' % i.name)
-            self.outfile.write('\n')
+            self.outfile.write(
+                "/* ------------------------------------------------------------------------ */\n"
+            )
+            self.outfile.write("/* Definitions for %s */\n" % i.name)
+            self.outfile.write("\n")
 
             # GDBusMethodInfos.
             if len(i.methods) > 0:
                 method_pointers = []
 
                 for m in i.methods:
-                    self.define_args('%s_interface__%s_method_in_args' % (i.name_lower, m.name_lower), m.in_args)
-                    self.define_args('%s_interface__%s_method_out_args' % (i.name_lower, m.name_lower), m.out_args)
-                    self.define_annotations('%s_interface__%s_method_annotations' % (i.name_lower, m.name_lower), m.annotations)
-
-                    self.outfile.write('const GDBusMethodInfo %s_interface__%s_method =\n' % (i.name_lower, m.name_lower))
-                    self.outfile.write('{\n')
-                    self.outfile.write('  -1,  /* ref count */\n')
+                    self.define_args(
+                        "%s_interface__%s_method_in_args"
+                        % (i.name_lower, m.name_lower),
+                        m.in_args,
+                    )
+                    self.define_args(
+                        "%s_interface__%s_method_out_args"
+                        % (i.name_lower, m.name_lower),
+                        m.out_args,
+                    )
+                    self.define_annotations(
+                        "%s_interface__%s_method_annotations"
+                        % (i.name_lower, m.name_lower),
+                        m.annotations,
+                    )
+
+                    self.outfile.write(
+                        "const GDBusMethodInfo %s_interface__%s_method =\n"
+                        % (i.name_lower, m.name_lower)
+                    )
+                    self.outfile.write("{\n")
+                    self.outfile.write("  -1,  /* ref count */\n")
                     self.outfile.write('  (gchar *) "%s",\n' % m.name)
                     if len(m.in_args) > 0:
-                        self.outfile.write('  (GDBusArgInfo **) %s_interface__%s_method_in_args,\n' % (i.name_lower, m.name_lower))
+                        self.outfile.write(
+                            "  (GDBusArgInfo **) %s_interface__%s_method_in_args,\n"
+                            % (i.name_lower, m.name_lower)
+                        )
                     else:
-                        self.outfile.write('  NULL,  /* no in args */\n')
+                        self.outfile.write("  NULL,  /* no in args */\n")
                     if len(m.out_args) > 0:
-                        self.outfile.write('  (GDBusArgInfo **) %s_interface__%s_method_out_args,\n' % (i.name_lower, m.name_lower))
+                        self.outfile.write(
+                            "  (GDBusArgInfo **) %s_interface__%s_method_out_args,\n"
+                            % (i.name_lower, m.name_lower)
+                        )
                     else:
-                        self.outfile.write('  NULL,  /* no out args */\n')
+                        self.outfile.write("  NULL,  /* no out args */\n")
                     if len(m.annotations) > 0:
-                        self.outfile.write('  (GDBusAnnotationInfo **) %s_interface__%s_method_annotations,\n' % (i.name_lower, m.name_lower))
+                        self.outfile.write(
+                            "  (GDBusAnnotationInfo **) %s_interface__%s_method_annotations,\n"
+                            % (i.name_lower, m.name_lower)
+                        )
                     else:
-                        self.outfile.write('  NULL,  /* no annotations */\n')
-                    self.outfile.write('};\n')
-                    self.outfile.write('\n')
-
-                    key = (m.since, '%s_interface__%s_method' % (i.name_lower, m.name_lower))
+                        self.outfile.write("  NULL,  /* no annotations */\n")
+                    self.outfile.write("};\n")
+                    self.outfile.write("\n")
+
+                    key = (
+                        m.since,
+                        "%s_interface__%s_method" % (i.name_lower, m.name_lower),
+                    )
                     method_pointers.append(key)
 
-                self.generate_array('%s_interface_methods' % i.name_lower,
-                                    'GDBusMethodInfo', method_pointers)
+                self.generate_array(
+                    "%s_interface_methods" % i.name_lower,
+                    "GDBusMethodInfo",
+                    method_pointers,
+                )
 
             # GDBusSignalInfos.
             if len(i.signals) > 0:
                 signal_pointers = []
 
                 for s in i.signals:
-                    self.define_args('%s_interface__%s_signal_args' % (i.name_lower, s.name_lower), s.args)
-                    self.define_annotations('%s_interface__%s_signal_annotations' % (i.name_lower, s.name_lower), s.annotations)
-
-                    self.outfile.write('const GDBusSignalInfo %s_interface__%s_signal =\n' % (i.name_lower, s.name_lower))
-                    self.outfile.write('{\n')
-                    self.outfile.write('  -1,  /* ref count */\n')
+                    self.define_args(
+                        "%s_interface__%s_signal_args" % (i.name_lower, s.name_lower),
+                        s.args,
+                    )
+                    self.define_annotations(
+                        "%s_interface__%s_signal_annotations"
+                        % (i.name_lower, s.name_lower),
+                        s.annotations,
+                    )
+
+                    self.outfile.write(
+                        "const GDBusSignalInfo %s_interface__%s_signal =\n"
+                        % (i.name_lower, s.name_lower)
+                    )
+                    self.outfile.write("{\n")
+                    self.outfile.write("  -1,  /* ref count */\n")
                     self.outfile.write('  (gchar *) "%s",\n' % s.name)
                     if len(s.args) > 0:
-                        self.outfile.write('  (GDBusArgInfo **) %s_interface__%s_signal_args,\n' % (i.name_lower, s.name_lower))
+                        self.outfile.write(
+                            "  (GDBusArgInfo **) %s_interface__%s_signal_args,\n"
+                            % (i.name_lower, s.name_lower)
+                        )
                     else:
-                        self.outfile.write('  NULL,  /* no args */\n')
+                        self.outfile.write("  NULL,  /* no args */\n")
                     if len(s.annotations) > 0:
-                        self.outfile.write('  (GDBusAnnotationInfo **) %s_interface__%s_signal_annotations,\n' % (i.name_lower, s.name_lower))
+                        self.outfile.write(
+                            "  (GDBusAnnotationInfo **) %s_interface__%s_signal_annotations,\n"
+                            % (i.name_lower, s.name_lower)
+                        )
                     else:
-                        self.outfile.write('  NULL,  /* no annotations */\n')
-                    self.outfile.write('};\n')
-                    self.outfile.write('\n')
-
-                    key = (s.since, '%s_interface__%s_signal' % (i.name_lower, s.name_lower))
+                        self.outfile.write("  NULL,  /* no annotations */\n")
+                    self.outfile.write("};\n")
+                    self.outfile.write("\n")
+
+                    key = (
+                        s.since,
+                        "%s_interface__%s_signal" % (i.name_lower, s.name_lower),
+                    )
                     signal_pointers.append(key)
 
-                self.generate_array('%s_interface_signals' % i.name_lower,
-                                    'GDBusSignalInfo', signal_pointers)
+                self.generate_array(
+                    "%s_interface_signals" % i.name_lower,
+                    "GDBusSignalInfo",
+                    signal_pointers,
+                )
 
             # GDBusPropertyInfos.
             if len(i.properties) > 0:
@@ -942,61 +1346,89 @@ class InterfaceInfoBodyCodeGenerator:
 
                 for p in i.properties:
                     if p.readable and p.writable:
-                        flags = 'G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE'
+                        flags = "G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE"
                     elif p.readable:
-                        flags = 'G_DBUS_PROPERTY_INFO_FLAGS_READABLE'
+                        flags = "G_DBUS_PROPERTY_INFO_FLAGS_READABLE"
                     elif p.writable:
-                        flags = 'G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE'
+                        flags = "G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE"
                     else:
-                        flags = 'G_DBUS_PROPERTY_INFO_FLAGS_NONE'
-
-                    self.define_annotations('%s_interface__%s_property_annotations' % (i.name_lower, p.name_lower), p.annotations)
-
-                    self.outfile.write('const GDBusPropertyInfo %s_interface__%s_property =\n' % (i.name_lower, p.name_lower))
-                    self.outfile.write('{\n')
-                    self.outfile.write('  -1,  /* ref count */\n')
+                        flags = "G_DBUS_PROPERTY_INFO_FLAGS_NONE"
+
+                    self.define_annotations(
+                        "%s_interface__%s_property_annotations"
+                        % (i.name_lower, p.name_lower),
+                        p.annotations,
+                    )
+
+                    self.outfile.write(
+                        "const GDBusPropertyInfo %s_interface__%s_property =\n"
+                        % (i.name_lower, p.name_lower)
+                    )
+                    self.outfile.write("{\n")
+                    self.outfile.write("  -1,  /* ref count */\n")
                     self.outfile.write('  (gchar *) "%s",\n' % p.name)
                     self.outfile.write('  (gchar *) "%s",\n' % p.signature)
-                    self.outfile.write('  %s,\n' % flags)
+                    self.outfile.write("  %s,\n" % flags)
                     if len(p.annotations) > 0:
-                        self.outfile.write('  (GDBusAnnotationInfo **) %s_interface__%s_property_annotations,\n' % (i.name_lower, p.name_lower))
+                        self.outfile.write(
+                            "  (GDBusAnnotationInfo **) %s_interface__%s_property_annotations,\n"
+                            % (i.name_lower, p.name_lower)
+                        )
                     else:
-                        self.outfile.write('  NULL,  /* no annotations */\n')
-                    self.outfile.write('};\n')
-                    self.outfile.write('\n')
-
-                    key = (p.since, '%s_interface__%s_property' % (i.name_lower, p.name_lower))
+                        self.outfile.write("  NULL,  /* no annotations */\n")
+                    self.outfile.write("};\n")
+                    self.outfile.write("\n")
+
+                    key = (
+                        p.since,
+                        "%s_interface__%s_property" % (i.name_lower, p.name_lower),
+                    )
                     property_pointers.append(key)
 
-                self.generate_array('%s_interface_properties' % i.name_lower,
-                                    'GDBusPropertyInfo', property_pointers)
+                self.generate_array(
+                    "%s_interface_properties" % i.name_lower,
+                    "GDBusPropertyInfo",
+                    property_pointers,
+                )
 
             # Finally the GDBusInterfaceInfo.
-            self.define_annotations('%s_interface_annotations' % i.name_lower,
-                                    i.annotations)
-
-            self.outfile.write('const GDBusInterfaceInfo %s_interface =\n' % i.name_lower)
-            self.outfile.write('{\n')
-            self.outfile.write('  -1,  /* ref count */\n')
+            self.define_annotations(
+                "%s_interface_annotations" % i.name_lower, i.annotations
+            )
+
+            self.outfile.write(
+                "const GDBusInterfaceInfo %s_interface =\n" % i.name_lower
+            )
+            self.outfile.write("{\n")
+            self.outfile.write("  -1,  /* ref count */\n")
             self.outfile.write('  (gchar *) "%s",\n' % i.name)
             if len(i.methods) > 0:
-                self.outfile.write('  (GDBusMethodInfo **) %s_interface_methods,\n' % i.name_lower)
+                self.outfile.write(
+                    "  (GDBusMethodInfo **) %s_interface_methods,\n" % i.name_lower
+                )
             else:
-                self.outfile.write('  NULL,  /* no methods */\n')
+                self.outfile.write("  NULL,  /* no methods */\n")
             if len(i.signals) > 0:
-                self.outfile.write('  (GDBusSignalInfo **) %s_interface_signals,\n' % i.name_lower)
+                self.outfile.write(
+                    "  (GDBusSignalInfo **) %s_interface_signals,\n" % i.name_lower
+                )
             else:
-                self.outfile.write('  NULL,  /* no signals */\n')
+                self.outfile.write("  NULL,  /* no signals */\n")
             if len(i.properties) > 0:
-                self.outfile.write('  (GDBusPropertyInfo **) %s_interface_properties,\n' % i.name_lower)
+                self.outfile.write(
+                    "  (GDBusPropertyInfo **) %s_interface_properties,\n" % i.name_lower
+                )
             else:
-                self.outfile.write(  'NULL,  /* no properties */\n')
+                self.outfile.write("NULL,  /* no properties */\n")
             if len(i.annotations) > 0:
-                self.outfile.write('  (GDBusAnnotationInfo **) %s_interface_annotations,\n' % i.name_lower)
+                self.outfile.write(
+                    "  (GDBusAnnotationInfo **) %s_interface_annotations,\n"
+                    % i.name_lower
+                )
             else:
-                self.outfile.write('  NULL,  /* no annotations */\n')
-            self.outfile.write('};\n')
-            self.outfile.write('\n')
+                self.outfile.write("  NULL,  /* no annotations */\n")
+            self.outfile.write("};\n")
+            self.outfile.write("\n")
 
     # ----------------------------------------------------------------------------------------------------
 
@@ -1004,12 +1436,23 @@ class InterfaceInfoBodyCodeGenerator:
         self.generate_body_preamble()
         self.define_infos()
 
+
 # ----------------------------------------------------------------------------------------------------
 
+
 class CodeGenerator:
-    def __init__(self, ifaces, namespace, generate_objmanager, header_name,
-                 input_files_basenames, docbook_gen, glib_min_required,
-                 symbol_decoration_define, outfile):
+    def __init__(
+        self,
+        ifaces,
+        namespace,
+        generate_objmanager,
+        header_name,
+        input_files_basenames,
+        docbook_gen,
+        glib_min_required,
+        symbol_decoration_define,
+        outfile,
+    ):
         self.ifaces = ifaces
         self.namespace, self.ns_upper, self.ns_lower = generate_namespace(namespace)
         self.generate_objmanager = generate_objmanager
@@ -1023,169 +1466,187 @@ class CodeGenerator:
     # ----------------------------------------------------------------------------------------------------
 
     def generate_body_preamble(self):
-        basenames = ', '.join(self.input_files_basenames)
+        basenames = ", ".join(self.input_files_basenames)
         self.outfile.write(LICENSE_STR.format(config.VERSION, basenames))
         if self.symbol_decoration_define is not None:
-            self.outfile.write('\n')
-            self.outfile.write('#define %s\n' % self.symbol_decoration_define)
-        self.outfile.write('\n')
-        self.outfile.write('#ifdef HAVE_CONFIG_H\n'
-                           '#  include "config.h"\n'
-                           '#endif\n'
-                           '\n'
-                           '#include "%s"\n'
-                           '\n'
-                           '#include <string.h>\n'
-                           %(self.header_name))
-
-        self.outfile.write('#ifdef G_OS_UNIX\n'
-                           '#  include <gio/gunixfdlist.h>\n'
-                           '#endif\n'
-                           '\n')
-
-        self.outfile.write('typedef struct\n'
-                           '{\n'
-                           '  GDBusArgInfo parent_struct;\n'
-                           '  gboolean use_gvariant;\n'
-                           '} _ExtendedGDBusArgInfo;\n'
-                           '\n')
-
-        self.outfile.write('typedef struct\n'
-                           '{\n'
-                           '  GDBusMethodInfo parent_struct;\n'
-                           '  const gchar *signal_name;\n'
-                           '  gboolean pass_fdlist;\n'
-                           '} _ExtendedGDBusMethodInfo;\n'
-                           '\n')
-
-        self.outfile.write('typedef struct\n'
-                           '{\n'
-                           '  GDBusSignalInfo parent_struct;\n'
-                           '  const gchar *signal_name;\n'
-                           '} _ExtendedGDBusSignalInfo;\n'
-                           '\n')
-
-        self.outfile.write('typedef struct\n'
-                           '{\n'
-                           '  GDBusPropertyInfo parent_struct;\n'
-                           '  const gchar *hyphen_name;\n'
-                           '  guint use_gvariant : 1;\n'
-                           '  guint emits_changed_signal : 1;\n'
-                           '} _ExtendedGDBusPropertyInfo;\n'
-                           '\n')
-
-        self.outfile.write('typedef struct\n'
-                           '{\n'
-                           '  GDBusInterfaceInfo parent_struct;\n'
-                           '  const gchar *hyphen_name;\n'
-                           '} _ExtendedGDBusInterfaceInfo;\n'
-                           '\n')
-
-        self.outfile.write('typedef struct\n'
-                           '{\n'
-                           '  const _ExtendedGDBusPropertyInfo *info;\n'
-                           '  guint prop_id;\n'
-                           '  GValue orig_value; /* the value before the change */\n'
-                           '} ChangedProperty;\n'
-                           '\n'
-                           'static void\n'
-                           '_changed_property_free (ChangedProperty *data)\n'
-                           '{\n'
-                           '  g_value_unset (&data->orig_value);\n'
-                           '  g_free (data);\n'
-                           '}\n'
-                           '\n')
-
-        self.outfile.write('static gboolean\n'
-                           '_g_strv_equal0 (gchar **a, gchar **b)\n'
-                           '{\n'
-                           '  gboolean ret = FALSE;\n'
-                           '  guint n;\n'
-                           '  if (a == NULL && b == NULL)\n'
-                           '    {\n'
-                           '      ret = TRUE;\n'
-                           '      goto out;\n'
-                           '    }\n'
-                           '  if (a == NULL || b == NULL)\n'
-                           '    goto out;\n'
-                           '  if (g_strv_length (a) != g_strv_length (b))\n'
-                           '    goto out;\n'
-                           '  for (n = 0; a[n] != NULL; n++)\n'
-                           '    if (g_strcmp0 (a[n], b[n]) != 0)\n'
-                           '      goto out;\n'
-                           '  ret = TRUE;\n'
-                           'out:\n'
-                           '  return ret;\n'
-                           '}\n'
-                           '\n')
-
-        self.outfile.write('static gboolean\n'
-                           '_g_variant_equal0 (GVariant *a, GVariant *b)\n'
-                           '{\n'
-                           '  gboolean ret = FALSE;\n'
-                           '  if (a == NULL && b == NULL)\n'
-                           '    {\n'
-                           '      ret = TRUE;\n'
-                           '      goto out;\n'
-                           '    }\n'
-                           '  if (a == NULL || b == NULL)\n'
-                           '    goto out;\n'
-                           '  ret = g_variant_equal (a, b);\n'
-                           'out:\n'
-                           '  return ret;\n'
-                           '}\n'
-                           '\n')
+            self.outfile.write("\n")
+            self.outfile.write("#define %s\n" % self.symbol_decoration_define)
+        self.outfile.write("\n")
+        self.outfile.write(
+            "#ifdef HAVE_CONFIG_H\n"
+            '#  include "config.h"\n'
+            "#endif\n"
+            "\n"
+            '#include "%s"\n'
+            "\n"
+            "#include <string.h>\n" % (self.header_name)
+        )
+
+        self.outfile.write(
+            "#ifdef G_OS_UNIX\n" "#  include <gio/gunixfdlist.h>\n" "#endif\n" "\n"
+        )
+
+        self.outfile.write(
+            "typedef struct\n"
+            "{\n"
+            "  GDBusArgInfo parent_struct;\n"
+            "  gboolean use_gvariant;\n"
+            "} _ExtendedGDBusArgInfo;\n"
+            "\n"
+        )
+
+        self.outfile.write(
+            "typedef struct\n"
+            "{\n"
+            "  GDBusMethodInfo parent_struct;\n"
+            "  const gchar *signal_name;\n"
+            "  gboolean pass_fdlist;\n"
+            "} _ExtendedGDBusMethodInfo;\n"
+            "\n"
+        )
+
+        self.outfile.write(
+            "typedef struct\n"
+            "{\n"
+            "  GDBusSignalInfo parent_struct;\n"
+            "  const gchar *signal_name;\n"
+            "} _ExtendedGDBusSignalInfo;\n"
+            "\n"
+        )
+
+        self.outfile.write(
+            "typedef struct\n"
+            "{\n"
+            "  GDBusPropertyInfo parent_struct;\n"
+            "  const gchar *hyphen_name;\n"
+            "  guint use_gvariant : 1;\n"
+            "  guint emits_changed_signal : 1;\n"
+            "} _ExtendedGDBusPropertyInfo;\n"
+            "\n"
+        )
+
+        self.outfile.write(
+            "typedef struct\n"
+            "{\n"
+            "  GDBusInterfaceInfo parent_struct;\n"
+            "  const gchar *hyphen_name;\n"
+            "} _ExtendedGDBusInterfaceInfo;\n"
+            "\n"
+        )
+
+        self.outfile.write(
+            "typedef struct\n"
+            "{\n"
+            "  const _ExtendedGDBusPropertyInfo *info;\n"
+            "  guint prop_id;\n"
+            "  GValue orig_value; /* the value before the change */\n"
+            "} ChangedProperty;\n"
+            "\n"
+            "static void\n"
+            "_changed_property_free (ChangedProperty *data)\n"
+            "{\n"
+            "  g_value_unset (&data->orig_value);\n"
+            "  g_free (data);\n"
+            "}\n"
+            "\n"
+        )
+
+        self.outfile.write(
+            "static gboolean\n"
+            "_g_strv_equal0 (gchar **a, gchar **b)\n"
+            "{\n"
+            "  gboolean ret = FALSE;\n"
+            "  guint n;\n"
+            "  if (a == NULL && b == NULL)\n"
+            "    {\n"
+            "      ret = TRUE;\n"
+            "      goto out;\n"
+            "    }\n"
+            "  if (a == NULL || b == NULL)\n"
+            "    goto out;\n"
+            "  if (g_strv_length (a) != g_strv_length (b))\n"
+            "    goto out;\n"
+            "  for (n = 0; a[n] != NULL; n++)\n"
+            "    if (g_strcmp0 (a[n], b[n]) != 0)\n"
+            "      goto out;\n"
+            "  ret = TRUE;\n"
+            "out:\n"
+            "  return ret;\n"
+            "}\n"
+            "\n"
+        )
+
+        self.outfile.write(
+            "static gboolean\n"
+            "_g_variant_equal0 (GVariant *a, GVariant *b)\n"
+            "{\n"
+            "  gboolean ret = FALSE;\n"
+            "  if (a == NULL && b == NULL)\n"
+            "    {\n"
+            "      ret = TRUE;\n"
+            "      goto out;\n"
+            "    }\n"
+            "  if (a == NULL || b == NULL)\n"
+            "    goto out;\n"
+            "  ret = g_variant_equal (a, b);\n"
+            "out:\n"
+            "  return ret;\n"
+            "}\n"
+            "\n"
+        )
 
         # simplified - only supports the types we use
-        self.outfile.write('G_GNUC_UNUSED static gboolean\n'
-                           '_g_value_equal (const GValue *a, const GValue *b)\n'
-                           '{\n'
-                           '  gboolean ret = FALSE;\n'
-                           '  g_assert (G_VALUE_TYPE (a) == G_VALUE_TYPE (b));\n'
-                           '  switch (G_VALUE_TYPE (a))\n'
-                           '    {\n'
-                           '      case G_TYPE_BOOLEAN:\n'
-                           '        ret = (g_value_get_boolean (a) == g_value_get_boolean (b));\n'
-                           '        break;\n'
-                           '      case G_TYPE_UCHAR:\n'
-                           '        ret = (g_value_get_uchar (a) == g_value_get_uchar (b));\n'
-                           '        break;\n'
-                           '      case G_TYPE_INT:\n'
-                           '        ret = (g_value_get_int (a) == g_value_get_int (b));\n'
-                           '        break;\n'
-                           '      case G_TYPE_UINT:\n'
-                           '        ret = (g_value_get_uint (a) == g_value_get_uint (b));\n'
-                           '        break;\n'
-                           '      case G_TYPE_INT64:\n'
-                           '        ret = (g_value_get_int64 (a) == g_value_get_int64 (b));\n'
-                           '        break;\n'
-                           '      case G_TYPE_UINT64:\n'
-                           '        ret = (g_value_get_uint64 (a) == g_value_get_uint64 (b));\n'
-                           '        break;\n'
-                           '      case G_TYPE_DOUBLE:\n'
-                           '        {\n'
-                           '          /* Avoid -Wfloat-equal warnings by doing a direct bit compare */\n'
-                           '          gdouble da = g_value_get_double (a);\n'
-                           '          gdouble db = g_value_get_double (b);\n'
-                           '          ret = memcmp (&da, &db, sizeof (gdouble)) == 0;\n'
-                           '        }\n'
-                           '        break;\n'
-                           '      case G_TYPE_STRING:\n'
-                           '        ret = (g_strcmp0 (g_value_get_string (a), g_value_get_string (b)) == 0);\n'
-                           '        break;\n'
-                           '      case G_TYPE_VARIANT:\n'
-                           '        ret = _g_variant_equal0 (g_value_get_variant (a), g_value_get_variant (b));\n'
-                           '        break;\n'
-                           '      default:\n'
-                           '        if (G_VALUE_TYPE (a) == G_TYPE_STRV)\n'
-                           '          ret = _g_strv_equal0 (g_value_get_boxed (a), g_value_get_boxed (b));\n'
-                           '        else\n'
-                           '          g_critical ("_g_value_equal() does not handle type %s", g_type_name (G_VALUE_TYPE (a)));\n'
-                           '        break;\n'
-                           '    }\n'
-                           '  return ret;\n'
-                           '}\n'
-                           '\n')
+        self.outfile.write(
+            "G_GNUC_UNUSED static gboolean\n"
+            "_g_value_equal (const GValue *a, const GValue *b)\n"
+            "{\n"
+            "  gboolean ret = FALSE;\n"
+            "  g_assert (G_VALUE_TYPE (a) == G_VALUE_TYPE (b));\n"
+            "  switch (G_VALUE_TYPE (a))\n"
+            "    {\n"
+            "      case G_TYPE_BOOLEAN:\n"
+            "        ret = (g_value_get_boolean (a) == g_value_get_boolean (b));\n"
+            "        break;\n"
+            "      case G_TYPE_UCHAR:\n"
+            "        ret = (g_value_get_uchar (a) == g_value_get_uchar (b));\n"
+            "        break;\n"
+            "      case G_TYPE_INT:\n"
+            "        ret = (g_value_get_int (a) == g_value_get_int (b));\n"
+            "        break;\n"
+            "      case G_TYPE_UINT:\n"
+            "        ret = (g_value_get_uint (a) == g_value_get_uint (b));\n"
+            "        break;\n"
+            "      case G_TYPE_INT64:\n"
+            "        ret = (g_value_get_int64 (a) == g_value_get_int64 (b));\n"
+            "        break;\n"
+            "      case G_TYPE_UINT64:\n"
+            "        ret = (g_value_get_uint64 (a) == g_value_get_uint64 (b));\n"
+            "        break;\n"
+            "      case G_TYPE_DOUBLE:\n"
+            "        {\n"
+            "          /* Avoid -Wfloat-equal warnings by doing a direct bit compare */\n"
+            "          gdouble da = g_value_get_double (a);\n"
+            "          gdouble db = g_value_get_double (b);\n"
+            "          ret = memcmp (&da, &db, sizeof (gdouble)) == 0;\n"
+            "        }\n"
+            "        break;\n"
+            "      case G_TYPE_STRING:\n"
+            "        ret = (g_strcmp0 (g_value_get_string (a), g_value_get_string (b)) == 0);\n"
+            "        break;\n"
+            "      case G_TYPE_VARIANT:\n"
+            "        ret = _g_variant_equal0 (g_value_get_variant (a), g_value_get_variant (b));\n"
+            "        break;\n"
+            "      default:\n"
+            "        if (G_VALUE_TYPE (a) == G_TYPE_STRV)\n"
+            "          ret = _g_strv_equal0 (g_value_get_boxed (a), g_value_get_boxed (b));\n"
+            "        else\n"
+            '          g_critical ("_g_value_equal() does not handle type %s", g_type_name (G_VALUE_TYPE (a)));\n'
+            "        break;\n"
+            "    }\n"
+            "  return ret;\n"
+            "}\n"
+            "\n"
+        )
 
     def generate_annotations(self, prefix, annotations):
         if annotations is None:
@@ -1193,457 +1654,664 @@ class CodeGenerator:
 
         n = 0
         for a in annotations:
-            #self.generate_annotations('%s_%d'%(prefix, n), a.get_annotations())
+            # self.generate_annotations('%s_%d'%(prefix, n), a.get_annotations())
 
             # skip internal annotations
-            if a.key.startswith('org.gtk.GDBus'):
+            if a.key.startswith("org.gtk.GDBus"):
                 continue
 
-            self.outfile.write('static const GDBusAnnotationInfo %s_%d =\n'
-                               '{\n'
-                               '  -1,\n'
-                               '  (gchar *) "%s",\n'
-                               '  (gchar *) "%s",\n'%(prefix, n, a.key, a.value))
+            self.outfile.write(
+                "static const GDBusAnnotationInfo %s_%d =\n"
+                "{\n"
+                "  -1,\n"
+                '  (gchar *) "%s",\n'
+                '  (gchar *) "%s",\n' % (prefix, n, a.key, a.value)
+            )
             if len(a.annotations) == 0:
-                self.outfile.write('  NULL\n')
+                self.outfile.write("  NULL\n")
             else:
-                self.outfile.write('  (GDBusAnnotationInfo **) &%s_%d_pointers\n'%(prefix, n))
-            self.outfile.write('};\n'
-                               '\n')
+                self.outfile.write(
+                    "  (GDBusAnnotationInfo **) &%s_%d_pointers\n" % (prefix, n)
+                )
+            self.outfile.write("};\n" "\n")
             n += 1
 
         if n > 0:
-            self.outfile.write('static const GDBusAnnotationInfo * const %s_pointers[] =\n'
-                               '{\n'%(prefix))
-            m = 0;
+            self.outfile.write(
+                "static const GDBusAnnotationInfo * const %s_pointers[] =\n"
+                "{\n" % (prefix)
+            )
+            m = 0
             for a in annotations:
-                if a.key.startswith('org.gtk.GDBus'):
+                if a.key.startswith("org.gtk.GDBus"):
                     continue
-                self.outfile.write('  &%s_%d,\n'%(prefix, m))
+                self.outfile.write("  &%s_%d,\n" % (prefix, m))
                 m += 1
-            self.outfile.write('  NULL\n'
-                               '};\n'
-                               '\n')
+            self.outfile.write("  NULL\n" "};\n" "\n")
         return n
 
     def generate_args(self, prefix, args):
         for a in args:
-            num_anno = self.generate_annotations('%s_arg_%s_annotation_info'%(prefix, a.name), a.annotations)
-
-            self.outfile.write('static const _ExtendedGDBusArgInfo %s_%s =\n'
-                               '{\n'
-                               '  {\n'
-                               '    -1,\n'
-                               '    (gchar *) "%s",\n'
-                               '    (gchar *) "%s",\n'%(prefix, a.name, a.name, a.signature))
+            num_anno = self.generate_annotations(
+                "%s_arg_%s_annotation_info" % (prefix, a.name), a.annotations
+            )
+
+            self.outfile.write(
+                "static const _ExtendedGDBusArgInfo %s_%s =\n"
+                "{\n"
+                "  {\n"
+                "    -1,\n"
+                '    (gchar *) "%s",\n'
+                '    (gchar *) "%s",\n' % (prefix, a.name, a.name, a.signature)
+            )
             if num_anno == 0:
-                self.outfile.write('    NULL\n')
+                self.outfile.write("    NULL\n")
             else:
-                self.outfile.write('    (GDBusAnnotationInfo **) &%s_arg_%s_annotation_info_pointers\n'%(prefix, a.name))
-            self.outfile.write('  },\n')
-            if not utils.lookup_annotation(a.annotations, 'org.gtk.GDBus.C.ForceGVariant'):
-                self.outfile.write('  FALSE\n')
+                self.outfile.write(
+                    "    (GDBusAnnotationInfo **) &%s_arg_%s_annotation_info_pointers\n"
+                    % (prefix, a.name)
+                )
+            self.outfile.write("  },\n")
+            if not utils.lookup_annotation(
+                a.annotations, "org.gtk.GDBus.C.ForceGVariant"
+            ):
+                self.outfile.write("  FALSE\n")
             else:
-                self.outfile.write('  TRUE\n')
-            self.outfile.write('};\n'
-                               '\n')
+                self.outfile.write("  TRUE\n")
+            self.outfile.write("};\n" "\n")
 
         if len(args) > 0:
-            self.outfile.write('static const GDBusArgInfo * const %s_pointers[] =\n'
-                             '{\n'%(prefix))
+            self.outfile.write(
+                "static const GDBusArgInfo * const %s_pointers[] =\n" "{\n" % (prefix)
+            )
             for a in args:
-                self.outfile.write('  &%s_%s.parent_struct,\n'%(prefix, a.name))
-            self.outfile.write('  NULL\n'
-                               '};\n'
-                               '\n')
+                self.outfile.write("  &%s_%s.parent_struct,\n" % (prefix, a.name))
+            self.outfile.write("  NULL\n" "};\n" "\n")
 
     def generate_introspection_for_interface(self, i):
-            self.outfile.write('/* ---- Introspection data for %s ---- */\n'
-                               '\n'%(i.name))
+        self.outfile.write(
+            "/* ---- Introspection data for %s ---- */\n" "\n" % (i.name)
+        )
 
-            if len(i.methods) > 0:
-                for m in i.methods:
-                    self.generate_args('_%s_method_info_%s_IN_ARG'%(i.name_lower, m.name_lower), m.in_args)
-                    self.generate_args('_%s_method_info_%s_OUT_ARG'%(i.name_lower, m.name_lower), m.out_args)
-
-                    num_anno = self.generate_annotations('_%s_method_%s_annotation_info'%(i.name_lower, m.name_lower), m.annotations)
-
-                    self.outfile.write('static const _ExtendedGDBusMethodInfo _%s_method_info_%s =\n'
-                                       '{\n'
-                                       '  {\n'
-                                       '    -1,\n'
-                                       '    (gchar *) "%s",\n'%(i.name_lower, m.name_lower, m.name))
-                    if len(m.in_args) == 0:
-                        self.outfile.write('    NULL,\n')
-                    else:
-                        self.outfile.write('    (GDBusArgInfo **) &_%s_method_info_%s_IN_ARG_pointers,\n'%(i.name_lower, m.name_lower))
-                    if len(m.out_args) == 0:
-                        self.outfile.write('    NULL,\n')
-                    else:
-                        self.outfile.write('    (GDBusArgInfo **) &_%s_method_info_%s_OUT_ARG_pointers,\n'%(i.name_lower, m.name_lower))
-                    if num_anno == 0:
-                        self.outfile.write('    NULL\n')
-                    else:
-                        self.outfile.write('    (GDBusAnnotationInfo **) &_%s_method_%s_annotation_info_pointers\n'%(i.name_lower, m.name_lower))
-                    self.outfile.write('  },\n'
-                                       '  "handle-%s",\n'
-                                       '  %s\n'
-                                       %(m.name_hyphen, 'TRUE' if m.unix_fd else 'FALSE'))
-                    self.outfile.write('};\n'
-                                       '\n')
-
-                self.outfile.write('static const GDBusMethodInfo * const _%s_method_info_pointers[] =\n'
-                                   '{\n'%(i.name_lower))
-                for m in i.methods:
-                    self.outfile.write('  &_%s_method_info_%s.parent_struct,\n'%(i.name_lower, m.name_lower))
-                self.outfile.write('  NULL\n'
-                                   '};\n'
-                                   '\n')
+        if len(i.methods) > 0:
+            for m in i.methods:
+                self.generate_args(
+                    "_%s_method_info_%s_IN_ARG" % (i.name_lower, m.name_lower),
+                    m.in_args,
+                )
+                self.generate_args(
+                    "_%s_method_info_%s_OUT_ARG" % (i.name_lower, m.name_lower),
+                    m.out_args,
+                )
+
+                num_anno = self.generate_annotations(
+                    "_%s_method_%s_annotation_info" % (i.name_lower, m.name_lower),
+                    m.annotations,
+                )
+
+                self.outfile.write(
+                    "static const _ExtendedGDBusMethodInfo _%s_method_info_%s =\n"
+                    "{\n"
+                    "  {\n"
+                    "    -1,\n"
+                    '    (gchar *) "%s",\n' % (i.name_lower, m.name_lower, m.name)
+                )
+                if len(m.in_args) == 0:
+                    self.outfile.write("    NULL,\n")
+                else:
+                    self.outfile.write(
+                        "    (GDBusArgInfo **) &_%s_method_info_%s_IN_ARG_pointers,\n"
+                        % (i.name_lower, m.name_lower)
+                    )
+                if len(m.out_args) == 0:
+                    self.outfile.write("    NULL,\n")
+                else:
+                    self.outfile.write(
+                        "    (GDBusArgInfo **) &_%s_method_info_%s_OUT_ARG_pointers,\n"
+                        % (i.name_lower, m.name_lower)
+                    )
+                if num_anno == 0:
+                    self.outfile.write("    NULL\n")
+                else:
+                    self.outfile.write(
+                        "    (GDBusAnnotationInfo **) &_%s_method_%s_annotation_info_pointers\n"
+                        % (i.name_lower, m.name_lower)
+                    )
+                self.outfile.write(
+                    "  },\n"
+                    '  "handle-%s",\n'
+                    "  %s\n" % (m.name_hyphen, "TRUE" if m.unix_fd else "FALSE")
+                )
+                self.outfile.write("};\n" "\n")
+
+            self.outfile.write(
+                "static const GDBusMethodInfo * const _%s_method_info_pointers[] =\n"
+                "{\n" % (i.name_lower)
+            )
+            for m in i.methods:
+                self.outfile.write(
+                    "  &_%s_method_info_%s.parent_struct,\n"
+                    % (i.name_lower, m.name_lower)
+                )
+            self.outfile.write("  NULL\n" "};\n" "\n")
 
-            # ---
+        # ---
 
-            if len(i.signals) > 0:
-                for s in i.signals:
-                    self.generate_args('_%s_signal_info_%s_ARG'%(i.name_lower, s.name_lower), s.args)
-
-                    num_anno = self.generate_annotations('_%s_signal_%s_annotation_info'%(i.name_lower, s.name_lower), s.annotations)
-                    self.outfile.write('static const _ExtendedGDBusSignalInfo _%s_signal_info_%s =\n'
-                                       '{\n'
-                                       '  {\n'
-                                       '    -1,\n'
-                                       '    (gchar *) "%s",\n'%(i.name_lower, s.name_lower, s.name))
-                    if len(s.args) == 0:
-                        self.outfile.write('    NULL,\n')
-                    else:
-                        self.outfile.write('    (GDBusArgInfo **) &_%s_signal_info_%s_ARG_pointers,\n'%(i.name_lower, s.name_lower))
-                    if num_anno == 0:
-                        self.outfile.write('    NULL\n')
-                    else:
-                        self.outfile.write('    (GDBusAnnotationInfo **) &_%s_signal_%s_annotation_info_pointers\n'%(i.name_lower, s.name_lower))
-                    self.outfile.write('  },\n'
-                                       '  "%s"\n'
-                                       %(s.name_hyphen))
-                    self.outfile.write('};\n'
-                                       '\n')
-
-                self.outfile.write('static const GDBusSignalInfo * const _%s_signal_info_pointers[] =\n'
-                                   '{\n'%(i.name_lower))
-                for s in i.signals:
-                    self.outfile.write('  &_%s_signal_info_%s.parent_struct,\n'%(i.name_lower, s.name_lower))
-                self.outfile.write('  NULL\n'
-                                   '};\n'
-                                   '\n')
+        if len(i.signals) > 0:
+            for s in i.signals:
+                self.generate_args(
+                    "_%s_signal_info_%s_ARG" % (i.name_lower, s.name_lower), s.args
+                )
+
+                num_anno = self.generate_annotations(
+                    "_%s_signal_%s_annotation_info" % (i.name_lower, s.name_lower),
+                    s.annotations,
+                )
+                self.outfile.write(
+                    "static const _ExtendedGDBusSignalInfo _%s_signal_info_%s =\n"
+                    "{\n"
+                    "  {\n"
+                    "    -1,\n"
+                    '    (gchar *) "%s",\n' % (i.name_lower, s.name_lower, s.name)
+                )
+                if len(s.args) == 0:
+                    self.outfile.write("    NULL,\n")
+                else:
+                    self.outfile.write(
+                        "    (GDBusArgInfo **) &_%s_signal_info_%s_ARG_pointers,\n"
+                        % (i.name_lower, s.name_lower)
+                    )
+                if num_anno == 0:
+                    self.outfile.write("    NULL\n")
+                else:
+                    self.outfile.write(
+                        "    (GDBusAnnotationInfo **) &_%s_signal_%s_annotation_info_pointers\n"
+                        % (i.name_lower, s.name_lower)
+                    )
+                self.outfile.write("  },\n" '  "%s"\n' % (s.name_hyphen))
+                self.outfile.write("};\n" "\n")
+
+            self.outfile.write(
+                "static const GDBusSignalInfo * const _%s_signal_info_pointers[] =\n"
+                "{\n" % (i.name_lower)
+            )
+            for s in i.signals:
+                self.outfile.write(
+                    "  &_%s_signal_info_%s.parent_struct,\n"
+                    % (i.name_lower, s.name_lower)
+                )
+            self.outfile.write("  NULL\n" "};\n" "\n")
 
-            # ---
+        # ---
 
-            if len(i.properties) > 0:
-                for p in i.properties:
-                    if p.readable and p.writable:
-                        access = 'G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE'
-                    elif p.readable:
-                        access = 'G_DBUS_PROPERTY_INFO_FLAGS_READABLE'
-                    elif p.writable:
-                        access = 'G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE'
-                    else:
-                        access = 'G_DBUS_PROPERTY_INFO_FLAGS_NONE'
-                    num_anno = self.generate_annotations('_%s_property_%s_annotation_info'%(i.name_lower, p.name_lower), p.annotations)
-                    self.outfile.write('static const _ExtendedGDBusPropertyInfo _%s_property_info_%s =\n'
-                                       '{\n'
-                                       '  {\n'
-                                       '    -1,\n'
-                                       '    (gchar *) "%s",\n'
-                                       '    (gchar *) "%s",\n'
-                                       '    %s,\n'%(i.name_lower, p.name_lower, p.name, p.arg.signature, access))
-                    if num_anno == 0:
-                        self.outfile.write('    NULL\n')
-                    else:
-                        self.outfile.write('    (GDBusAnnotationInfo **) &_%s_property_%s_annotation_info_pointers\n'%(i.name_lower, p.name_lower))
-                    self.outfile.write('  },\n'
-                                       '  "%s",\n'
-                                       %(p.name_hyphen))
-                    if not utils.lookup_annotation(p.annotations, 'org.gtk.GDBus.C.ForceGVariant'):
-                        self.outfile.write('  FALSE,\n')
-                    else:
-                        self.outfile.write('  TRUE,\n')
-                    if p.emits_changed_signal:
-                        self.outfile.write('  TRUE\n')
-                    else:
-                        self.outfile.write('  FALSE\n')
-                    self.outfile.write('};\n'
-                                       '\n')
+        if len(i.properties) > 0:
+            for p in i.properties:
+                if p.readable and p.writable:
+                    access = "G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE"
+                elif p.readable:
+                    access = "G_DBUS_PROPERTY_INFO_FLAGS_READABLE"
+                elif p.writable:
+                    access = "G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE"
+                else:
+                    access = "G_DBUS_PROPERTY_INFO_FLAGS_NONE"
+                num_anno = self.generate_annotations(
+                    "_%s_property_%s_annotation_info" % (i.name_lower, p.name_lower),
+                    p.annotations,
+                )
+                self.outfile.write(
+                    "static const _ExtendedGDBusPropertyInfo _%s_property_info_%s =\n"
+                    "{\n"
+                    "  {\n"
+                    "    -1,\n"
+                    '    (gchar *) "%s",\n'
+                    '    (gchar *) "%s",\n'
+                    "    %s,\n"
+                    % (i.name_lower, p.name_lower, p.name, p.arg.signature, access)
+                )
+                if num_anno == 0:
+                    self.outfile.write("    NULL\n")
+                else:
+                    self.outfile.write(
+                        "    (GDBusAnnotationInfo **) &_%s_property_%s_annotation_info_pointers\n"
+                        % (i.name_lower, p.name_lower)
+                    )
+                self.outfile.write("  },\n" '  "%s",\n' % (p.name_hyphen))
+                if not utils.lookup_annotation(
+                    p.annotations, "org.gtk.GDBus.C.ForceGVariant"
+                ):
+                    self.outfile.write("  FALSE,\n")
+                else:
+                    self.outfile.write("  TRUE,\n")
+                if p.emits_changed_signal:
+                    self.outfile.write("  TRUE\n")
+                else:
+                    self.outfile.write("  FALSE\n")
+                self.outfile.write("};\n" "\n")
 
-                self.outfile.write('static const GDBusPropertyInfo * const _%s_property_info_pointers[] =\n'
-                                   '{\n'%(i.name_lower))
-                for p in i.properties:
-                    self.outfile.write('  &_%s_property_info_%s.parent_struct,\n'%(i.name_lower, p.name_lower))
-                self.outfile.write('  NULL\n'
-                                   '};\n'
-                                   '\n')
-
-            num_anno = self.generate_annotations('_%s_annotation_info'%(i.name_lower), i.annotations)
-            self.outfile.write('static const _ExtendedGDBusInterfaceInfo _%s_interface_info =\n'
-                               '{\n'
-                               '  {\n'
-                               '    -1,\n'
-                               '    (gchar *) "%s",\n'%(i.name_lower, i.name))
-            if len(i.methods) == 0:
-                self.outfile.write('    NULL,\n')
-            else:
-                self.outfile.write('    (GDBusMethodInfo **) &_%s_method_info_pointers,\n'%(i.name_lower))
-            if len(i.signals) == 0:
-                self.outfile.write('    NULL,\n')
-            else:
-                self.outfile.write('    (GDBusSignalInfo **) &_%s_signal_info_pointers,\n'%(i.name_lower))
-            if len(i.properties) == 0:
-                self.outfile.write('    NULL,\n')
-            else:
-                self.outfile.write('    (GDBusPropertyInfo **) &_%s_property_info_pointers,\n'%(i.name_lower))
-            if num_anno == 0:
-                self.outfile.write('    NULL\n')
-            else:
-                self.outfile.write('    (GDBusAnnotationInfo **) &_%s_annotation_info_pointers\n'%(i.name_lower))
-            self.outfile.write('  },\n'
-                               '  "%s",\n'
-                               '};\n'
-                               '\n'
-                               %(i.name_hyphen))
-            self.outfile.write('\n')
-            self.outfile.write(self.docbook_gen.expand(
-                    '/**\n'
-                    ' * %s_interface_info:\n'
-                    ' *\n'
-                    ' * Gets a machine-readable description of the #%s D-Bus interface.\n'
-                    ' *\n'
-                    ' * Returns: (transfer none): A #GDBusInterfaceInfo. Do not free.\n'
-                    %(i.name_lower, i.name), False))
-            self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0)
-            self.outfile.write('GDBusInterfaceInfo *\n'
-                               '%s_interface_info (void)\n'
-                               '{\n'
-                               '  return (GDBusInterfaceInfo *) &_%s_interface_info.parent_struct;\n'
-                                '}\n'
-                                '\n'%(i.name_lower, i.name_lower))
-
-            self.outfile.write(self.docbook_gen.expand(
-                    '/**\n'
-                    ' * %s_override_properties:\n'
-                    ' * @klass: The class structure for a #GObject derived class.\n'
-                    ' * @property_id_begin: The property id to assign to the first overridden property.\n'
-                    ' *\n'
-                    ' * Overrides all #GObject properties in the #%s interface for a concrete class.\n'
-                    ' * The properties are overridden in the order they are defined.\n'
-                    ' *\n'
-                    ' * Returns: The last property id.\n'
-                    %(i.name_lower, i.camel_name), False))
-            self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0)
-            self.outfile.write('guint\n'
-                               '%s_override_properties (GObjectClass *klass, guint property_id_begin)\n'
-                               '{\n'%(i.name_lower))
+            self.outfile.write(
+                "static const GDBusPropertyInfo * const _%s_property_info_pointers[] =\n"
+                "{\n" % (i.name_lower)
+            )
             for p in i.properties:
-                self.outfile.write('  g_object_class_override_property (klass, property_id_begin++, "%s");\n'%(p.name_hyphen))
-            self.outfile.write('  return property_id_begin - 1;\n'
-                               '}\n'
-                               '\n')
-            self.outfile.write('\n')
+                self.outfile.write(
+                    "  &_%s_property_info_%s.parent_struct,\n"
+                    % (i.name_lower, p.name_lower)
+                )
+            self.outfile.write("  NULL\n" "};\n" "\n")
+
+        num_anno = self.generate_annotations(
+            "_%s_annotation_info" % (i.name_lower), i.annotations
+        )
+        self.outfile.write(
+            "static const _ExtendedGDBusInterfaceInfo _%s_interface_info =\n"
+            "{\n"
+            "  {\n"
+            "    -1,\n"
+            '    (gchar *) "%s",\n' % (i.name_lower, i.name)
+        )
+        if len(i.methods) == 0:
+            self.outfile.write("    NULL,\n")
+        else:
+            self.outfile.write(
+                "    (GDBusMethodInfo **) &_%s_method_info_pointers,\n" % (i.name_lower)
+            )
+        if len(i.signals) == 0:
+            self.outfile.write("    NULL,\n")
+        else:
+            self.outfile.write(
+                "    (GDBusSignalInfo **) &_%s_signal_info_pointers,\n" % (i.name_lower)
+            )
+        if len(i.properties) == 0:
+            self.outfile.write("    NULL,\n")
+        else:
+            self.outfile.write(
+                "    (GDBusPropertyInfo **) &_%s_property_info_pointers,\n"
+                % (i.name_lower)
+            )
+        if num_anno == 0:
+            self.outfile.write("    NULL\n")
+        else:
+            self.outfile.write(
+                "    (GDBusAnnotationInfo **) &_%s_annotation_info_pointers\n"
+                % (i.name_lower)
+            )
+        self.outfile.write("  },\n" '  "%s",\n' "};\n" "\n" % (i.name_hyphen))
+        self.outfile.write("\n")
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %s_interface_info:\n"
+                " *\n"
+                " * Gets a machine-readable description of the #%s D-Bus interface.\n"
+                " *\n"
+                " * Returns: (transfer none): A #GDBusInterfaceInfo. Do not free.\n"
+                % (i.name_lower, i.name),
+                False,
+            )
+        )
+        self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0)
+        self.outfile.write(
+            "GDBusInterfaceInfo *\n"
+            "%s_interface_info (void)\n"
+            "{\n"
+            "  return (GDBusInterfaceInfo *) &_%s_interface_info.parent_struct;\n"
+            "}\n"
+            "\n" % (i.name_lower, i.name_lower)
+        )
+
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %s_override_properties:\n"
+                " * @klass: The class structure for a #GObject derived class.\n"
+                " * @property_id_begin: The property id to assign to the first overridden property.\n"
+                " *\n"
+                " * Overrides all #GObject properties in the #%s interface for a concrete class.\n"
+                " * The properties are overridden in the order they are defined.\n"
+                " *\n"
+                " * Returns: The last property id.\n" % (i.name_lower, i.camel_name),
+                False,
+            )
+        )
+        self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0)
+        self.outfile.write(
+            "guint\n"
+            "%s_override_properties (GObjectClass *klass, guint property_id_begin)\n"
+            "{\n" % (i.name_lower)
+        )
+        for p in i.properties:
+            self.outfile.write(
+                '  g_object_class_override_property (klass, property_id_begin++, "%s");\n'
+                % (p.name_hyphen)
+            )
+        self.outfile.write("  return property_id_begin - 1;\n" "}\n" "\n")
+        self.outfile.write("\n")
 
     # ----------------------------------------------------------------------------------------------------
 
     def generate_interface(self, i):
-        self.outfile.write('\n')
-
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * %s:\n'
-                ' *\n'
-                ' * Abstract interface type for the D-Bus interface #%s.\n'
-                %(i.camel_name, i.name), False))
+        self.outfile.write("\n")
+
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %s:\n"
+                " *\n"
+                " * Abstract interface type for the D-Bus interface #%s.\n"
+                % (i.camel_name, i.name),
+                False,
+            )
+        )
         self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0)
-        self.outfile.write('\n')
+        self.outfile.write("\n")
 
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * %sIface:\n'
-                ' * @parent_iface: The parent interface.\n'
-                %(i.camel_name), False))
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %sIface:\n"
+                " * @parent_iface: The parent interface.\n" % (i.camel_name),
+                False,
+            )
+        )
 
         doc_bits = {}
         if len(i.methods) > 0:
             for m in i.methods:
-                key = (m.since, '_method_%s'%m.name_lower)
-                value  = '@handle_%s: '%(m.name_lower)
-                value += 'Handler for the #%s::handle-%s signal.'%(i.camel_name, m.name_hyphen)
+                key = (m.since, "_method_%s" % m.name_lower)
+                value = "@handle_%s: " % (m.name_lower)
+                value += "Handler for the #%s::handle-%s signal." % (
+                    i.camel_name,
+                    m.name_hyphen,
+                )
                 doc_bits[key] = value
         if len(i.signals) > 0:
             for s in i.signals:
-                key = (s.since, '_signal_%s'%s.name_lower)
-                value  = '@%s: '%(s.name_lower)
-                value += 'Handler for the #%s::%s signal.'%(i.camel_name, s.name_hyphen)
+                key = (s.since, "_signal_%s" % s.name_lower)
+                value = "@%s: " % (s.name_lower)
+                value += "Handler for the #%s::%s signal." % (
+                    i.camel_name,
+                    s.name_hyphen,
+                )
                 doc_bits[key] = value
         if len(i.properties) > 0:
             for p in i.properties:
-                key = (p.since, '_prop_get_%s'%p.name_lower)
-                value  = '@get_%s: '%(p.name_lower)
-                value += 'Getter for the #%s:%s property.'%(i.camel_name, p.name_hyphen)
+                key = (p.since, "_prop_get_%s" % p.name_lower)
+                value = "@get_%s: " % (p.name_lower)
+                value += "Getter for the #%s:%s property." % (
+                    i.camel_name,
+                    p.name_hyphen,
+                )
                 doc_bits[key] = value
         for key in sorted(doc_bits.keys(), key=utils.version_cmp_key):
-            self.outfile.write(' * %s\n'%doc_bits[key])
-
-        self.outfile.write(self.docbook_gen.expand(
-                ' *\n'
-                ' * Virtual table for the D-Bus interface #%s.\n'
-                %(i.name), False))
+            self.outfile.write(" * %s\n" % doc_bits[key])
+
+        self.outfile.write(
+            self.docbook_gen.expand(
+                " *\n" " * Virtual table for the D-Bus interface #%s.\n" % (i.name),
+                False,
+            )
+        )
         self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0)
-        self.outfile.write('\n')
-
-        self.outfile.write('typedef %sIface %sInterface;\n'%(i.camel_name, i.camel_name))
-        self.outfile.write('G_DEFINE_INTERFACE (%s, %s, G_TYPE_OBJECT)\n'%(i.camel_name, i.name_lower))
-        self.outfile.write('\n')
-
-        self.outfile.write('static void\n'
-                           '%s_default_init (%sIface *iface)\n'
-                           '{\n'%(i.name_lower, i.camel_name));
+        self.outfile.write("\n")
+
+        self.outfile.write(
+            "typedef %sIface %sInterface;\n" % (i.camel_name, i.camel_name)
+        )
+        self.outfile.write(
+            "G_DEFINE_INTERFACE (%s, %s, G_TYPE_OBJECT)\n"
+            % (i.camel_name, i.name_lower)
+        )
+        self.outfile.write("\n")
+
+        self.outfile.write(
+            "static void\n"
+            "%s_default_init (%sIface *iface)\n"
+            "{\n" % (i.name_lower, i.camel_name)
+        )
 
         if len(i.methods) > 0:
-            self.outfile.write('  /* GObject signals for incoming D-Bus method calls: */\n')
+            self.outfile.write(
+                "  /* GObject signals for incoming D-Bus method calls: */\n"
+            )
             for m in i.methods:
-                self.outfile.write(self.docbook_gen.expand(
-                        '  /**\n'
-                        '   * %s::handle-%s:\n'
-                        '   * @object: A #%s.\n'
-                        '   * @invocation: A #GDBusMethodInvocation.\n'
-                        %(i.camel_name, m.name_hyphen, i.camel_name), False))
+                self.outfile.write(
+                    self.docbook_gen.expand(
+                        "  /**\n"
+                        "   * %s::handle-%s:\n"
+                        "   * @object: A #%s.\n"
+                        "   * @invocation: A #GDBusMethodInvocation.\n"
+                        % (i.camel_name, m.name_hyphen, i.camel_name),
+                        False,
+                    )
+                )
                 if m.unix_fd:
-                    self.outfile.write('   * @fd_list: (nullable): A #GUnixFDList or %NULL.\n')
+                    self.outfile.write(
+                        "   * @fd_list: (nullable): A #GUnixFDList or %NULL.\n"
+                    )
                 for a in m.in_args:
-                    self.outfile.write('   * @arg_%s: Argument passed by remote caller.\n'%(a.name))
-                self.outfile.write(self.docbook_gen.expand(
-                        '   *\n'
-                        '   * Signal emitted when a remote caller is invoking the %s.%s() D-Bus method.\n'
-                        '   *\n'
-                        '   * If a signal handler returns %%TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call %s_complete_%s() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %%G_DBUS_ERROR_UNKNOWN_METHOD error is returned.\n'
-                        '   *\n'
-                        '   * Returns: %%G_DBUS_METHOD_INVOCATION_HANDLED or %%TRUE if the invocation was handled, %%G_DBUS_METHOD_INVOCATION_UNHANDLED or %%FALSE to let other signal handlers run.\n'
-                        %(i.name, m.name, i.name_lower, m.name_lower), False))
+                    self.outfile.write(
+                        "   * @arg_%s: Argument passed by remote caller.\n" % (a.name)
+                    )
+                self.outfile.write(
+                    self.docbook_gen.expand(
+                        "   *\n"
+                        "   * Signal emitted when a remote caller is invoking the %s.%s() D-Bus method.\n"
+                        "   *\n"
+                        "   * If a signal handler returns %%TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call %s_complete_%s() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %%G_DBUS_ERROR_UNKNOWN_METHOD error is returned.\n"
+                        "   *\n"
+                        "   * Returns: %%G_DBUS_METHOD_INVOCATION_HANDLED or %%TRUE if the invocation was handled, %%G_DBUS_METHOD_INVOCATION_UNHANDLED or %%FALSE to let other signal handlers run.\n"
+                        % (i.name, m.name, i.name_lower, m.name_lower),
+                        False,
+                    )
+                )
                 self.write_gtkdoc_deprecated_and_since_and_close(m, self.outfile, 2)
                 if m.unix_fd:
                     extra_args = 2
                 else:
                     extra_args = 1
-                self.outfile.write('  g_signal_new ("handle-%s",\n'
-                                   '    G_TYPE_FROM_INTERFACE (iface),\n'
-                                   '    G_SIGNAL_RUN_LAST,\n'
-                                   '    G_STRUCT_OFFSET (%sIface, handle_%s),\n'
-                                   '    g_signal_accumulator_true_handled,\n'
-                                   '    NULL,\n' # accu_data
-                                   '    g_cclosure_marshal_generic,\n'
-                                   '    G_TYPE_BOOLEAN,\n'
-                                   '    %d,\n'
-                                   '    G_TYPE_DBUS_METHOD_INVOCATION'
-                                   %(m.name_hyphen, i.camel_name, m.name_lower, len(m.in_args) + extra_args))
+                self.outfile.write(
+                    '  g_signal_new ("handle-%s",\n'
+                    "    G_TYPE_FROM_INTERFACE (iface),\n"
+                    "    G_SIGNAL_RUN_LAST,\n"
+                    "    G_STRUCT_OFFSET (%sIface, handle_%s),\n"
+                    "    g_signal_accumulator_true_handled,\n"
+                    "    NULL,\n"  # accu_data
+                    "    g_cclosure_marshal_generic,\n"
+                    "    G_TYPE_BOOLEAN,\n"
+                    "    %d,\n"
+                    "    G_TYPE_DBUS_METHOD_INVOCATION"
+                    % (
+                        m.name_hyphen,
+                        i.camel_name,
+                        m.name_lower,
+                        len(m.in_args) + extra_args,
+                    )
+                )
                 if m.unix_fd:
-                    self.outfile.write(', G_TYPE_UNIX_FD_LIST')
+                    self.outfile.write(", G_TYPE_UNIX_FD_LIST")
                 for a in m.in_args:
-                    self.outfile.write(', %s'%(a.gtype))
-                self.outfile.write(');\n')
-                self.outfile.write('\n')
+                    self.outfile.write(", %s" % (a.gtype))
+                self.outfile.write(");\n")
+                self.outfile.write("\n")
 
         if len(i.signals) > 0:
-            self.outfile.write('  /* GObject signals for received D-Bus signals: */\n')
+            self.outfile.write("  /* GObject signals for received D-Bus signals: */\n")
             for s in i.signals:
-                self.outfile.write(self.docbook_gen.expand(
-                        '  /**\n'
-                        '   * %s::%s:\n'
-                        '   * @object: A #%s.\n'
-                        %(i.camel_name, s.name_hyphen, i.camel_name), False))
+                self.outfile.write(
+                    self.docbook_gen.expand(
+                        "  /**\n"
+                        "   * %s::%s:\n"
+                        "   * @object: A #%s.\n"
+                        % (i.camel_name, s.name_hyphen, i.camel_name),
+                        False,
+                    )
+                )
                 for a in s.args:
-                    self.outfile.write('   * @arg_%s: Argument.\n'%(a.name))
-                self.outfile.write(self.docbook_gen.expand(
-                        '   *\n'
-                        '   * On the client-side, this signal is emitted whenever the D-Bus signal #%s::%s is received.\n'
-                        '   *\n'
-                        '   * On the service-side, this signal can be used with e.g. g_signal_emit_by_name() to make the object emit the D-Bus signal.\n'
-                        %(i.name, s.name), False))
+                    self.outfile.write("   * @arg_%s: Argument.\n" % (a.name))
+                self.outfile.write(
+                    self.docbook_gen.expand(
+                        "   *\n"
+                        "   * On the client-side, this signal is emitted whenever the D-Bus signal #%s::%s is received.\n"
+                        "   *\n"
+                        "   * On the service-side, this signal can be used with e.g. g_signal_emit_by_name() to make the object emit the D-Bus signal.\n"
+                        % (i.name, s.name),
+                        False,
+                    )
+                )
                 self.write_gtkdoc_deprecated_and_since_and_close(s, self.outfile, 2)
-                self.outfile.write('  g_signal_new ("%s",\n'
-                                   '    G_TYPE_FROM_INTERFACE (iface),\n'
-                                   '    G_SIGNAL_RUN_LAST,\n'
-                                   '    G_STRUCT_OFFSET (%sIface, %s),\n'
-                                   '    NULL,\n' # accumulator
-                                   '    NULL,\n' # accu_data
-                                   '    g_cclosure_marshal_generic,\n'
-                                   '    G_TYPE_NONE,\n'
-                                   '    %d'
-                                   %(s.name_hyphen, i.camel_name, s.name_lower, len(s.args)))
+                self.outfile.write(
+                    '  g_signal_new ("%s",\n'
+                    "    G_TYPE_FROM_INTERFACE (iface),\n"
+                    "    G_SIGNAL_RUN_LAST,\n"
+                    "    G_STRUCT_OFFSET (%sIface, %s),\n"
+                    "    NULL,\n"  # accumulator
+                    "    NULL,\n"  # accu_data
+                    "    g_cclosure_marshal_generic,\n"
+                    "    G_TYPE_NONE,\n"
+                    "    %d" % (s.name_hyphen, i.camel_name, s.name_lower, len(s.args))
+                )
                 for a in s.args:
-                    self.outfile.write(', %s'%(a.gtype))
-                self.outfile.write(');\n')
-                self.outfile.write('\n')
+                    self.outfile.write(", %s" % (a.gtype))
+                self.outfile.write(");\n")
+                self.outfile.write("\n")
 
         if len(i.properties) > 0:
-            self.outfile.write('  /* GObject properties for D-Bus properties: */\n')
+            self.outfile.write("  /* GObject properties for D-Bus properties: */\n")
             for p in i.properties:
                 if p.readable and p.writable:
-                    hint = 'Since the D-Bus property for this #GObject property is both readable and writable, it is meaningful to both read from it and write to it on both the service- and client-side.'
+                    hint = "Since the D-Bus property for this #GObject property is both readable and writable, it is meaningful to both read from it and write to it on both the service- and client-side."
                 elif p.readable:
-                    hint = 'Since the D-Bus property for this #GObject property is readable but not writable, it is meaningful to read from it on both the client- and service-side. It is only meaningful, however, to write to it on the service-side.'
+                    hint = "Since the D-Bus property for this #GObject property is readable but not writable, it is meaningful to read from it on both the client- and service-side. It is only meaningful, however, to write to it on the service-side."
                 elif p.writable:
-                    hint = 'Since the D-Bus property for this #GObject property is writable but not readable, it is meaningful to write to it on both the client- and service-side. It is only meaningful, however, to read from it on the service-side.'
+                    hint = "Since the D-Bus property for this #GObject property is writable but not readable, it is meaningful to write to it on both the client- and service-side. It is only meaningful, however, to read from it on the service-side."
                 else:
-                    print_error('Cannot handle property "{}" that neither readable nor writable'.format(p.name))
-                self.outfile.write(self.docbook_gen.expand(
-                        '  /**\n'
-                        '   * %s:%s:\n'
-                        '   *\n'
-                        '   * Represents the D-Bus property #%s:%s.\n'
-                        '   *\n'
-                        '   * %s\n'
-                        %(i.camel_name, p.name_hyphen, i.name, p.name, hint), False))
+                    print_error(
+                        'Cannot handle property "{}" that neither readable nor writable'.format(
+                            p.name
+                        )
+                    )
+                self.outfile.write(
+                    self.docbook_gen.expand(
+                        "  /**\n"
+                        "   * %s:%s:\n"
+                        "   *\n"
+                        "   * Represents the D-Bus property #%s:%s.\n"
+                        "   *\n"
+                        "   * %s\n"
+                        % (i.camel_name, p.name_hyphen, i.name, p.name, hint),
+                        False,
+                    )
+                )
                 self.write_gtkdoc_deprecated_and_since_and_close(p, self.outfile, 2)
-                self.outfile.write('  g_object_interface_install_property (iface,\n')
-                if p.arg.gtype == 'G_TYPE_VARIANT':
-                    s = 'g_param_spec_variant ("%s", "%s", "%s", G_VARIANT_TYPE ("%s"), NULL'%(p.name_hyphen, p.name, p.name, p.arg.signature)
-                elif p.arg.signature == 'b':
-                    s = 'g_param_spec_boolean ("%s", "%s", "%s", FALSE'%(p.name_hyphen, p.name, p.name)
-                elif p.arg.signature == 'y':
-                    s = 'g_param_spec_uchar ("%s", "%s", "%s", 0, 255, 0'%(p.name_hyphen, p.name, p.name)
-                elif p.arg.signature == 'n':
-                    s = 'g_param_spec_int ("%s", "%s", "%s", G_MININT16, G_MAXINT16, 0'%(p.name_hyphen, p.name, p.name)
-                elif p.arg.signature == 'q':
-                    s = 'g_param_spec_uint ("%s", "%s", "%s", 0, G_MAXUINT16, 0'%(p.name_hyphen, p.name, p.name)
-                elif p.arg.signature == 'i':
-                    s = 'g_param_spec_int ("%s", "%s", "%s", G_MININT32, G_MAXINT32, 0'%(p.name_hyphen, p.name, p.name)
-                elif p.arg.signature == 'u':
-                    s = 'g_param_spec_uint ("%s", "%s", "%s", 0, G_MAXUINT32, 0'%(p.name_hyphen, p.name, p.name)
-                elif p.arg.signature == 'x':
-                    s = 'g_param_spec_int64 ("%s", "%s", "%s", G_MININT64, G_MAXINT64, 0'%(p.name_hyphen, p.name, p.name)
-                elif p.arg.signature == 't':
-                    s = 'g_param_spec_uint64 ("%s", "%s", "%s", 0, G_MAXUINT64, 0'%(p.name_hyphen, p.name, p.name)
-                elif p.arg.signature == 'd':
-                    s = 'g_param_spec_double ("%s", "%s", "%s", -G_MAXDOUBLE, G_MAXDOUBLE, 0.0'%(p.name_hyphen, p.name, p.name)
-                elif p.arg.signature == 's':
-                    s = 'g_param_spec_string ("%s", "%s", "%s", NULL'%(p.name_hyphen, p.name, p.name)
-                elif p.arg.signature == 'o':
-                    s = 'g_param_spec_string ("%s", "%s", "%s", NULL'%(p.name_hyphen, p.name, p.name)
-                elif p.arg.signature == 'g':
-                    s = 'g_param_spec_string ("%s", "%s", "%s", NULL'%(p.name_hyphen, p.name, p.name)
-                elif p.arg.signature == 'ay':
-                    s = 'g_param_spec_string ("%s", "%s", "%s", NULL'%(p.name_hyphen, p.name, p.name)
-                elif p.arg.signature == 'as':
-                    s = 'g_param_spec_boxed ("%s", "%s", "%s", G_TYPE_STRV'%(p.name_hyphen, p.name, p.name)
-                elif p.arg.signature == 'ao':
-                    s = 'g_param_spec_boxed ("%s", "%s", "%s", G_TYPE_STRV'%(p.name_hyphen, p.name, p.name)
-                elif p.arg.signature == 'aay':
-                    s = 'g_param_spec_boxed ("%s", "%s", "%s", G_TYPE_STRV'%(p.name_hyphen, p.name, p.name)
+                self.outfile.write("  g_object_interface_install_property (iface,\n")
+                if p.arg.gtype == "G_TYPE_VARIANT":
+                    s = (
+                        'g_param_spec_variant ("%s", "%s", "%s", G_VARIANT_TYPE ("%s"), NULL'
+                        % (p.name_hyphen, p.name, p.name, p.arg.signature)
+                    )
+                elif p.arg.signature == "b":
+                    s = 'g_param_spec_boolean ("%s", "%s", "%s", FALSE' % (
+                        p.name_hyphen,
+                        p.name,
+                        p.name,
+                    )
+                elif p.arg.signature == "y":
+                    s = 'g_param_spec_uchar ("%s", "%s", "%s", 0, 255, 0' % (
+                        p.name_hyphen,
+                        p.name,
+                        p.name,
+                    )
+                elif p.arg.signature == "n":
+                    s = (
+                        'g_param_spec_int ("%s", "%s", "%s", G_MININT16, G_MAXINT16, 0'
+                        % (p.name_hyphen, p.name, p.name)
+                    )
+                elif p.arg.signature == "q":
+                    s = 'g_param_spec_uint ("%s", "%s", "%s", 0, G_MAXUINT16, 0' % (
+                        p.name_hyphen,
+                        p.name,
+                        p.name,
+                    )
+                elif p.arg.signature == "i":
+                    s = (
+                        'g_param_spec_int ("%s", "%s", "%s", G_MININT32, G_MAXINT32, 0'
+                        % (p.name_hyphen, p.name, p.name)
+                    )
+                elif p.arg.signature == "u":
+                    s = 'g_param_spec_uint ("%s", "%s", "%s", 0, G_MAXUINT32, 0' % (
+                        p.name_hyphen,
+                        p.name,
+                        p.name,
+                    )
+                elif p.arg.signature == "x":
+                    s = (
+                        'g_param_spec_int64 ("%s", "%s", "%s", G_MININT64, G_MAXINT64, 0'
+                        % (p.name_hyphen, p.name, p.name)
+                    )
+                elif p.arg.signature == "t":
+                    s = 'g_param_spec_uint64 ("%s", "%s", "%s", 0, G_MAXUINT64, 0' % (
+                        p.name_hyphen,
+                        p.name,
+                        p.name,
+                    )
+                elif p.arg.signature == "d":
+                    s = (
+                        'g_param_spec_double ("%s", "%s", "%s", -G_MAXDOUBLE, G_MAXDOUBLE, 0.0'
+                        % (p.name_hyphen, p.name, p.name)
+                    )
+                elif p.arg.signature == "s":
+                    s = 'g_param_spec_string ("%s", "%s", "%s", NULL' % (
+                        p.name_hyphen,
+                        p.name,
+                        p.name,
+                    )
+                elif p.arg.signature == "o":
+                    s = 'g_param_spec_string ("%s", "%s", "%s", NULL' % (
+                        p.name_hyphen,
+                        p.name,
+                        p.name,
+                    )
+                elif p.arg.signature == "g":
+                    s = 'g_param_spec_string ("%s", "%s", "%s", NULL' % (
+                        p.name_hyphen,
+                        p.name,
+                        p.name,
+                    )
+                elif p.arg.signature == "ay":
+                    s = 'g_param_spec_string ("%s", "%s", "%s", NULL' % (
+                        p.name_hyphen,
+                        p.name,
+                        p.name,
+                    )
+                elif p.arg.signature == "as":
+                    s = 'g_param_spec_boxed ("%s", "%s", "%s", G_TYPE_STRV' % (
+                        p.name_hyphen,
+                        p.name,
+                        p.name,
+                    )
+                elif p.arg.signature == "ao":
+                    s = 'g_param_spec_boxed ("%s", "%s", "%s", G_TYPE_STRV' % (
+                        p.name_hyphen,
+                        p.name,
+                        p.name,
+                    )
+                elif p.arg.signature == "aay":
+                    s = 'g_param_spec_boxed ("%s", "%s", "%s", G_TYPE_STRV' % (
+                        p.name_hyphen,
+                        p.name,
+                        p.name,
+                    )
                 else:
-                    print_error('Unsupported gtype "{}" for GParamSpec'.format(p.arg.gtype))
-                flags = 'G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS'
+                    print_error(
+                        'Unsupported gtype "{}" for GParamSpec'.format(p.arg.gtype)
+                    )
+                flags = "G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS"
                 if p.deprecated:
-                    flags = 'G_PARAM_DEPRECATED | ' + flags
-                self.outfile.write('    %s, %s));'%(s, flags));
-                self.outfile.write('\n')
+                    flags = "G_PARAM_DEPRECATED | " + flags
+                self.outfile.write("    %s, %s));" % (s, flags))
+                self.outfile.write("\n")
 
-        self.outfile.write('}\n'
-                           '\n')
+        self.outfile.write("}\n" "\n")
 
     # ----------------------------------------------------------------------------------------------------
 
@@ -1651,1237 +2319,1585 @@ class CodeGenerator:
         for p in i.properties:
             # getter
             if p.readable and p.writable:
-                hint = 'Since this D-Bus property is both readable and writable, it is meaningful to use this function on both the client- and service-side.'
+                hint = "Since this D-Bus property is both readable and writable, it is meaningful to use this function on both the client- and service-side."
             elif p.readable:
-                hint = 'Since this D-Bus property is readable, it is meaningful to use this function on both the client- and service-side.'
+                hint = "Since this D-Bus property is readable, it is meaningful to use this function on both the client- and service-side."
             elif p.writable:
-                hint = 'Since this D-Bus property is not readable, it is only meaningful to use this function on the service-side.'
+                hint = "Since this D-Bus property is not readable, it is only meaningful to use this function on the service-side."
             else:
-                print_error('Cannot handle property "{}" that neither readable nor writable'.format(p.name))
-            self.outfile.write(self.docbook_gen.expand(
-                    '/**\n'
-                    ' * %s_get_%s: (skip)\n'
-                    ' * @object: A #%s.\n'
-                    ' *\n'
-                    ' * Gets the value of the #%s:%s D-Bus property.\n'
-                    ' *\n'
-                    ' * %s\n'
-                    ' *\n'
-                    %(i.name_lower, p.name_lower, i.camel_name, i.name, p.name, hint), False))
-            if p.arg.free_func != None:
-                self.outfile.write(' * The returned value is only valid until the property changes so on the client-side it is only safe to use this function on the thread where @object was constructed. Use %s_dup_%s() if on another thread.\n'
-                                   ' *\n'
-                                   ' * Returns: (transfer none) (nullable): The property value or %%NULL if the property is not set. Do not free the returned value, it belongs to @object.\n'
-                                   %(i.name_lower, p.name_lower))
+                print_error(
+                    'Cannot handle property "{}" that neither readable nor writable'.format(
+                        p.name
+                    )
+                )
+            self.outfile.write(
+                self.docbook_gen.expand(
+                    "/**\n"
+                    " * %s_get_%s: (skip)\n"
+                    " * @object: A #%s.\n"
+                    " *\n"
+                    " * Gets the value of the #%s:%s D-Bus property.\n"
+                    " *\n"
+                    " * %s\n"
+                    " *\n"
+                    % (i.name_lower, p.name_lower, i.camel_name, i.name, p.name, hint),
+                    False,
+                )
+            )
+            if p.arg.free_func is not None:
+                self.outfile.write(
+                    " * The returned value is only valid until the property changes so on the client-side it is only safe to use this function on the thread where @object was constructed. Use %s_dup_%s() if on another thread.\n"
+                    " *\n"
+                    " * Returns: (transfer none) (nullable): The property value or %%NULL if the property is not set. Do not free the returned value, it belongs to @object.\n"
+                    % (i.name_lower, p.name_lower)
+                )
             else:
-                self.outfile.write(' * Returns: The property value.\n')
+                self.outfile.write(" * Returns: The property value.\n")
             self.write_gtkdoc_deprecated_and_since_and_close(p, self.outfile, 0)
-            self.outfile.write('%s\n'
-                               '%s_get_%s (%s *object)\n'
-                               '{\n'%(p.arg.ctype_in, i.name_lower, p.name_lower, i.camel_name))
-            self.outfile.write('  return %s%s_GET_IFACE (object)->get_%s (object);\n'%(i.ns_upper, i.name_upper, p.name_lower))
-            self.outfile.write('}\n')
-            self.outfile.write('\n')
-            if p.arg.free_func != None:
-
-                self.outfile.write(self.docbook_gen.expand(
-                        '/**\n'
-                        ' * %s_dup_%s: (skip)\n'
-                        ' * @object: A #%s.\n'
-                        ' *\n'
-                        ' * Gets a copy of the #%s:%s D-Bus property.\n'
-                        ' *\n'
-                        ' * %s\n'
-                        ' *\n'
-                        ' * Returns: (transfer full) (nullable): The property value or %%NULL if the property is not set. The returned value should be freed with %s().\n'
-                        %(i.name_lower, p.name_lower, i.camel_name, i.name, p.name, hint, p.arg.free_func), False))
+            self.outfile.write(
+                "%s\n"
+                "%s_get_%s (%s *object)\n"
+                "{\n" % (p.arg.ctype_in, i.name_lower, p.name_lower, i.camel_name)
+            )
+            self.outfile.write(
+                "  return %s%s_GET_IFACE (object)->get_%s (object);\n"
+                % (i.ns_upper, i.name_upper, p.name_lower)
+            )
+            self.outfile.write("}\n")
+            self.outfile.write("\n")
+            if p.arg.free_func is not None:
+
+                self.outfile.write(
+                    self.docbook_gen.expand(
+                        "/**\n"
+                        " * %s_dup_%s: (skip)\n"
+                        " * @object: A #%s.\n"
+                        " *\n"
+                        " * Gets a copy of the #%s:%s D-Bus property.\n"
+                        " *\n"
+                        " * %s\n"
+                        " *\n"
+                        " * Returns: (transfer full) (nullable): The property value or %%NULL if the property is not set. The returned value should be freed with %s().\n"
+                        % (
+                            i.name_lower,
+                            p.name_lower,
+                            i.camel_name,
+                            i.name,
+                            p.name,
+                            hint,
+                            p.arg.free_func,
+                        ),
+                        False,
+                    )
+                )
                 self.write_gtkdoc_deprecated_and_since_and_close(p, self.outfile, 0)
-                self.outfile.write('%s\n'
-                                   '%s_dup_%s (%s *object)\n'
-                                   '{\n'
-                                   '  %svalue;\n'%(p.arg.ctype_in_dup, i.name_lower, p.name_lower, i.camel_name, p.arg.ctype_in_dup))
-                self.outfile.write('  g_object_get (G_OBJECT (object), "%s", &value, NULL);\n'%(p.name_hyphen))
-                self.outfile.write('  return value;\n')
-                self.outfile.write('}\n')
-                self.outfile.write('\n')
+                self.outfile.write(
+                    "%s\n"
+                    "%s_dup_%s (%s *object)\n"
+                    "{\n"
+                    "  %svalue;\n"
+                    % (
+                        p.arg.ctype_in_dup,
+                        i.name_lower,
+                        p.name_lower,
+                        i.camel_name,
+                        p.arg.ctype_in_dup,
+                    )
+                )
+                self.outfile.write(
+                    '  g_object_get (G_OBJECT (object), "%s", &value, NULL);\n'
+                    % (p.name_hyphen)
+                )
+                self.outfile.write("  return value;\n")
+                self.outfile.write("}\n")
+                self.outfile.write("\n")
 
             # setter
             if p.readable and p.writable:
-                hint = 'Since this D-Bus property is both readable and writable, it is meaningful to use this function on both the client- and service-side.'
+                hint = "Since this D-Bus property is both readable and writable, it is meaningful to use this function on both the client- and service-side."
             elif p.readable:
-                hint = 'Since this D-Bus property is not writable, it is only meaningful to use this function on the service-side.'
+                hint = "Since this D-Bus property is not writable, it is only meaningful to use this function on the service-side."
             elif p.writable:
-                hint = 'Since this D-Bus property is writable, it is meaningful to use this function on both the client- and service-side.'
+                hint = "Since this D-Bus property is writable, it is meaningful to use this function on both the client- and service-side."
             else:
-                print_error('Cannot handle property "{}" that neither readable nor writable'.format(p.name))
-            self.outfile.write(self.docbook_gen.expand(
-                    '/**\n'
-                    ' * %s_set_%s: (skip)\n'
-                    ' * @object: A #%s.\n'
-                    ' * @value: The value to set.\n'
-                    ' *\n'
-                    ' * Sets the #%s:%s D-Bus property to @value.\n'
-                    ' *\n'
-                    ' * %s\n'
-                    %(i.name_lower, p.name_lower, i.camel_name, i.name, p.name, hint), False))
+                print_error(
+                    'Cannot handle property "{}" that neither readable nor writable'.format(
+                        p.name
+                    )
+                )
+            self.outfile.write(
+                self.docbook_gen.expand(
+                    "/**\n"
+                    " * %s_set_%s: (skip)\n"
+                    " * @object: A #%s.\n"
+                    " * @value: The value to set.\n"
+                    " *\n"
+                    " * Sets the #%s:%s D-Bus property to @value.\n"
+                    " *\n"
+                    " * %s\n"
+                    % (i.name_lower, p.name_lower, i.camel_name, i.name, p.name, hint),
+                    False,
+                )
+            )
             self.write_gtkdoc_deprecated_and_since_and_close(p, self.outfile, 0)
-            self.outfile.write('void\n'
-                               '%s_set_%s (%s *object, %svalue)\n'
-                               '{\n'%(i.name_lower, p.name_lower, i.camel_name, p.arg.ctype_in, ))
-            self.outfile.write('  g_object_set (G_OBJECT (object), "%s", value, NULL);\n'%(p.name_hyphen))
-            self.outfile.write('}\n')
-            self.outfile.write('\n')
+            self.outfile.write(
+                "void\n"
+                "%s_set_%s (%s *object, %svalue)\n"
+                "{\n" % (i.name_lower, p.name_lower, i.camel_name, p.arg.ctype_in,)
+            )
+            self.outfile.write(
+                '  g_object_set (G_OBJECT (object), "%s", value, NULL);\n'
+                % (p.name_hyphen)
+            )
+            self.outfile.write("}\n")
+            self.outfile.write("\n")
 
     # ---------------------------------------------------------------------------------------------------
 
     def generate_signal_emitters(self, i):
         for s in i.signals:
-            self.outfile.write(self.docbook_gen.expand(
-                    '/**\n'
-                    ' * %s_emit_%s:\n'
-                    ' * @object: A #%s.\n'
-                    %(i.name_lower, s.name_lower, i.camel_name), False))
+            self.outfile.write(
+                self.docbook_gen.expand(
+                    "/**\n"
+                    " * %s_emit_%s:\n"
+                    " * @object: A #%s.\n" % (i.name_lower, s.name_lower, i.camel_name),
+                    False,
+                )
+            )
             for a in s.args:
-                self.outfile.write(' * @arg_%s: Argument to pass with the signal.\n'%(a.name))
-            self.outfile.write(self.docbook_gen.expand(
-                    ' *\n'
-                    ' * Emits the #%s::%s D-Bus signal.\n'
-                    %(i.name, s.name), False))
+                self.outfile.write(
+                    " * @arg_%s: Argument to pass with the signal.\n" % (a.name)
+                )
+            self.outfile.write(
+                self.docbook_gen.expand(
+                    " *\n" " * Emits the #%s::%s D-Bus signal.\n" % (i.name, s.name),
+                    False,
+                )
+            )
             self.write_gtkdoc_deprecated_and_since_and_close(s, self.outfile, 0)
-            self.outfile.write('void\n'
-                               '%s_emit_%s (\n'
-                               '    %s *object'%(i.name_lower, s.name_lower, i.camel_name))
+            self.outfile.write(
+                "void\n"
+                "%s_emit_%s (\n"
+                "    %s *object" % (i.name_lower, s.name_lower, i.camel_name)
+            )
             for a in s.args:
-                self.outfile.write(',\n    %sarg_%s'%(a.ctype_in, a.name))
-            self.outfile.write(')\n'
-                               '{\n'
-                               '  g_signal_emit_by_name (object, "%s"'%(s.name_hyphen))
+                self.outfile.write(",\n    %sarg_%s" % (a.ctype_in, a.name))
+            self.outfile.write(
+                ")\n" "{\n" '  g_signal_emit_by_name (object, "%s"' % (s.name_hyphen)
+            )
             for a in s.args:
-                self.outfile.write(', arg_%s'%a.name)
-            self.outfile.write(');\n')
-            self.outfile.write('}\n'
-                               '\n')
+                self.outfile.write(", arg_%s" % a.name)
+            self.outfile.write(");\n")
+            self.outfile.write("}\n" "\n")
 
     # ---------------------------------------------------------------------------------------------------
 
     def generate_method_calls(self, i):
         for m in i.methods:
             # async begin
-            self.outfile.write('/**\n'
-                               ' * %s_call_%s:\n'
-                               ' * @proxy: A #%sProxy.\n'
-                               %(i.name_lower, m.name_lower, i.camel_name))
+            self.outfile.write(
+                "/**\n"
+                " * %s_call_%s:\n"
+                " * @proxy: A #%sProxy.\n" % (i.name_lower, m.name_lower, i.camel_name)
+            )
             for a in m.in_args:
-                self.outfile.write(' * @arg_%s: Argument to pass with the method invocation.\n'%(a.name))
+                self.outfile.write(
+                    " * @arg_%s: Argument to pass with the method invocation.\n"
+                    % (a.name)
+                )
             if self.glib_min_required >= (2, 64):
-                self.outfile.write(' * @call_flags: Flags from the #GDBusCallFlags enumeration. If you want to allow interactive\n'
-                                   '       authorization be sure to set %G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION.\n'
-                                   ' * @timeout_msec: The timeout in milliseconds (with %G_MAXINT meaning "infinite") or\n'
-                                   '       -1 to use the proxy default timeout.\n')
+                self.outfile.write(
+                    " * @call_flags: Flags from the #GDBusCallFlags enumeration. If you want to allow interactive\n"
+                    "       authorization be sure to set %G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION.\n"
+                    ' * @timeout_msec: The timeout in milliseconds (with %G_MAXINT meaning "infinite") or\n'
+                    "       -1 to use the proxy default timeout.\n"
+                )
             if m.unix_fd:
-                self.outfile.write(' * @fd_list: (nullable): A #GUnixFDList or %NULL.\n')
-            self.outfile.write(self.docbook_gen.expand(
-                    ' * @cancellable: (nullable): A #GCancellable or %%NULL.\n'
-                    ' * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %%NULL.\n'
-                    ' * @user_data: User data to pass to @callback.\n'
-                    ' *\n'
-                    ' * Asynchronously invokes the %s.%s() D-Bus method on @proxy.\n'
-                    ' * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from (see g_main_context_push_thread_default()).\n'
-                    ' * You can then call %s_call_%s_finish() to get the result of the operation.\n'
-                    ' *\n'
-                    ' * See %s_call_%s_sync() for the synchronous, blocking version of this method.\n'
-                    %(i.name, m.name, i.name_lower, m.name_lower, i.name_lower, m.name_lower), False))
+                self.outfile.write(
+                    " * @fd_list: (nullable): A #GUnixFDList or %NULL.\n"
+                )
+            self.outfile.write(
+                self.docbook_gen.expand(
+                    " * @cancellable: (nullable): A #GCancellable or %%NULL.\n"
+                    " * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %%NULL.\n"
+                    " * @user_data: User data to pass to @callback.\n"
+                    " *\n"
+                    " * Asynchronously invokes the %s.%s() D-Bus method on @proxy.\n"
+                    " * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from (see g_main_context_push_thread_default()).\n"
+                    " * You can then call %s_call_%s_finish() to get the result of the operation.\n"
+                    " *\n"
+                    " * See %s_call_%s_sync() for the synchronous, blocking version of this method.\n"
+                    % (
+                        i.name,
+                        m.name,
+                        i.name_lower,
+                        m.name_lower,
+                        i.name_lower,
+                        m.name_lower,
+                    ),
+                    False,
+                )
+            )
             self.write_gtkdoc_deprecated_and_since_and_close(m, self.outfile, 0)
-            self.outfile.write('void\n'
-                               '%s_call_%s (\n'
-                               '    %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
+            self.outfile.write(
+                "void\n"
+                "%s_call_%s (\n"
+                "    %s *proxy" % (i.name_lower, m.name_lower, i.camel_name)
+            )
             for a in m.in_args:
-                self.outfile.write(',\n    %sarg_%s'%(a.ctype_in, a.name))
+                self.outfile.write(",\n    %sarg_%s" % (a.ctype_in, a.name))
             if self.glib_min_required >= (2, 64):
-                self.outfile.write(',\n    GDBusCallFlags call_flags'
-                                   ',\n    gint timeout_msec')
+                self.outfile.write(
+                    ",\n    GDBusCallFlags call_flags" ",\n    gint timeout_msec"
+                )
             if m.unix_fd:
-                self.outfile.write(',\n    GUnixFDList *fd_list')
-            self.outfile.write(',\n'
-                               '    GCancellable *cancellable,\n'
-                               '    GAsyncReadyCallback callback,\n'
-                               '    gpointer user_data)\n'
-                               '{\n')
+                self.outfile.write(",\n    GUnixFDList *fd_list")
+            self.outfile.write(
+                ",\n"
+                "    GCancellable *cancellable,\n"
+                "    GAsyncReadyCallback callback,\n"
+                "    gpointer user_data)\n"
+                "{\n"
+            )
             if m.unix_fd:
-                self.outfile.write('  g_dbus_proxy_call_with_unix_fd_list (G_DBUS_PROXY (proxy),\n')
+                self.outfile.write(
+                    "  g_dbus_proxy_call_with_unix_fd_list (G_DBUS_PROXY (proxy),\n"
+                )
             else:
-                self.outfile.write('  g_dbus_proxy_call (G_DBUS_PROXY (proxy),\n')
-            self.outfile.write('    "%s",\n'
-                               '    g_variant_new ("('%(m.name))
+                self.outfile.write("  g_dbus_proxy_call (G_DBUS_PROXY (proxy),\n")
+            self.outfile.write('    "%s",\n' '    g_variant_new ("(' % (m.name))
             for a in m.in_args:
-                self.outfile.write('%s'%(a.format_in))
+                self.outfile.write("%s" % (a.format_in))
             self.outfile.write(')"')
             for a in m.in_args:
-                self.outfile.write(',\n                   arg_%s'%(a.name))
-            self.outfile.write('),\n')
+                self.outfile.write(",\n                   arg_%s" % (a.name))
+            self.outfile.write("),\n")
             if self.glib_min_required >= (2, 64):
-                self.outfile.write('    call_flags,\n'
-                                   '    timeout_msec,\n')
+                self.outfile.write("    call_flags,\n" "    timeout_msec,\n")
             else:
-                self.outfile.write('    G_DBUS_CALL_FLAGS_NONE,\n'
-                                   '    -1,\n')
+                self.outfile.write("    G_DBUS_CALL_FLAGS_NONE,\n" "    -1,\n")
             if m.unix_fd:
-                self.outfile.write('    fd_list,\n')
-            self.outfile.write('    cancellable,\n'
-                               '    callback,\n'
-                               '    user_data);\n')
-            self.outfile.write('}\n'
-                               '\n')
+                self.outfile.write("    fd_list,\n")
+            self.outfile.write(
+                "    cancellable,\n" "    callback,\n" "    user_data);\n"
+            )
+            self.outfile.write("}\n" "\n")
             # async finish
-            self.outfile.write('/**\n'
-                               ' * %s_call_%s_finish:\n'
-                               ' * @proxy: A #%sProxy.\n'
-                               %(i.name_lower, m.name_lower, i.camel_name))
+            self.outfile.write(
+                "/**\n"
+                " * %s_call_%s_finish:\n"
+                " * @proxy: A #%sProxy.\n" % (i.name_lower, m.name_lower, i.camel_name)
+            )
             for a in m.out_args:
-                self.outfile.write(' * @out_%s: (out) (optional)%s: Return location for return parameter or %%NULL to ignore.\n'%(a.name, ' ' + a.array_annotation if a.array_annotation else ''))
+                self.outfile.write(
+                    " * @out_%s: (out) (optional)%s: Return location for return parameter or %%NULL to ignore.\n"
+                    % (a.name, " " + a.array_annotation if a.array_annotation else "")
+                )
             if m.unix_fd:
-                self.outfile.write(' * @out_fd_list: (out) (optional): Return location for a #GUnixFDList or %NULL to ignore.\n')
-            self.outfile.write(self.docbook_gen.expand(
-                    ' * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %s_call_%s().\n'
-                    ' * @error: Return location for error or %%NULL.\n'
-                    ' *\n'
-                    ' * Finishes an operation started with %s_call_%s().\n'
-                    ' *\n'
-                    ' * Returns: (skip): %%TRUE if the call succeeded, %%FALSE if @error is set.\n'
-                    %(i.name_lower, m.name_lower, i.name_lower, m.name_lower), False))
+                self.outfile.write(
+                    " * @out_fd_list: (out) (optional): Return location for a #GUnixFDList or %NULL to ignore.\n"
+                )
+            self.outfile.write(
+                self.docbook_gen.expand(
+                    " * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %s_call_%s().\n"
+                    " * @error: Return location for error or %%NULL.\n"
+                    " *\n"
+                    " * Finishes an operation started with %s_call_%s().\n"
+                    " *\n"
+                    " * Returns: (skip): %%TRUE if the call succeeded, %%FALSE if @error is set.\n"
+                    % (i.name_lower, m.name_lower, i.name_lower, m.name_lower),
+                    False,
+                )
+            )
             self.write_gtkdoc_deprecated_and_since_and_close(m, self.outfile, 0)
-            self.outfile.write('gboolean\n'
-                               '%s_call_%s_finish (\n'
-                               '    %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
+            self.outfile.write(
+                "gboolean\n"
+                "%s_call_%s_finish (\n"
+                "    %s *proxy" % (i.name_lower, m.name_lower, i.camel_name)
+            )
             for a in m.out_args:
-                self.outfile.write(',\n    %sout_%s'%(a.ctype_out, a.name))
+                self.outfile.write(",\n    %sout_%s" % (a.ctype_out, a.name))
             if m.unix_fd:
-                self.outfile.write(',\n    GUnixFDList **out_fd_list')
-            self.outfile.write(',\n'
-                               '    GAsyncResult *res,\n'
-                               '    GError **error)\n'
-                               '{\n'
-                               '  GVariant *_ret;\n')
+                self.outfile.write(",\n    GUnixFDList **out_fd_list")
+            self.outfile.write(
+                ",\n"
+                "    GAsyncResult *res,\n"
+                "    GError **error)\n"
+                "{\n"
+                "  GVariant *_ret;\n"
+            )
             if m.unix_fd:
-                self.outfile.write('  _ret = g_dbus_proxy_call_with_unix_fd_list_finish (G_DBUS_PROXY (proxy), out_fd_list, res, error);\n')
+                self.outfile.write(
+                    "  _ret = g_dbus_proxy_call_with_unix_fd_list_finish (G_DBUS_PROXY (proxy), out_fd_list, res, error);\n"
+                )
             else:
-                self.outfile.write('  _ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error);\n')
-            self.outfile.write('  if (_ret == NULL)\n'
-                               '    goto _out;\n')
-            self.outfile.write('  g_variant_get (_ret,\n'
-                               '                 \"(')
+                self.outfile.write(
+                    "  _ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error);\n"
+                )
+            self.outfile.write("  if (_ret == NULL)\n" "    goto _out;\n")
+            self.outfile.write("  g_variant_get (_ret,\n" '                 "(')
             for a in m.out_args:
-                self.outfile.write('%s'%(a.format_out))
+                self.outfile.write("%s" % (a.format_out))
             self.outfile.write(')"')
             for a in m.out_args:
-                self.outfile.write(',\n                 out_%s'%(a.name))
-            self.outfile.write(');\n'
-                               '  g_variant_unref (_ret);\n')
-            self.outfile.write('_out:\n'
-                               '  return _ret != NULL;\n'
-                               '}\n'
-                               '\n')
-
+                self.outfile.write(",\n                 out_%s" % (a.name))
+            self.outfile.write(");\n" "  g_variant_unref (_ret);\n")
+            self.outfile.write("_out:\n" "  return _ret != NULL;\n" "}\n" "\n")
 
             # sync
-            self.outfile.write('/**\n'
-                               ' * %s_call_%s_sync:\n'
-                               ' * @proxy: A #%sProxy.\n'
-                               %(i.name_lower, m.name_lower, i.camel_name))
+            self.outfile.write(
+                "/**\n"
+                " * %s_call_%s_sync:\n"
+                " * @proxy: A #%sProxy.\n" % (i.name_lower, m.name_lower, i.camel_name)
+            )
             for a in m.in_args:
-                self.outfile.write(' * @arg_%s: Argument to pass with the method invocation.\n'%(a.name))
+                self.outfile.write(
+                    " * @arg_%s: Argument to pass with the method invocation.\n"
+                    % (a.name)
+                )
             if self.glib_min_required >= (2, 64):
-                self.outfile.write(' * @call_flags: Flags from the #GDBusCallFlags enumeration. If you want to allow interactive\n'
-                                   '       authorization be sure to set %G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION.\n'
-                                   ' * @timeout_msec: The timeout in milliseconds (with %G_MAXINT meaning "infinite") or\n'
-                                   '       -1 to use the proxy default timeout.\n')
+                self.outfile.write(
+                    " * @call_flags: Flags from the #GDBusCallFlags enumeration. If you want to allow interactive\n"
+                    "       authorization be sure to set %G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION.\n"
+                    ' * @timeout_msec: The timeout in milliseconds (with %G_MAXINT meaning "infinite") or\n'
+                    "       -1 to use the proxy default timeout.\n"
+                )
             if m.unix_fd:
-                self.outfile.write(' * @fd_list: (nullable): A #GUnixFDList or %NULL.\n')
+                self.outfile.write(
+                    " * @fd_list: (nullable): A #GUnixFDList or %NULL.\n"
+                )
             for a in m.out_args:
-                self.outfile.write(' * @out_%s: (out) (optional)%s: Return location for return parameter or %%NULL to ignore.\n'%(a.name, ' ' + a.array_annotation if a.array_annotation else ''))
+                self.outfile.write(
+                    " * @out_%s: (out) (optional)%s: Return location for return parameter or %%NULL to ignore.\n"
+                    % (a.name, " " + a.array_annotation if a.array_annotation else "")
+                )
             if m.unix_fd:
-                self.outfile.write(' * @out_fd_list: (out): Return location for a #GUnixFDList or %NULL.\n')
-            self.outfile.write(self.docbook_gen.expand(
-                    ' * @cancellable: (nullable): A #GCancellable or %%NULL.\n'
-                    ' * @error: Return location for error or %%NULL.\n'
-                    ' *\n'
-                    ' * Synchronously invokes the %s.%s() D-Bus method on @proxy. The calling thread is blocked until a reply is received.\n'
-                    ' *\n'
-                    ' * See %s_call_%s() for the asynchronous version of this method.\n'
-                    ' *\n'
-                    ' * Returns: (skip): %%TRUE if the call succeeded, %%FALSE if @error is set.\n'
-                    %(i.name, m.name, i.name_lower, m.name_lower), False))
+                self.outfile.write(
+                    " * @out_fd_list: (out): Return location for a #GUnixFDList or %NULL.\n"
+                )
+            self.outfile.write(
+                self.docbook_gen.expand(
+                    " * @cancellable: (nullable): A #GCancellable or %%NULL.\n"
+                    " * @error: Return location for error or %%NULL.\n"
+                    " *\n"
+                    " * Synchronously invokes the %s.%s() D-Bus method on @proxy. The calling thread is blocked until a reply is received.\n"
+                    " *\n"
+                    " * See %s_call_%s() for the asynchronous version of this method.\n"
+                    " *\n"
+                    " * Returns: (skip): %%TRUE if the call succeeded, %%FALSE if @error is set.\n"
+                    % (i.name, m.name, i.name_lower, m.name_lower),
+                    False,
+                )
+            )
             self.write_gtkdoc_deprecated_and_since_and_close(m, self.outfile, 0)
-            self.outfile.write('gboolean\n'
-                               '%s_call_%s_sync (\n'
-                               '    %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
+            self.outfile.write(
+                "gboolean\n"
+                "%s_call_%s_sync (\n"
+                "    %s *proxy" % (i.name_lower, m.name_lower, i.camel_name)
+            )
             for a in m.in_args:
-                self.outfile.write(',\n    %sarg_%s'%(a.ctype_in, a.name))
+                self.outfile.write(",\n    %sarg_%s" % (a.ctype_in, a.name))
             if self.glib_min_required >= (2, 64):
-                self.outfile.write(',\n    GDBusCallFlags call_flags'
-                                   ',\n    gint timeout_msec')
+                self.outfile.write(
+                    ",\n    GDBusCallFlags call_flags" ",\n    gint timeout_msec"
+                )
             if m.unix_fd:
-                self.outfile.write(',\n    GUnixFDList  *fd_list')
+                self.outfile.write(",\n    GUnixFDList  *fd_list")
             for a in m.out_args:
-                self.outfile.write(',\n    %sout_%s'%(a.ctype_out, a.name))
+                self.outfile.write(",\n    %sout_%s" % (a.ctype_out, a.name))
             if m.unix_fd:
-                self.outfile.write(',\n    GUnixFDList **out_fd_list')
-            self.outfile.write(',\n'
-                               '    GCancellable *cancellable,\n'
-                               '    GError **error)\n'
-                               '{\n'
-                               '  GVariant *_ret;\n')
+                self.outfile.write(",\n    GUnixFDList **out_fd_list")
+            self.outfile.write(
+                ",\n"
+                "    GCancellable *cancellable,\n"
+                "    GError **error)\n"
+                "{\n"
+                "  GVariant *_ret;\n"
+            )
             if m.unix_fd:
-                self.outfile.write('  _ret = g_dbus_proxy_call_with_unix_fd_list_sync (G_DBUS_PROXY (proxy),\n')
+                self.outfile.write(
+                    "  _ret = g_dbus_proxy_call_with_unix_fd_list_sync (G_DBUS_PROXY (proxy),\n"
+                )
             else:
-                self.outfile.write('  _ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),\n')
-            self.outfile.write('    "%s",\n'
-                               '    g_variant_new ("('%(m.name))
+                self.outfile.write(
+                    "  _ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),\n"
+                )
+            self.outfile.write('    "%s",\n' '    g_variant_new ("(' % (m.name))
             for a in m.in_args:
-                self.outfile.write('%s'%(a.format_in))
+                self.outfile.write("%s" % (a.format_in))
             self.outfile.write(')"')
             for a in m.in_args:
-                self.outfile.write(',\n                   arg_%s'%(a.name))
-            self.outfile.write('),\n')
+                self.outfile.write(",\n                   arg_%s" % (a.name))
+            self.outfile.write("),\n")
             if self.glib_min_required >= (2, 64):
-                self.outfile.write('    call_flags,\n'
-                                   '    timeout_msec,\n')
+                self.outfile.write("    call_flags,\n" "    timeout_msec,\n")
             else:
-                self.outfile.write('    G_DBUS_CALL_FLAGS_NONE,\n'
-                                   '    -1,\n')
+                self.outfile.write("    G_DBUS_CALL_FLAGS_NONE,\n" "    -1,\n")
             if m.unix_fd:
-                self.outfile.write('    fd_list,\n'
-                                   '    out_fd_list,\n')
-            self.outfile.write('    cancellable,\n'
-                               '    error);\n'
-                               '  if (_ret == NULL)\n'
-                               '    goto _out;\n')
-            self.outfile.write('  g_variant_get (_ret,\n'
-                               '                 \"(')
+                self.outfile.write("    fd_list,\n" "    out_fd_list,\n")
+            self.outfile.write(
+                "    cancellable,\n"
+                "    error);\n"
+                "  if (_ret == NULL)\n"
+                "    goto _out;\n"
+            )
+            self.outfile.write("  g_variant_get (_ret,\n" '                 "(')
             for a in m.out_args:
-                self.outfile.write('%s'%(a.format_out))
+                self.outfile.write("%s" % (a.format_out))
             self.outfile.write(')"')
             for a in m.out_args:
-                self.outfile.write(',\n                 out_%s'%(a.name))
-            self.outfile.write(');\n'
-                               '  g_variant_unref (_ret);\n')
-            self.outfile.write('_out:\n'
-                               '  return _ret != NULL;\n'
-                               '}\n'
-                               '\n')
+                self.outfile.write(",\n                 out_%s" % (a.name))
+            self.outfile.write(");\n" "  g_variant_unref (_ret);\n")
+            self.outfile.write("_out:\n" "  return _ret != NULL;\n" "}\n" "\n")
 
     # ---------------------------------------------------------------------------------------------------
 
     def generate_method_completers(self, i):
         for m in i.methods:
-            self.outfile.write('/**\n'
-                               ' * %s_complete_%s:\n'
-                               ' * @object: A #%s.\n'
-                               ' * @invocation: (transfer full): A #GDBusMethodInvocation.\n'
-                               %(i.name_lower, m.name_lower, i.camel_name))
+            self.outfile.write(
+                "/**\n"
+                " * %s_complete_%s:\n"
+                " * @object: A #%s.\n"
+                " * @invocation: (transfer full): A #GDBusMethodInvocation.\n"
+                % (i.name_lower, m.name_lower, i.camel_name)
+            )
             if m.unix_fd:
-                self.outfile.write(' * @fd_list: (nullable): A #GUnixFDList or %NULL.\n')
+                self.outfile.write(
+                    " * @fd_list: (nullable): A #GUnixFDList or %NULL.\n"
+                )
             for a in m.out_args:
-                self.outfile.write(' * @%s: Parameter to return.\n'%(a.name))
-            self.outfile.write(self.docbook_gen.expand(
-                    ' *\n'
-                    ' * Helper function used in service implementations to finish handling invocations of the %s.%s() D-Bus method. If you instead want to finish handling an invocation by returning an error, use g_dbus_method_invocation_return_error() or similar.\n'
-                    ' *\n'
-                    ' * This method will free @invocation, you cannot use it afterwards.\n'
-                    %(i.name, m.name), False))
+                self.outfile.write(" * @%s: Parameter to return.\n" % (a.name))
+            self.outfile.write(
+                self.docbook_gen.expand(
+                    " *\n"
+                    " * Helper function used in service implementations to finish handling invocations of the %s.%s() D-Bus method. If you instead want to finish handling an invocation by returning an error, use g_dbus_method_invocation_return_error() or similar.\n"
+                    " *\n"
+                    " * This method will free @invocation, you cannot use it afterwards.\n"
+                    % (i.name, m.name),
+                    False,
+                )
+            )
             self.write_gtkdoc_deprecated_and_since_and_close(m, self.outfile, 0)
-            self.outfile.write('void\n'
-                               '%s_complete_%s (\n'
-                               '    %s *object,\n'
-                               '    GDBusMethodInvocation *invocation'%(i.name_lower, m.name_lower, i.camel_name))
+            self.outfile.write(
+                "void\n"
+                "%s_complete_%s (\n"
+                "    %s *object,\n"
+                "    GDBusMethodInvocation *invocation"
+                % (i.name_lower, m.name_lower, i.camel_name)
+            )
             if m.unix_fd:
-                self.outfile.write(',\n    GUnixFDList *fd_list')
+                self.outfile.write(",\n    GUnixFDList *fd_list")
             for a in m.out_args:
-                self.outfile.write(',\n    %s%s'%(a.ctype_in, a.name))
-            self.outfile.write(')\n'
-                               '{\n')
+                self.outfile.write(",\n    %s%s" % (a.ctype_in, a.name))
+            self.outfile.write(")\n" "{\n")
 
             if m.unix_fd:
-                self.outfile.write('  g_dbus_method_invocation_return_value_with_unix_fd_list (invocation,\n'
-                                   '    g_variant_new ("(')
+                self.outfile.write(
+                    "  g_dbus_method_invocation_return_value_with_unix_fd_list (invocation,\n"
+                    '    g_variant_new ("('
+                )
             else:
-                self.outfile.write('  g_dbus_method_invocation_return_value (invocation,\n'
-                                   '    g_variant_new ("(')
+                self.outfile.write(
+                    "  g_dbus_method_invocation_return_value (invocation,\n"
+                    '    g_variant_new ("('
+                )
             for a in m.out_args:
-                self.outfile.write('%s'%(a.format_in))
+                self.outfile.write("%s" % (a.format_in))
             self.outfile.write(')"')
             for a in m.out_args:
-                self.outfile.write(',\n                   %s'%(a.name))
+                self.outfile.write(",\n                   %s" % (a.name))
             if m.unix_fd:
-                self.outfile.write('),\n    fd_list);\n')
+                self.outfile.write("),\n    fd_list);\n")
             else:
-                self.outfile.write('));\n')
-            self.outfile.write('}\n'
-                               '\n')
+                self.outfile.write("));\n")
+            self.outfile.write("}\n" "\n")
 
     # ---------------------------------------------------------------------------------------------------
 
     def generate_proxy(self, i):
         # class boilerplate
-        self.outfile.write('/* ------------------------------------------------------------------------ */\n'
-                           '\n')
-
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * %sProxy:\n'
-                ' *\n'
-                ' * The #%sProxy structure contains only private data and should only be accessed using the provided API.\n'
-                %(i.camel_name, i.camel_name), False))
+        self.outfile.write(
+            "/* ------------------------------------------------------------------------ */\n"
+            "\n"
+        )
+
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %sProxy:\n"
+                " *\n"
+                " * The #%sProxy structure contains only private data and should only be accessed using the provided API.\n"
+                % (i.camel_name, i.camel_name),
+                False,
+            )
+        )
         self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0)
-        self.outfile.write('\n')
-
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * %sProxyClass:\n'
-                ' * @parent_class: The parent class.\n'
-                ' *\n'
-                ' * Class structure for #%sProxy.\n'
-                %(i.camel_name, i.camel_name), False))
+        self.outfile.write("\n")
+
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %sProxyClass:\n"
+                " * @parent_class: The parent class.\n"
+                " *\n"
+                " * Class structure for #%sProxy.\n" % (i.camel_name, i.camel_name),
+                False,
+            )
+        )
         self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0)
-        self.outfile.write('\n')
-
-        self.outfile.write('struct _%sProxyPrivate\n'
-                           '{\n'
-                           '  GData *qdata;\n'
-                           '};\n'
-                           '\n'%i.camel_name)
-
-        self.outfile.write('static void %s_proxy_iface_init (%sIface *iface);\n'
-                           '\n'%(i.name_lower, i.camel_name))
-        self.outfile.write('#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38\n')
-        self.outfile.write('G_DEFINE_TYPE_WITH_CODE (%sProxy, %s_proxy, G_TYPE_DBUS_PROXY,\n'%(i.camel_name, i.name_lower))
-        self.outfile.write('                         G_ADD_PRIVATE (%sProxy)\n'%(i.camel_name))
-        self.outfile.write('                         G_IMPLEMENT_INTERFACE (%sTYPE_%s, %s_proxy_iface_init))\n\n'%(i.ns_upper, i.name_upper, i.name_lower))
-        self.outfile.write('#else\n')
-        self.outfile.write('G_DEFINE_TYPE_WITH_CODE (%sProxy, %s_proxy, G_TYPE_DBUS_PROXY,\n'%(i.camel_name, i.name_lower))
-        self.outfile.write('                         G_IMPLEMENT_INTERFACE (%sTYPE_%s, %s_proxy_iface_init))\n\n'%(i.ns_upper, i.name_upper, i.name_lower))
-        self.outfile.write('#endif\n')
+        self.outfile.write("\n")
+
+        self.outfile.write(
+            "struct _%sProxyPrivate\n"
+            "{\n"
+            "  GData *qdata;\n"
+            "};\n"
+            "\n" % i.camel_name
+        )
+
+        self.outfile.write(
+            "static void %s_proxy_iface_init (%sIface *iface);\n"
+            "\n" % (i.name_lower, i.camel_name)
+        )
+        self.outfile.write("#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38\n")
+        self.outfile.write(
+            "G_DEFINE_TYPE_WITH_CODE (%sProxy, %s_proxy, G_TYPE_DBUS_PROXY,\n"
+            % (i.camel_name, i.name_lower)
+        )
+        self.outfile.write(
+            "                         G_ADD_PRIVATE (%sProxy)\n" % (i.camel_name)
+        )
+        self.outfile.write(
+            "                         G_IMPLEMENT_INTERFACE (%sTYPE_%s, %s_proxy_iface_init))\n\n"
+            % (i.ns_upper, i.name_upper, i.name_lower)
+        )
+        self.outfile.write("#else\n")
+        self.outfile.write(
+            "G_DEFINE_TYPE_WITH_CODE (%sProxy, %s_proxy, G_TYPE_DBUS_PROXY,\n"
+            % (i.camel_name, i.name_lower)
+        )
+        self.outfile.write(
+            "                         G_IMPLEMENT_INTERFACE (%sTYPE_%s, %s_proxy_iface_init))\n\n"
+            % (i.ns_upper, i.name_upper, i.name_lower)
+        )
+        self.outfile.write("#endif\n")
 
         # finalize
-        self.outfile.write('static void\n'
-                           '%s_proxy_finalize (GObject *object)\n'
-                           '{\n'%(i.name_lower))
-        self.outfile.write('  %sProxy *proxy = %s%s_PROXY (object);\n'%(i.camel_name, i.ns_upper, i.name_upper))
-        self.outfile.write('  g_datalist_clear (&proxy->priv->qdata);\n')
-        self.outfile.write('  G_OBJECT_CLASS (%s_proxy_parent_class)->finalize (object);\n'
-                           '}\n'
-                           '\n'%(i.name_lower))
+        self.outfile.write(
+            "static void\n"
+            "%s_proxy_finalize (GObject *object)\n"
+            "{\n" % (i.name_lower)
+        )
+        self.outfile.write(
+            "  %sProxy *proxy = %s%s_PROXY (object);\n"
+            % (i.camel_name, i.ns_upper, i.name_upper)
+        )
+        self.outfile.write("  g_datalist_clear (&proxy->priv->qdata);\n")
+        self.outfile.write(
+            "  G_OBJECT_CLASS (%s_proxy_parent_class)->finalize (object);\n"
+            "}\n"
+            "\n" % (i.name_lower)
+        )
 
         # property accessors
         #
         # Note that we are guaranteed that prop_id starts at 1 and is
         # laid out in the same order as introspection data pointers
         #
-        self.outfile.write('static void\n'
-                           '%s_proxy_get_property (GObject      *object,\n'
-                           '  guint         prop_id,\n'
-                           '  GValue       *value,\n'
-                           '  GParamSpec   *pspec G_GNUC_UNUSED)\n'
-                           '{\n'%(i.name_lower))
+        self.outfile.write(
+            "static void\n"
+            "%s_proxy_get_property (GObject      *object,\n"
+            "  guint         prop_id,\n"
+            "  GValue       *value,\n"
+            "  GParamSpec   *pspec G_GNUC_UNUSED)\n"
+            "{\n" % (i.name_lower)
+        )
         if len(i.properties) > 0:
-            self.outfile.write('  const _ExtendedGDBusPropertyInfo *info;\n'
-                               '  GVariant *variant;\n'
-                               '  g_assert (prop_id != 0 && prop_id - 1 < %d);\n'
-                               '  info = (const _ExtendedGDBusPropertyInfo *) _%s_property_info_pointers[prop_id - 1];\n'
-                               '  variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (object), info->parent_struct.name);\n'
-                               '  if (info->use_gvariant)\n'
-                               '    {\n'
-                               '      g_value_set_variant (value, variant);\n'
-                               '    }\n'
-                               '  else\n'
-                               '    {\n'
-                               # could be that we don't have the value in cache - in that case, we do
-                               # nothing and the user gets the default value for the GType
-                               '      if (variant != NULL)\n'
-                               '        g_dbus_gvariant_to_gvalue (variant, value);\n'
-                               '    }\n'
-                               '  if (variant != NULL)\n'
-                               '    g_variant_unref (variant);\n'
-                               %(len(i.properties), i.name_lower))
-        self.outfile.write('}\n'
-                           '\n')
+            self.outfile.write(
+                "  const _ExtendedGDBusPropertyInfo *info;\n"
+                "  GVariant *variant;\n"
+                "  g_assert (prop_id != 0 && prop_id - 1 < %d);\n"
+                "  info = (const _ExtendedGDBusPropertyInfo *) _%s_property_info_pointers[prop_id - 1];\n"
+                "  variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (object), info->parent_struct.name);\n"
+                "  if (info->use_gvariant)\n"
+                "    {\n"
+                "      g_value_set_variant (value, variant);\n"
+                "    }\n"
+                "  else\n"
+                "    {\n"
+                # could be that we don't have the value in cache - in that case, we do
+                # nothing and the user gets the default value for the GType
+                "      if (variant != NULL)\n"
+                "        g_dbus_gvariant_to_gvalue (variant, value);\n"
+                "    }\n"
+                "  if (variant != NULL)\n"
+                "    g_variant_unref (variant);\n" % (len(i.properties), i.name_lower)
+            )
+        self.outfile.write("}\n" "\n")
         if len(i.properties) > 0:
-            self.outfile.write('static void\n'
-                               '%s_proxy_set_property_cb (GDBusProxy *proxy,\n'
-                               '  GAsyncResult *res,\n'
-                               '  gpointer      user_data)\n'
-                               '{\n'%(i.name_lower))
-            self.outfile.write('  const _ExtendedGDBusPropertyInfo *info = user_data;\n'
-                               '  GError *error;\n'
-                               '  GVariant *_ret;\n'
-                               '  error = NULL;\n'
-                               '  _ret = g_dbus_proxy_call_finish (proxy, res, &error);\n'
-                               '  if (!_ret)\n'
-                               '    {\n'
-                               '      g_warning ("Error setting property \'%%s\' on interface %s: %%s (%%s, %%d)",\n'
-                               '                 info->parent_struct.name, \n'
-                               '                 error->message, g_quark_to_string (error->domain), error->code);\n'
-                               '      g_error_free (error);\n'
-                               '    }\n'
-                               '  else\n'
-                               '    {\n'
-                               '      g_variant_unref (_ret);\n'
-                               '    }\n'
-                               %(i.name))
-            self.outfile.write('}\n'
-                               '\n')
-        self.outfile.write('static void\n'
-                           '%s_proxy_set_property (GObject      *object,\n'
-                           '  guint         prop_id,\n'
-                           '  const GValue *value,\n'
-                           '  GParamSpec   *pspec G_GNUC_UNUSED)\n'
-                           '{\n'%(i.name_lower))
+            self.outfile.write(
+                "static void\n"
+                "%s_proxy_set_property_cb (GDBusProxy *proxy,\n"
+                "  GAsyncResult *res,\n"
+                "  gpointer      user_data)\n"
+                "{\n" % (i.name_lower)
+            )
+            self.outfile.write(
+                "  const _ExtendedGDBusPropertyInfo *info = user_data;\n"
+                "  GError *error;\n"
+                "  GVariant *_ret;\n"
+                "  error = NULL;\n"
+                "  _ret = g_dbus_proxy_call_finish (proxy, res, &error);\n"
+                "  if (!_ret)\n"
+                "    {\n"
+                "      g_warning (\"Error setting property '%%s' on interface %s: %%s (%%s, %%d)\",\n"
+                "                 info->parent_struct.name, \n"
+                "                 error->message, g_quark_to_string (error->domain), error->code);\n"
+                "      g_error_free (error);\n"
+                "    }\n"
+                "  else\n"
+                "    {\n"
+                "      g_variant_unref (_ret);\n"
+                "    }\n" % (i.name)
+            )
+            self.outfile.write("}\n" "\n")
+        self.outfile.write(
+            "static void\n"
+            "%s_proxy_set_property (GObject      *object,\n"
+            "  guint         prop_id,\n"
+            "  const GValue *value,\n"
+            "  GParamSpec   *pspec G_GNUC_UNUSED)\n"
+            "{\n" % (i.name_lower)
+        )
         if len(i.properties) > 0:
-            self.outfile.write('  const _ExtendedGDBusPropertyInfo *info;\n'
-                               '  GVariant *variant;\n'
-                               '  g_assert (prop_id != 0 && prop_id - 1 < %d);\n'
-                               '  info = (const _ExtendedGDBusPropertyInfo *) _%s_property_info_pointers[prop_id - 1];\n'
-                               '  variant = g_dbus_gvalue_to_gvariant (value, G_VARIANT_TYPE (info->parent_struct.signature));\n'
-                               '  g_dbus_proxy_call (G_DBUS_PROXY (object),\n'
-                               '    "org.freedesktop.DBus.Properties.Set",\n'
-                               '    g_variant_new ("(ssv)", "%s", info->parent_struct.name, variant),\n'
-                               '    G_DBUS_CALL_FLAGS_NONE,\n'
-                               '    -1,\n'
-                               '    NULL, (GAsyncReadyCallback) %s_proxy_set_property_cb, (GDBusPropertyInfo *) &info->parent_struct);\n'
-                               '  g_variant_unref (variant);\n'
-                               %(len(i.properties), i.name_lower, i.name, i.name_lower))
-        self.outfile.write('}\n'
-                           '\n')
+            self.outfile.write(
+                "  const _ExtendedGDBusPropertyInfo *info;\n"
+                "  GVariant *variant;\n"
+                "  g_assert (prop_id != 0 && prop_id - 1 < %d);\n"
+                "  info = (const _ExtendedGDBusPropertyInfo *) _%s_property_info_pointers[prop_id - 1];\n"
+                "  variant = g_dbus_gvalue_to_gvariant (value, G_VARIANT_TYPE (info->parent_struct.signature));\n"
+                "  g_dbus_proxy_call (G_DBUS_PROXY (object),\n"
+                '    "org.freedesktop.DBus.Properties.Set",\n'
+                '    g_variant_new ("(ssv)", "%s", info->parent_struct.name, variant),\n'
+                "    G_DBUS_CALL_FLAGS_NONE,\n"
+                "    -1,\n"
+                "    NULL, (GAsyncReadyCallback) %s_proxy_set_property_cb, (GDBusPropertyInfo *) &info->parent_struct);\n"
+                "  g_variant_unref (variant);\n"
+                % (len(i.properties), i.name_lower, i.name, i.name_lower)
+            )
+        self.outfile.write("}\n" "\n")
 
         # signal received
-        self.outfile.write('static void\n'
-                           '%s_proxy_g_signal (GDBusProxy *proxy,\n'
-                           '  const gchar *sender_name G_GNUC_UNUSED,\n'
-                           '  const gchar *signal_name,\n'
-                           '  GVariant *parameters)\n'
-                           '{\n'%(i.name_lower))
-        self.outfile.write('  _ExtendedGDBusSignalInfo *info;\n'
-                           '  GVariantIter iter;\n'
-                           '  GVariant *child;\n'
-                           '  GValue *paramv;\n'
-                           '  gsize num_params;\n'
-                           '  gsize n;\n'
-                           '  guint signal_id;\n');
+        self.outfile.write(
+            "static void\n"
+            "%s_proxy_g_signal (GDBusProxy *proxy,\n"
+            "  const gchar *sender_name G_GNUC_UNUSED,\n"
+            "  const gchar *signal_name,\n"
+            "  GVariant *parameters)\n"
+            "{\n" % (i.name_lower)
+        )
+        self.outfile.write(
+            "  _ExtendedGDBusSignalInfo *info;\n"
+            "  GVariantIter iter;\n"
+            "  GVariant *child;\n"
+            "  GValue *paramv;\n"
+            "  gsize num_params;\n"
+            "  gsize n;\n"
+            "  guint signal_id;\n"
+        )
         # Note: info could be NULL if we are talking to a newer version of the interface
-        self.outfile.write('  info = (_ExtendedGDBusSignalInfo *) g_dbus_interface_info_lookup_signal ((GDBusInterfaceInfo *) &_%s_interface_info.parent_struct, signal_name);\n'
-                           '  if (info == NULL)\n'
-                           '    return;\n'
-                           %(i.name_lower))
-        self.outfile.write('  num_params = g_variant_n_children (parameters);\n'
-                           '  paramv = g_new0 (GValue, num_params + 1);\n'
-                           '  g_value_init (&paramv[0], %sTYPE_%s);\n'
-                           '  g_value_set_object (&paramv[0], proxy);\n'
-                           %(i.ns_upper, i.name_upper))
-        self.outfile.write('  g_variant_iter_init (&iter, parameters);\n'
-                           '  n = 1;\n'
-                           '  while ((child = g_variant_iter_next_value (&iter)) != NULL)\n'
-                           '    {\n'
-                           '      _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.args[n - 1];\n'
-                           '      if (arg_info->use_gvariant)\n'
-                           '        {\n'
-                           '          g_value_init (&paramv[n], G_TYPE_VARIANT);\n'
-                           '          g_value_set_variant (&paramv[n], child);\n'
-                           '          n++;\n'
-                           '        }\n'
-                           '      else\n'
-                           '        g_dbus_gvariant_to_gvalue (child, &paramv[n++]);\n'
-                           '      g_variant_unref (child);\n'
-                           '    }\n'
-                           )
-        self.outfile.write('  signal_id = g_signal_lookup (info->signal_name, %sTYPE_%s);\n'
-                           %(i.ns_upper, i.name_upper))
-        self.outfile.write('  g_signal_emitv (paramv, signal_id, 0, NULL);\n')
-        self.outfile.write('  for (n = 0; n < num_params + 1; n++)\n'
-                           '    g_value_unset (&paramv[n]);\n'
-                           '  g_free (paramv);\n')
-        self.outfile.write('}\n'
-                           '\n')
+        self.outfile.write(
+            "  info = (_ExtendedGDBusSignalInfo *) g_dbus_interface_info_lookup_signal ((GDBusInterfaceInfo *) &_%s_interface_info.parent_struct, signal_name);\n"
+            "  if (info == NULL)\n"
+            "    return;\n" % (i.name_lower)
+        )
+        self.outfile.write(
+            "  num_params = g_variant_n_children (parameters);\n"
+            "  paramv = g_new0 (GValue, num_params + 1);\n"
+            "  g_value_init (&paramv[0], %sTYPE_%s);\n"
+            "  g_value_set_object (&paramv[0], proxy);\n" % (i.ns_upper, i.name_upper)
+        )
+        self.outfile.write(
+            "  g_variant_iter_init (&iter, parameters);\n"
+            "  n = 1;\n"
+            "  while ((child = g_variant_iter_next_value (&iter)) != NULL)\n"
+            "    {\n"
+            "      _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.args[n - 1];\n"
+            "      if (arg_info->use_gvariant)\n"
+            "        {\n"
+            "          g_value_init (&paramv[n], G_TYPE_VARIANT);\n"
+            "          g_value_set_variant (&paramv[n], child);\n"
+            "          n++;\n"
+            "        }\n"
+            "      else\n"
+            "        g_dbus_gvariant_to_gvalue (child, &paramv[n++]);\n"
+            "      g_variant_unref (child);\n"
+            "    }\n"
+        )
+        self.outfile.write(
+            "  signal_id = g_signal_lookup (info->signal_name, %sTYPE_%s);\n"
+            % (i.ns_upper, i.name_upper)
+        )
+        self.outfile.write("  g_signal_emitv (paramv, signal_id, 0, NULL);\n")
+        self.outfile.write(
+            "  for (n = 0; n < num_params + 1; n++)\n"
+            "    g_value_unset (&paramv[n]);\n"
+            "  g_free (paramv);\n"
+        )
+        self.outfile.write("}\n" "\n")
 
         # property changed
-        self.outfile.write('static void\n'
-                           '%s_proxy_g_properties_changed (GDBusProxy *_proxy,\n'
-                           '  GVariant *changed_properties,\n'
-                           '  const gchar *const *invalidated_properties)\n'
-                           '{\n'%(i.name_lower))
+        self.outfile.write(
+            "static void\n"
+            "%s_proxy_g_properties_changed (GDBusProxy *_proxy,\n"
+            "  GVariant *changed_properties,\n"
+            "  const gchar *const *invalidated_properties)\n"
+            "{\n" % (i.name_lower)
+        )
         # Note: info could be NULL if we are talking to a newer version of the interface
-        self.outfile.write('  %sProxy *proxy = %s%s_PROXY (_proxy);\n'
-                           '  guint n;\n'
-                           '  const gchar *key;\n'
-                           '  GVariantIter *iter;\n'
-                           '  _ExtendedGDBusPropertyInfo *info;\n'
-                           '  g_variant_get (changed_properties, "a{sv}", &iter);\n'
-                           '  while (g_variant_iter_next (iter, "{&sv}", &key, NULL))\n'
-                           '    {\n'
-                           '      info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_%s_interface_info.parent_struct, key);\n'
-                           '      g_datalist_remove_data (&proxy->priv->qdata, key);\n'
-                           '      if (info != NULL)\n'
-                           '        g_object_notify (G_OBJECT (proxy), info->hyphen_name);\n'
-                           '    }\n'
-                           '  g_variant_iter_free (iter);\n'
-                           '  for (n = 0; invalidated_properties[n] != NULL; n++)\n'
-                           '    {\n'
-                           '      info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_%s_interface_info.parent_struct, invalidated_properties[n]);\n'
-                           '      g_datalist_remove_data (&proxy->priv->qdata, invalidated_properties[n]);\n'
-                           '      if (info != NULL)\n'
-                           '        g_object_notify (G_OBJECT (proxy), info->hyphen_name);\n'
-                           '    }\n'
-                           '}\n'
-                           '\n'
-                           %(i.camel_name, i.ns_upper, i.name_upper,
-                             i.name_lower, i.name_lower))
+        self.outfile.write(
+            "  %sProxy *proxy = %s%s_PROXY (_proxy);\n"
+            "  guint n;\n"
+            "  const gchar *key;\n"
+            "  GVariantIter *iter;\n"
+            "  _ExtendedGDBusPropertyInfo *info;\n"
+            '  g_variant_get (changed_properties, "a{sv}", &iter);\n'
+            '  while (g_variant_iter_next (iter, "{&sv}", &key, NULL))\n'
+            "    {\n"
+            "      info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_%s_interface_info.parent_struct, key);\n"
+            "      g_datalist_remove_data (&proxy->priv->qdata, key);\n"
+            "      if (info != NULL)\n"
+            "        g_object_notify (G_OBJECT (proxy), info->hyphen_name);\n"
+            "    }\n"
+            "  g_variant_iter_free (iter);\n"
+            "  for (n = 0; invalidated_properties[n] != NULL; n++)\n"
+            "    {\n"
+            "      info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_%s_interface_info.parent_struct, invalidated_properties[n]);\n"
+            "      g_datalist_remove_data (&proxy->priv->qdata, invalidated_properties[n]);\n"
+            "      if (info != NULL)\n"
+            "        g_object_notify (G_OBJECT (proxy), info->hyphen_name);\n"
+            "    }\n"
+            "}\n"
+            "\n" % (i.camel_name, i.ns_upper, i.name_upper, i.name_lower, i.name_lower)
+        )
 
         # property vfuncs
         for p in i.properties:
-            nul_value = '0'
-            if p.arg.free_func != None:
-                nul_value = 'NULL'
-            self.outfile.write('static %s\n'
-                               '%s_proxy_get_%s (%s *object)\n'
-                               '{\n'
-                               '  %sProxy *proxy = %s%s_PROXY (object);\n'
-                               '  GVariant *variant;\n'
-                               '  %svalue = %s;\n'%(p.arg.ctype_in, i.name_lower, p.name_lower, i.camel_name,
-                                                    i.camel_name, i.ns_upper, i.name_upper,
-                                                    p.arg.ctype_in, nul_value))
+            nul_value = "0"
+            if p.arg.free_func is not None:
+                nul_value = "NULL"
+            self.outfile.write(
+                "static %s\n"
+                "%s_proxy_get_%s (%s *object)\n"
+                "{\n"
+                "  %sProxy *proxy = %s%s_PROXY (object);\n"
+                "  GVariant *variant;\n"
+                "  %svalue = %s;\n"
+                % (
+                    p.arg.ctype_in,
+                    i.name_lower,
+                    p.name_lower,
+                    i.camel_name,
+                    i.camel_name,
+                    i.ns_upper,
+                    i.name_upper,
+                    p.arg.ctype_in,
+                    nul_value,
+                )
+            )
             # For some property types, we have to free the returned
             # value (or part of it, e.g. the container) because of how
             # GVariant works.. see https://bugzilla.gnome.org/show_bug.cgi?id=657100
             # for details
             #
-            free_container = False;
-            if p.arg.gvariant_get == 'g_variant_get_strv' or p.arg.gvariant_get == 'g_variant_get_objv' or p.arg.gvariant_get == 'g_variant_get_bytestring_array':
-                free_container = True;
+            free_container = False
+            if (
+                p.arg.gvariant_get == "g_variant_get_strv"
+                or p.arg.gvariant_get == "g_variant_get_objv"
+                or p.arg.gvariant_get == "g_variant_get_bytestring_array"
+            ):
+                free_container = True
             # If already using an old value for strv, objv, bytestring_array (see below),
             # then just return that... that way the result from multiple consecutive calls
             # to the getter are valid as long as they're freed
             #
             if free_container:
-                self.outfile.write('  value = g_datalist_get_data (&proxy->priv->qdata, \"%s\");\n'
-                                   '  if (value != NULL)\n'
-                                   '    return value;\n'
-                                   %(p.name))
-            self.outfile.write('  variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), \"%s\");\n'%(p.name))
-            if p.arg.gtype == 'G_TYPE_VARIANT':
-                self.outfile.write('  value = variant;\n')
-                self.outfile.write('  if (variant != NULL)\n')
-                self.outfile.write('    g_variant_unref (variant);\n')
+                self.outfile.write(
+                    '  value = g_datalist_get_data (&proxy->priv->qdata, "%s");\n'
+                    "  if (value != NULL)\n"
+                    "    return value;\n" % (p.name)
+                )
+            self.outfile.write(
+                '  variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "%s");\n'
+                % (p.name)
+            )
+            if p.arg.gtype == "G_TYPE_VARIANT":
+                self.outfile.write("  value = variant;\n")
+                self.outfile.write("  if (variant != NULL)\n")
+                self.outfile.write("    g_variant_unref (variant);\n")
             else:
-                self.outfile.write('  if (variant != NULL)\n'
-                                   '    {\n')
-                extra_len = ''
-                if p.arg.gvariant_get == 'g_variant_get_string' or p.arg.gvariant_get == 'g_variant_get_strv' or p.arg.gvariant_get == 'g_variant_get_objv' or p.arg.gvariant_get == 'g_variant_get_bytestring_array':
-                    extra_len = ', NULL'
-                self.outfile.write('      value = %s (variant%s);\n'%(p.arg.gvariant_get, extra_len))
+                self.outfile.write("  if (variant != NULL)\n" "    {\n")
+                extra_len = ""
+                if (
+                    p.arg.gvariant_get == "g_variant_get_string"
+                    or p.arg.gvariant_get == "g_variant_get_strv"
+                    or p.arg.gvariant_get == "g_variant_get_objv"
+                    or p.arg.gvariant_get == "g_variant_get_bytestring_array"
+                ):
+                    extra_len = ", NULL"
+                self.outfile.write(
+                    "      value = %s (variant%s);\n" % (p.arg.gvariant_get, extra_len)
+                )
                 if free_container:
-                    self.outfile.write('      g_datalist_set_data_full (&proxy->priv->qdata, \"%s\", (gpointer) value, g_free);\n'
-                                       %(p.name))
-                self.outfile.write('      g_variant_unref (variant);\n')
-                self.outfile.write('    }\n')
-            self.outfile.write('  return value;\n')
-            self.outfile.write('}\n')
-            self.outfile.write('\n')
+                    self.outfile.write(
+                        '      g_datalist_set_data_full (&proxy->priv->qdata, "%s", (gpointer) value, g_free);\n'
+                        % (p.name)
+                    )
+                self.outfile.write("      g_variant_unref (variant);\n")
+                self.outfile.write("    }\n")
+            self.outfile.write("  return value;\n")
+            self.outfile.write("}\n")
+            self.outfile.write("\n")
 
         # class boilerplate
-        self.outfile.write('static void\n'
-                           '%s_proxy_init (%sProxy *proxy)\n'
-                           '{\n'
-                           '#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38\n'
-                           '  proxy->priv = %s_proxy_get_instance_private (proxy);\n'
-                           '#else\n'
-                           '  proxy->priv = G_TYPE_INSTANCE_GET_PRIVATE (proxy, %sTYPE_%s_PROXY, %sProxyPrivate);\n'
-                           '#endif\n\n'
-                           '  g_dbus_proxy_set_interface_info (G_DBUS_PROXY (proxy), %s_interface_info ());\n'
-                           '}\n'
-                           '\n'
-                           %(i.name_lower, i.camel_name,
-                             i.name_lower,
-                             i.ns_upper, i.name_upper, i.camel_name,
-                             i.name_lower))
-        self.outfile.write('static void\n'
-                           '%s_proxy_class_init (%sProxyClass *klass)\n'
-                           '{\n'
-                           '  GObjectClass *gobject_class;\n'
-                           '  GDBusProxyClass *proxy_class;\n'
-                           '\n'
-                           '  gobject_class = G_OBJECT_CLASS (klass);\n'
-                           '  gobject_class->finalize     = %s_proxy_finalize;\n'
-                           '  gobject_class->get_property = %s_proxy_get_property;\n'
-                           '  gobject_class->set_property = %s_proxy_set_property;\n'
-                           '\n'
-                           '  proxy_class = G_DBUS_PROXY_CLASS (klass);\n'
-                           '  proxy_class->g_signal = %s_proxy_g_signal;\n'
-                           '  proxy_class->g_properties_changed = %s_proxy_g_properties_changed;\n'
-                           '\n'%(i.name_lower, i.camel_name,
-                                 i.name_lower, i.name_lower, i.name_lower, i.name_lower, i.name_lower))
+        self.outfile.write(
+            "static void\n"
+            "%s_proxy_init (%sProxy *proxy)\n"
+            "{\n"
+            "#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38\n"
+            "  proxy->priv = %s_proxy_get_instance_private (proxy);\n"
+            "#else\n"
+            "  proxy->priv = G_TYPE_INSTANCE_GET_PRIVATE (proxy, %sTYPE_%s_PROXY, %sProxyPrivate);\n"
+            "#endif\n\n"
+            "  g_dbus_proxy_set_interface_info (G_DBUS_PROXY (proxy), %s_interface_info ());\n"
+            "}\n"
+            "\n"
+            % (
+                i.name_lower,
+                i.camel_name,
+                i.name_lower,
+                i.ns_upper,
+                i.name_upper,
+                i.camel_name,
+                i.name_lower,
+            )
+        )
+        self.outfile.write(
+            "static void\n"
+            "%s_proxy_class_init (%sProxyClass *klass)\n"
+            "{\n"
+            "  GObjectClass *gobject_class;\n"
+            "  GDBusProxyClass *proxy_class;\n"
+            "\n"
+            "  gobject_class = G_OBJECT_CLASS (klass);\n"
+            "  gobject_class->finalize     = %s_proxy_finalize;\n"
+            "  gobject_class->get_property = %s_proxy_get_property;\n"
+            "  gobject_class->set_property = %s_proxy_set_property;\n"
+            "\n"
+            "  proxy_class = G_DBUS_PROXY_CLASS (klass);\n"
+            "  proxy_class->g_signal = %s_proxy_g_signal;\n"
+            "  proxy_class->g_properties_changed = %s_proxy_g_properties_changed;\n"
+            "\n"
+            % (
+                i.name_lower,
+                i.camel_name,
+                i.name_lower,
+                i.name_lower,
+                i.name_lower,
+                i.name_lower,
+                i.name_lower,
+            )
+        )
         if len(i.properties) > 0:
-            self.outfile.write('  %s_override_properties (gobject_class, 1);\n\n'%(i.name_lower))
-        self.outfile.write('#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_38\n'
-                           '  g_type_class_add_private (klass, sizeof (%sProxyPrivate));\n'
-                           '#endif\n'%(i.camel_name))
-        self.outfile.write('}\n'
-                           '\n')
-
-        self.outfile.write('static void\n'
-                           '%s_proxy_iface_init (%sIface *iface)\n'
-                           '{\n'%(i.name_lower, i.camel_name))
+            self.outfile.write(
+                "  %s_override_properties (gobject_class, 1);\n\n" % (i.name_lower)
+            )
+        self.outfile.write(
+            "#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_38\n"
+            "  g_type_class_add_private (klass, sizeof (%sProxyPrivate));\n"
+            "#endif\n" % (i.camel_name)
+        )
+        self.outfile.write("}\n" "\n")
+
+        self.outfile.write(
+            "static void\n"
+            "%s_proxy_iface_init (%sIface *iface)\n"
+            "{\n" % (i.name_lower, i.camel_name)
+        )
         for p in i.properties:
-            self.outfile.write('  iface->get_%s = %s_proxy_get_%s;\n'%(p.name_lower, i.name_lower, p.name_lower))
-        self.outfile.write('}\n'
-                           '\n')
+            self.outfile.write(
+                "  iface->get_%s = %s_proxy_get_%s;\n"
+                % (p.name_lower, i.name_lower, p.name_lower)
+            )
+        self.outfile.write("}\n" "\n")
 
         # constructors
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * %s_proxy_new:\n'
-                ' * @connection: A #GDBusConnection.\n'
-                ' * @flags: Flags from the #GDBusProxyFlags enumeration.\n'
-                ' * @name: (nullable): A bus name (well-known or unique) or %%NULL if @connection is not a message bus connection.\n'
-                ' * @object_path: An object path.\n'
-                ' * @cancellable: (nullable): A #GCancellable or %%NULL.\n'
-                ' * @callback: A #GAsyncReadyCallback to call when the request is satisfied.\n'
-                ' * @user_data: User data to pass to @callback.\n'
-                ' *\n'
-                ' * Asynchronously creates a proxy for the D-Bus interface #%s. See g_dbus_proxy_new() for more details.\n'
-                ' *\n'
-                ' * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from (see g_main_context_push_thread_default()).\n'
-                ' * You can then call %s_proxy_new_finish() to get the result of the operation.\n'
-                ' *\n'
-                ' * See %s_proxy_new_sync() for the synchronous, blocking version of this constructor.\n'
-                %(i.name_lower, i.name, i.name_lower, i.name_lower), False))
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %s_proxy_new:\n"
+                " * @connection: A #GDBusConnection.\n"
+                " * @flags: Flags from the #GDBusProxyFlags enumeration.\n"
+                " * @name: (nullable): A bus name (well-known or unique) or %%NULL if @connection is not a message bus connection.\n"
+                " * @object_path: An object path.\n"
+                " * @cancellable: (nullable): A #GCancellable or %%NULL.\n"
+                " * @callback: A #GAsyncReadyCallback to call when the request is satisfied.\n"
+                " * @user_data: User data to pass to @callback.\n"
+                " *\n"
+                " * Asynchronously creates a proxy for the D-Bus interface #%s. See g_dbus_proxy_new() for more details.\n"
+                " *\n"
+                " * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from (see g_main_context_push_thread_default()).\n"
+                " * You can then call %s_proxy_new_finish() to get the result of the operation.\n"
+                " *\n"
+                " * See %s_proxy_new_sync() for the synchronous, blocking version of this constructor.\n"
+                % (i.name_lower, i.name, i.name_lower, i.name_lower),
+                False,
+            )
+        )
         self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0)
-        self.outfile.write('void\n'
-                           '%s_proxy_new (\n'
-                           '    GDBusConnection     *connection,\n'
-                           '    GDBusProxyFlags      flags,\n'
-                           '    const gchar         *name,\n'
-                           '    const gchar         *object_path,\n'
-                           '    GCancellable        *cancellable,\n'
-                           '    GAsyncReadyCallback  callback,\n'
-                           '    gpointer             user_data)\n'
-                           '{\n'
-                           '  g_async_initable_new_async (%sTYPE_%s_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "%s", NULL);\n'
-                           '}\n'
-                           '\n'
-                           %(i.name_lower, i.ns_upper, i.name_upper, i.name))
-        self.outfile.write('/**\n'
-                           ' * %s_proxy_new_finish:\n'
-                           ' * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %s_proxy_new().\n'
-                           ' * @error: Return location for error or %%NULL\n'
-                           ' *\n'
-                           ' * Finishes an operation started with %s_proxy_new().\n'
-                           ' *\n'
-                           ' * Returns: (transfer full) (type %sProxy): The constructed proxy object or %%NULL if @error is set.\n'
-                           %(i.name_lower, i.name_lower, i.name_lower, i.camel_name))
+        self.outfile.write(
+            "void\n"
+            "%s_proxy_new (\n"
+            "    GDBusConnection     *connection,\n"
+            "    GDBusProxyFlags      flags,\n"
+            "    const gchar         *name,\n"
+            "    const gchar         *object_path,\n"
+            "    GCancellable        *cancellable,\n"
+            "    GAsyncReadyCallback  callback,\n"
+            "    gpointer             user_data)\n"
+            "{\n"
+            '  g_async_initable_new_async (%sTYPE_%s_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "%s", NULL);\n'
+            "}\n"
+            "\n" % (i.name_lower, i.ns_upper, i.name_upper, i.name)
+        )
+        self.outfile.write(
+            "/**\n"
+            " * %s_proxy_new_finish:\n"
+            " * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %s_proxy_new().\n"
+            " * @error: Return location for error or %%NULL\n"
+            " *\n"
+            " * Finishes an operation started with %s_proxy_new().\n"
+            " *\n"
+            " * Returns: (transfer full) (type %sProxy): The constructed proxy object or %%NULL if @error is set.\n"
+            % (i.name_lower, i.name_lower, i.name_lower, i.camel_name)
+        )
         self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0)
-        self.outfile.write('%s *\n'
-                           '%s_proxy_new_finish (\n'
-                           '    GAsyncResult        *res,\n'
-                           '    GError             **error)\n'
-                           '{\n'
-                           '  GObject *ret;\n'
-                           '  GObject *source_object;\n'
-                           '  source_object = g_async_result_get_source_object (res);\n'
-                           '  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);\n'
-                           '  g_object_unref (source_object);\n'
-                           '  if (ret != NULL)\n'
-                           '    return %s%s (ret);\n'
-                           '  else\n'
-                           '    return NULL;\n'
-                           '}\n'
-                           '\n'
-                           %(i.camel_name, i.name_lower, i.ns_upper, i.name_upper))
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * %s_proxy_new_sync:\n'
-                ' * @connection: A #GDBusConnection.\n'
-                ' * @flags: Flags from the #GDBusProxyFlags enumeration.\n'
-                ' * @name: (nullable): A bus name (well-known or unique) or %%NULL if @connection is not a message bus connection.\n'
-                ' * @object_path: An object path.\n'
-                ' * @cancellable: (nullable): A #GCancellable or %%NULL.\n'
-                ' * @error: Return location for error or %%NULL\n'
-                ' *\n'
-                ' * Synchronously creates a proxy for the D-Bus interface #%s. See g_dbus_proxy_new_sync() for more details.\n'
-                ' *\n'
-                ' * The calling thread is blocked until a reply is received.\n'
-                ' *\n'
-                ' * See %s_proxy_new() for the asynchronous version of this constructor.\n'
-                ' *\n'
-                ' * Returns: (transfer full) (type %sProxy): The constructed proxy object or %%NULL if @error is set.\n'
-                %(i.name_lower, i.name, i.name_lower, i.camel_name), False))
+        self.outfile.write(
+            "%s *\n"
+            "%s_proxy_new_finish (\n"
+            "    GAsyncResult        *res,\n"
+            "    GError             **error)\n"
+            "{\n"
+            "  GObject *ret;\n"
+            "  GObject *source_object;\n"
+            "  source_object = g_async_result_get_source_object (res);\n"
+            "  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);\n"
+            "  g_object_unref (source_object);\n"
+            "  if (ret != NULL)\n"
+            "    return %s%s (ret);\n"
+            "  else\n"
+            "    return NULL;\n"
+            "}\n"
+            "\n" % (i.camel_name, i.name_lower, i.ns_upper, i.name_upper)
+        )
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %s_proxy_new_sync:\n"
+                " * @connection: A #GDBusConnection.\n"
+                " * @flags: Flags from the #GDBusProxyFlags enumeration.\n"
+                " * @name: (nullable): A bus name (well-known or unique) or %%NULL if @connection is not a message bus connection.\n"
+                " * @object_path: An object path.\n"
+                " * @cancellable: (nullable): A #GCancellable or %%NULL.\n"
+                " * @error: Return location for error or %%NULL\n"
+                " *\n"
+                " * Synchronously creates a proxy for the D-Bus interface #%s. See g_dbus_proxy_new_sync() for more details.\n"
+                " *\n"
+                " * The calling thread is blocked until a reply is received.\n"
+                " *\n"
+                " * See %s_proxy_new() for the asynchronous version of this constructor.\n"
+                " *\n"
+                " * Returns: (transfer full) (type %sProxy): The constructed proxy object or %%NULL if @error is set.\n"
+                % (i.name_lower, i.name, i.name_lower, i.camel_name),
+                False,
+            )
+        )
         self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0)
-        self.outfile.write('%s *\n'
-                           '%s_proxy_new_sync (\n'
-                           '    GDBusConnection     *connection,\n'
-                           '    GDBusProxyFlags      flags,\n'
-                           '    const gchar         *name,\n'
-                           '    const gchar         *object_path,\n'
-                           '    GCancellable        *cancellable,\n'
-                           '    GError             **error)\n'
-                           '{\n'
-                           '  GInitable *ret;\n'
-                           '  ret = g_initable_new (%sTYPE_%s_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "%s", NULL);\n'
-                           '  if (ret != NULL)\n'
-                           '    return %s%s (ret);\n'
-                           '  else\n'
-                           '    return NULL;\n'
-                           '}\n'
-                           '\n'
-                           %(i.camel_name, i.name_lower, i.ns_upper, i.name_upper, i.name, i.ns_upper, i.name_upper))
-        self.outfile.write('\n')
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * %s_proxy_new_for_bus:\n'
-                ' * @bus_type: A #GBusType.\n'
-                ' * @flags: Flags from the #GDBusProxyFlags enumeration.\n'
-                ' * @name: A bus name (well-known or unique).\n'
-                ' * @object_path: An object path.\n'
-                ' * @cancellable: (nullable): A #GCancellable or %%NULL.\n'
-                ' * @callback: A #GAsyncReadyCallback to call when the request is satisfied.\n'
-                ' * @user_data: User data to pass to @callback.\n'
-                ' *\n'
-                ' * Like %s_proxy_new() but takes a #GBusType instead of a #GDBusConnection.\n'
-                ' *\n'
-                ' * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from (see g_main_context_push_thread_default()).\n'
-                ' * You can then call %s_proxy_new_for_bus_finish() to get the result of the operation.\n'
-                ' *\n'
-                ' * See %s_proxy_new_for_bus_sync() for the synchronous, blocking version of this constructor.\n'
-                %(i.name_lower, i.name_lower, i.name_lower, i.name_lower), False))
+        self.outfile.write(
+            "%s *\n"
+            "%s_proxy_new_sync (\n"
+            "    GDBusConnection     *connection,\n"
+            "    GDBusProxyFlags      flags,\n"
+            "    const gchar         *name,\n"
+            "    const gchar         *object_path,\n"
+            "    GCancellable        *cancellable,\n"
+            "    GError             **error)\n"
+            "{\n"
+            "  GInitable *ret;\n"
+            '  ret = g_initable_new (%sTYPE_%s_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "%s", NULL);\n'
+            "  if (ret != NULL)\n"
+            "    return %s%s (ret);\n"
+            "  else\n"
+            "    return NULL;\n"
+            "}\n"
+            "\n"
+            % (
+                i.camel_name,
+                i.name_lower,
+                i.ns_upper,
+                i.name_upper,
+                i.name,
+                i.ns_upper,
+                i.name_upper,
+            )
+        )
+        self.outfile.write("\n")
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %s_proxy_new_for_bus:\n"
+                " * @bus_type: A #GBusType.\n"
+                " * @flags: Flags from the #GDBusProxyFlags enumeration.\n"
+                " * @name: A bus name (well-known or unique).\n"
+                " * @object_path: An object path.\n"
+                " * @cancellable: (nullable): A #GCancellable or %%NULL.\n"
+                " * @callback: A #GAsyncReadyCallback to call when the request is satisfied.\n"
+                " * @user_data: User data to pass to @callback.\n"
+                " *\n"
+                " * Like %s_proxy_new() but takes a #GBusType instead of a #GDBusConnection.\n"
+                " *\n"
+                " * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from (see g_main_context_push_thread_default()).\n"
+                " * You can then call %s_proxy_new_for_bus_finish() to get the result of the operation.\n"
+                " *\n"
+                " * See %s_proxy_new_for_bus_sync() for the synchronous, blocking version of this constructor.\n"
+                % (i.name_lower, i.name_lower, i.name_lower, i.name_lower),
+                False,
+            )
+        )
         self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0)
-        self.outfile.write('void\n'
-                           '%s_proxy_new_for_bus (\n'
-                           '    GBusType             bus_type,\n'
-                           '    GDBusProxyFlags      flags,\n'
-                           '    const gchar         *name,\n'
-                           '    const gchar         *object_path,\n'
-                           '    GCancellable        *cancellable,\n'
-                           '    GAsyncReadyCallback  callback,\n'
-                           '    gpointer             user_data)\n'
-                           '{\n'
-                           '  g_async_initable_new_async (%sTYPE_%s_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "%s", NULL);\n'
-                           '}\n'
-                           '\n'
-                           %(i.name_lower, i.ns_upper, i.name_upper, i.name))
-        self.outfile.write('/**\n'
-                           ' * %s_proxy_new_for_bus_finish:\n'
-                           ' * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %s_proxy_new_for_bus().\n'
-                           ' * @error: Return location for error or %%NULL\n'
-                           ' *\n'
-                           ' * Finishes an operation started with %s_proxy_new_for_bus().\n'
-                           ' *\n'
-                           ' * Returns: (transfer full) (type %sProxy): The constructed proxy object or %%NULL if @error is set.\n'
-                           %(i.name_lower, i.name_lower, i.name_lower, i.camel_name))
+        self.outfile.write(
+            "void\n"
+            "%s_proxy_new_for_bus (\n"
+            "    GBusType             bus_type,\n"
+            "    GDBusProxyFlags      flags,\n"
+            "    const gchar         *name,\n"
+            "    const gchar         *object_path,\n"
+            "    GCancellable        *cancellable,\n"
+            "    GAsyncReadyCallback  callback,\n"
+            "    gpointer             user_data)\n"
+            "{\n"
+            '  g_async_initable_new_async (%sTYPE_%s_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "%s", NULL);\n'
+            "}\n"
+            "\n" % (i.name_lower, i.ns_upper, i.name_upper, i.name)
+        )
+        self.outfile.write(
+            "/**\n"
+            " * %s_proxy_new_for_bus_finish:\n"
+            " * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %s_proxy_new_for_bus().\n"
+            " * @error: Return location for error or %%NULL\n"
+            " *\n"
+            " * Finishes an operation started with %s_proxy_new_for_bus().\n"
+            " *\n"
+            " * Returns: (transfer full) (type %sProxy): The constructed proxy object or %%NULL if @error is set.\n"
+            % (i.name_lower, i.name_lower, i.name_lower, i.camel_name)
+        )
         self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0)
-        self.outfile.write('%s *\n'
-                           '%s_proxy_new_for_bus_finish (\n'
-                           '    GAsyncResult        *res,\n'
-                           '    GError             **error)\n'
-                           '{\n'
-                           '  GObject *ret;\n'
-                           '  GObject *source_object;\n'
-                           '  source_object = g_async_result_get_source_object (res);\n'
-                           '  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);\n'
-                           '  g_object_unref (source_object);\n'
-                           '  if (ret != NULL)\n'
-                           '    return %s%s (ret);\n'
-                           '  else\n'
-                           '    return NULL;\n'
-                           '}\n'
-                           '\n'
-                           %(i.camel_name, i.name_lower, i.ns_upper, i.name_upper))
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * %s_proxy_new_for_bus_sync:\n'
-                ' * @bus_type: A #GBusType.\n'
-                ' * @flags: Flags from the #GDBusProxyFlags enumeration.\n'
-                ' * @name: A bus name (well-known or unique).\n'
-                ' * @object_path: An object path.\n'
-                ' * @cancellable: (nullable): A #GCancellable or %%NULL.\n'
-                ' * @error: Return location for error or %%NULL\n'
-                ' *\n'
-                ' * Like %s_proxy_new_sync() but takes a #GBusType instead of a #GDBusConnection.\n'
-                ' *\n'
-                ' * The calling thread is blocked until a reply is received.\n'
-                ' *\n'
-                ' * See %s_proxy_new_for_bus() for the asynchronous version of this constructor.\n'
-                ' *\n'
-                ' * Returns: (transfer full) (type %sProxy): The constructed proxy object or %%NULL if @error is set.\n'
-                %(i.name_lower, i.name_lower, i.name_lower, i.camel_name), False))
+        self.outfile.write(
+            "%s *\n"
+            "%s_proxy_new_for_bus_finish (\n"
+            "    GAsyncResult        *res,\n"
+            "    GError             **error)\n"
+            "{\n"
+            "  GObject *ret;\n"
+            "  GObject *source_object;\n"
+            "  source_object = g_async_result_get_source_object (res);\n"
+            "  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);\n"
+            "  g_object_unref (source_object);\n"
+            "  if (ret != NULL)\n"
+            "    return %s%s (ret);\n"
+            "  else\n"
+            "    return NULL;\n"
+            "}\n"
+            "\n" % (i.camel_name, i.name_lower, i.ns_upper, i.name_upper)
+        )
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %s_proxy_new_for_bus_sync:\n"
+                " * @bus_type: A #GBusType.\n"
+                " * @flags: Flags from the #GDBusProxyFlags enumeration.\n"
+                " * @name: A bus name (well-known or unique).\n"
+                " * @object_path: An object path.\n"
+                " * @cancellable: (nullable): A #GCancellable or %%NULL.\n"
+                " * @error: Return location for error or %%NULL\n"
+                " *\n"
+                " * Like %s_proxy_new_sync() but takes a #GBusType instead of a #GDBusConnection.\n"
+                " *\n"
+                " * The calling thread is blocked until a reply is received.\n"
+                " *\n"
+                " * See %s_proxy_new_for_bus() for the asynchronous version of this constructor.\n"
+                " *\n"
+                " * Returns: (transfer full) (type %sProxy): The constructed proxy object or %%NULL if @error is set.\n"
+                % (i.name_lower, i.name_lower, i.name_lower, i.camel_name),
+                False,
+            )
+        )
         self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0)
-        self.outfile.write('%s *\n'
-                           '%s_proxy_new_for_bus_sync (\n'
-                           '    GBusType             bus_type,\n'
-                           '    GDBusProxyFlags      flags,\n'
-                           '    const gchar         *name,\n'
-                           '    const gchar         *object_path,\n'
-                           '    GCancellable        *cancellable,\n'
-                           '    GError             **error)\n'
-                           '{\n'
-                           '  GInitable *ret;\n'
-                           '  ret = g_initable_new (%sTYPE_%s_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "%s", NULL);\n'
-                           '  if (ret != NULL)\n'
-                           '    return %s%s (ret);\n'
-                           '  else\n'
-                           '    return NULL;\n'
-                           '}\n'
-                           '\n'
-                           %(i.camel_name, i.name_lower, i.ns_upper, i.name_upper, i.name, i.ns_upper, i.name_upper))
-        self.outfile.write('\n')
+        self.outfile.write(
+            "%s *\n"
+            "%s_proxy_new_for_bus_sync (\n"
+            "    GBusType             bus_type,\n"
+            "    GDBusProxyFlags      flags,\n"
+            "    const gchar         *name,\n"
+            "    const gchar         *object_path,\n"
+            "    GCancellable        *cancellable,\n"
+            "    GError             **error)\n"
+            "{\n"
+            "  GInitable *ret;\n"
+            '  ret = g_initable_new (%sTYPE_%s_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "%s", NULL);\n'
+            "  if (ret != NULL)\n"
+            "    return %s%s (ret);\n"
+            "  else\n"
+            "    return NULL;\n"
+            "}\n"
+            "\n"
+            % (
+                i.camel_name,
+                i.name_lower,
+                i.ns_upper,
+                i.name_upper,
+                i.name,
+                i.ns_upper,
+                i.name_upper,
+            )
+        )
+        self.outfile.write("\n")
 
     # ---------------------------------------------------------------------------------------------------
 
     def generate_skeleton(self, i):
         # class boilerplate
-        self.outfile.write('/* ------------------------------------------------------------------------ */\n'
-                           '\n')
-
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * %sSkeleton:\n'
-                ' *\n'
-                ' * The #%sSkeleton structure contains only private data and should only be accessed using the provided API.\n'
-                %(i.camel_name, i.camel_name), False))
+        self.outfile.write(
+            "/* ------------------------------------------------------------------------ */\n"
+            "\n"
+        )
+
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %sSkeleton:\n"
+                " *\n"
+                " * The #%sSkeleton structure contains only private data and should only be accessed using the provided API.\n"
+                % (i.camel_name, i.camel_name),
+                False,
+            )
+        )
         self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0)
-        self.outfile.write('\n')
-
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * %sSkeletonClass:\n'
-                ' * @parent_class: The parent class.\n'
-                ' *\n'
-                ' * Class structure for #%sSkeleton.\n'
-                %(i.camel_name, i.camel_name), False))
+        self.outfile.write("\n")
+
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %sSkeletonClass:\n"
+                " * @parent_class: The parent class.\n"
+                " *\n"
+                " * Class structure for #%sSkeleton.\n" % (i.camel_name, i.camel_name),
+                False,
+            )
+        )
         self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0)
-        self.outfile.write('\n')
-
-        self.outfile.write('struct _%sSkeletonPrivate\n'
-                           '{\n'
-                           '  GValue *properties;\n'
-                           '  GList *changed_properties;\n'
-                           '  GSource *changed_properties_idle_source;\n'
-                           '  GMainContext *context;\n'
-                           '  GMutex lock;\n'
-                           '};\n'
-                           '\n'%i.camel_name)
-
-        self.outfile.write('static void\n'
-                           '_%s_skeleton_handle_method_call (\n'
-                           '  GDBusConnection *connection G_GNUC_UNUSED,\n'
-                           '  const gchar *sender G_GNUC_UNUSED,\n'
-                           '  const gchar *object_path G_GNUC_UNUSED,\n'
-                           '  const gchar *interface_name,\n'
-                           '  const gchar *method_name,\n'
-                           '  GVariant *parameters,\n'
-                           '  GDBusMethodInvocation *invocation,\n'
-                           '  gpointer user_data)\n'
-                           '{\n'
-                           '  %sSkeleton *skeleton = %s%s_SKELETON (user_data);\n'
-                           '  _ExtendedGDBusMethodInfo *info;\n'
-                           '  GVariantIter iter;\n'
-                           '  GVariant *child;\n'
-                           '  GValue *paramv;\n'
-                           '  gsize num_params;\n'
-                           '  guint num_extra;\n'
-                           '  gsize n;\n'
-                           '  guint signal_id;\n'
-                           '  GValue return_value = G_VALUE_INIT;\n'
-                           %(i.name_lower, i.camel_name, i.ns_upper, i.name_upper))
-        self.outfile.write('  info = (_ExtendedGDBusMethodInfo *) g_dbus_method_invocation_get_method_info (invocation);\n'
-                           '  g_assert (info != NULL);\n'
-                           %())
-        self.outfile.write('  num_params = g_variant_n_children (parameters);\n'
-                           '  num_extra = info->pass_fdlist ? 3 : 2;'
-                           '  paramv = g_new0 (GValue, num_params + num_extra);\n'
-                           '  n = 0;\n'
-                           '  g_value_init (&paramv[n], %sTYPE_%s);\n'
-                           '  g_value_set_object (&paramv[n++], skeleton);\n'
-                           '  g_value_init (&paramv[n], G_TYPE_DBUS_METHOD_INVOCATION);\n'
-                           '  g_value_set_object (&paramv[n++], invocation);\n'
-                           '  if (info->pass_fdlist)\n'
-                           '    {\n'
-                           '#ifdef G_OS_UNIX\n'
-                           '      g_value_init (&paramv[n], G_TYPE_UNIX_FD_LIST);\n'
-                           '      g_value_set_object (&paramv[n++], g_dbus_message_get_unix_fd_list (g_dbus_method_invocation_get_message (invocation)));\n'
-                           '#else\n'
-                           '      g_assert_not_reached ();\n'
-                           '#endif\n'
-                           '    }\n'
-                           %(i.ns_upper, i.name_upper))
-        self.outfile.write('  g_variant_iter_init (&iter, parameters);\n'
-                           '  while ((child = g_variant_iter_next_value (&iter)) != NULL)\n'
-                           '    {\n'
-                           '      _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.in_args[n - num_extra];\n'
-                           '      if (arg_info->use_gvariant)\n'
-                           '        {\n'
-                           '          g_value_init (&paramv[n], G_TYPE_VARIANT);\n'
-                           '          g_value_set_variant (&paramv[n], child);\n'
-                           '          n++;\n'
-                           '        }\n'
-                           '      else\n'
-                           '        g_dbus_gvariant_to_gvalue (child, &paramv[n++]);\n'
-                           '      g_variant_unref (child);\n'
-                           '    }\n')
-        self.outfile.write('  signal_id = g_signal_lookup (info->signal_name, %sTYPE_%s);\n'
-                           %(i.ns_upper, i.name_upper))
-        self.outfile.write('  g_value_init (&return_value, G_TYPE_BOOLEAN);\n'
-                           '  g_signal_emitv (paramv, signal_id, 0, &return_value);\n'
-                           '  if (!g_value_get_boolean (&return_value))\n'
-                           '    g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD, "Method %s is not implemented on interface %s", method_name, interface_name);\n'
-                           '  g_value_unset (&return_value);\n')
-        self.outfile.write('  for (n = 0; n < num_params + num_extra; n++)\n'
-                           '    g_value_unset (&paramv[n]);\n'
-                           '  g_free (paramv);\n')
-        self.outfile.write('}\n'
-                           '\n')
-
-        self.outfile.write('static GVariant *\n'
-                           '_%s_skeleton_handle_get_property (\n'
-                           '  GDBusConnection *connection G_GNUC_UNUSED,\n'
-                           '  const gchar *sender G_GNUC_UNUSED,\n'
-                           '  const gchar *object_path G_GNUC_UNUSED,\n'
-                           '  const gchar *interface_name G_GNUC_UNUSED,\n'
-                           '  const gchar *property_name,\n'
-                           '  GError **error,\n'
-                           '  gpointer user_data)\n'
-                           '{\n'
-                           '  %sSkeleton *skeleton = %s%s_SKELETON (user_data);\n'
-                           '  GValue value = G_VALUE_INIT;\n'
-                           '  GParamSpec *pspec;\n'
-                           '  _ExtendedGDBusPropertyInfo *info;\n'
-                           '  GVariant *ret;\n'
-                           %(i.name_lower, i.camel_name, i.ns_upper, i.name_upper))
-        self.outfile.write('  ret = NULL;\n'
-                           '  info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_%s_interface_info.parent_struct, property_name);\n'
-                           '  g_assert (info != NULL);\n'
-                           '  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name);\n'
-                           '  if (pspec == NULL)\n'
-                           '    {\n'
-                           '      g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %%s", property_name);\n'
-                           '    }\n'
-                           '  else\n'
-                           '    {\n'
-                           '      g_value_init (&value, pspec->value_type);\n'
-                           '      g_object_get_property (G_OBJECT (skeleton), info->hyphen_name, &value);\n'
-                           '      ret = g_dbus_gvalue_to_gvariant (&value, G_VARIANT_TYPE (info->parent_struct.signature));\n'
-                           '      g_value_unset (&value);\n'
-                           '    }\n'
-                           '  return ret;\n'
-                           '}\n'
-                           '\n'
-                           %(i.name_lower))
-
-        self.outfile.write('static gboolean\n'
-                           '_%s_skeleton_handle_set_property (\n'
-                           '  GDBusConnection *connection G_GNUC_UNUSED,\n'
-                           '  const gchar *sender G_GNUC_UNUSED,\n'
-                           '  const gchar *object_path G_GNUC_UNUSED,\n'
-                           '  const gchar *interface_name G_GNUC_UNUSED,\n'
-                           '  const gchar *property_name,\n'
-                           '  GVariant *variant,\n'
-                           '  GError **error,\n'
-                           '  gpointer user_data)\n'
-                           '{\n'
-                           '  %sSkeleton *skeleton = %s%s_SKELETON (user_data);\n'
-                           '  GValue value = G_VALUE_INIT;\n'
-                           '  GParamSpec *pspec;\n'
-                           '  _ExtendedGDBusPropertyInfo *info;\n'
-                           '  gboolean ret;\n'
-                           %(i.name_lower, i.camel_name, i.ns_upper, i.name_upper))
-        self.outfile.write('  ret = FALSE;\n'
-                           '  info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_%s_interface_info.parent_struct, property_name);\n'
-                           '  g_assert (info != NULL);\n'
-                           '  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name);\n'
-                           '  if (pspec == NULL)\n'
-                           '    {\n'
-                           '      g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %%s", property_name);\n'
-                           '    }\n'
-                           '  else\n'
-                           '    {\n'
-                           '      if (info->use_gvariant)\n'
-                           '        g_value_set_variant (&value, variant);\n'
-                           '      else\n'
-                           '        g_dbus_gvariant_to_gvalue (variant, &value);\n'
-                           '      g_object_set_property (G_OBJECT (skeleton), info->hyphen_name, &value);\n'
-                           '      g_value_unset (&value);\n'
-                           '      ret = TRUE;\n'
-                           '    }\n'
-                           '  return ret;\n'
-                           '}\n'
-                           '\n'
-                           %(i.name_lower))
-
-
-        self.outfile.write('static const GDBusInterfaceVTable _%s_skeleton_vtable =\n'
-                           '{\n'
-                           '  _%s_skeleton_handle_method_call,\n'
-                           '  _%s_skeleton_handle_get_property,\n'
-                           '  _%s_skeleton_handle_set_property,\n'
-                           '  {NULL}\n'
-                           '};\n'
-                           '\n'%(i.name_lower, i.name_lower, i.name_lower, i.name_lower))
-
-        self.outfile.write('static GDBusInterfaceInfo *\n'
-                           '%s_skeleton_dbus_interface_get_info (GDBusInterfaceSkeleton *skeleton G_GNUC_UNUSED)\n'
-                           '{\n'
-                           '  return %s_interface_info ();\n'
-                           %(i.name_lower, i.name_lower))
-        self.outfile.write('}\n'
-                           '\n')
-
-        self.outfile.write('static GDBusInterfaceVTable *\n'
-                           '%s_skeleton_dbus_interface_get_vtable (GDBusInterfaceSkeleton *skeleton G_GNUC_UNUSED)\n'
-                           '{\n'
-                           '  return (GDBusInterfaceVTable *) &_%s_skeleton_vtable;\n'
-                           %(i.name_lower, i.name_lower))
-        self.outfile.write('}\n'
-                           '\n')
-
-        self.outfile.write('static GVariant *\n'
-                           '%s_skeleton_dbus_interface_get_properties (GDBusInterfaceSkeleton *_skeleton)\n'
-                           '{\n'
-                           '  %sSkeleton *skeleton = %s%s_SKELETON (_skeleton);\n'
-                           %(i.name_lower, i.camel_name, i.ns_upper, i.name_upper))
-        self.outfile.write('\n'
-                           '  GVariantBuilder builder;\n'
-                           '  guint n;\n'
-                           '  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));\n'
-                           '  if (_%s_interface_info.parent_struct.properties == NULL)\n'
-                           '    goto out;\n'
-                           '  for (n = 0; _%s_interface_info.parent_struct.properties[n] != NULL; n++)\n'
-                           '    {\n'
-                           '      GDBusPropertyInfo *info = _%s_interface_info.parent_struct.properties[n];\n'
-                           '      if (info->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE)\n'
-                           '        {\n'
-                           '          GVariant *value;\n'
-                           '          value = _%s_skeleton_handle_get_property (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)), NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)), "%s", info->name, NULL, skeleton);\n'
-                           '          if (value != NULL)\n'
-                           '            {\n'
-                           '              g_variant_take_ref (value);\n'
-                           '              g_variant_builder_add (&builder, "{sv}", info->name, value);\n'
-                           '              g_variant_unref (value);\n'
-                           '            }\n'
-                           '        }\n'
-                           '    }\n'
-                           'out:\n'
-                           '  return g_variant_builder_end (&builder);\n'
-                           '}\n'
-                           '\n'
-                           %(i.name_lower, i.name_lower, i.name_lower, i.name_lower, i.name))
+        self.outfile.write("\n")
+
+        self.outfile.write(
+            "struct _%sSkeletonPrivate\n"
+            "{\n"
+            "  GValue *properties;\n"
+            "  GList *changed_properties;\n"
+            "  GSource *changed_properties_idle_source;\n"
+            "  GMainContext *context;\n"
+            "  GMutex lock;\n"
+            "};\n"
+            "\n" % i.camel_name
+        )
+
+        self.outfile.write(
+            "static void\n"
+            "_%s_skeleton_handle_method_call (\n"
+            "  GDBusConnection *connection G_GNUC_UNUSED,\n"
+            "  const gchar *sender G_GNUC_UNUSED,\n"
+            "  const gchar *object_path G_GNUC_UNUSED,\n"
+            "  const gchar *interface_name,\n"
+            "  const gchar *method_name,\n"
+            "  GVariant *parameters,\n"
+            "  GDBusMethodInvocation *invocation,\n"
+            "  gpointer user_data)\n"
+            "{\n"
+            "  %sSkeleton *skeleton = %s%s_SKELETON (user_data);\n"
+            "  _ExtendedGDBusMethodInfo *info;\n"
+            "  GVariantIter iter;\n"
+            "  GVariant *child;\n"
+            "  GValue *paramv;\n"
+            "  gsize num_params;\n"
+            "  guint num_extra;\n"
+            "  gsize n;\n"
+            "  guint signal_id;\n"
+            "  GValue return_value = G_VALUE_INIT;\n"
+            % (i.name_lower, i.camel_name, i.ns_upper, i.name_upper)
+        )
+        self.outfile.write(
+            "  info = (_ExtendedGDBusMethodInfo *) g_dbus_method_invocation_get_method_info (invocation);\n"
+            "  g_assert (info != NULL);\n"
+        )
+        self.outfile.write(
+            "  num_params = g_variant_n_children (parameters);\n"
+            "  num_extra = info->pass_fdlist ? 3 : 2;"
+            "  paramv = g_new0 (GValue, num_params + num_extra);\n"
+            "  n = 0;\n"
+            "  g_value_init (&paramv[n], %sTYPE_%s);\n"
+            "  g_value_set_object (&paramv[n++], skeleton);\n"
+            "  g_value_init (&paramv[n], G_TYPE_DBUS_METHOD_INVOCATION);\n"
+            "  g_value_set_object (&paramv[n++], invocation);\n"
+            "  if (info->pass_fdlist)\n"
+            "    {\n"
+            "#ifdef G_OS_UNIX\n"
+            "      g_value_init (&paramv[n], G_TYPE_UNIX_FD_LIST);\n"
+            "      g_value_set_object (&paramv[n++], g_dbus_message_get_unix_fd_list (g_dbus_method_invocation_get_message (invocation)));\n"
+            "#else\n"
+            "      g_assert_not_reached ();\n"
+            "#endif\n"
+            "    }\n" % (i.ns_upper, i.name_upper)
+        )
+        self.outfile.write(
+            "  g_variant_iter_init (&iter, parameters);\n"
+            "  while ((child = g_variant_iter_next_value (&iter)) != NULL)\n"
+            "    {\n"
+            "      _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.in_args[n - num_extra];\n"
+            "      if (arg_info->use_gvariant)\n"
+            "        {\n"
+            "          g_value_init (&paramv[n], G_TYPE_VARIANT);\n"
+            "          g_value_set_variant (&paramv[n], child);\n"
+            "          n++;\n"
+            "        }\n"
+            "      else\n"
+            "        g_dbus_gvariant_to_gvalue (child, &paramv[n++]);\n"
+            "      g_variant_unref (child);\n"
+            "    }\n"
+        )
+        self.outfile.write(
+            "  signal_id = g_signal_lookup (info->signal_name, %sTYPE_%s);\n"
+            % (i.ns_upper, i.name_upper)
+        )
+        self.outfile.write(
+            "  g_value_init (&return_value, G_TYPE_BOOLEAN);\n"
+            "  g_signal_emitv (paramv, signal_id, 0, &return_value);\n"
+            "  if (!g_value_get_boolean (&return_value))\n"
+            '    g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD, "Method %s is not implemented on interface %s", method_name, interface_name);\n'
+            "  g_value_unset (&return_value);\n"
+        )
+        self.outfile.write(
+            "  for (n = 0; n < num_params + num_extra; n++)\n"
+            "    g_value_unset (&paramv[n]);\n"
+            "  g_free (paramv);\n"
+        )
+        self.outfile.write("}\n" "\n")
+
+        self.outfile.write(
+            "static GVariant *\n"
+            "_%s_skeleton_handle_get_property (\n"
+            "  GDBusConnection *connection G_GNUC_UNUSED,\n"
+            "  const gchar *sender G_GNUC_UNUSED,\n"
+            "  const gchar *object_path G_GNUC_UNUSED,\n"
+            "  const gchar *interface_name G_GNUC_UNUSED,\n"
+            "  const gchar *property_name,\n"
+            "  GError **error,\n"
+            "  gpointer user_data)\n"
+            "{\n"
+            "  %sSkeleton *skeleton = %s%s_SKELETON (user_data);\n"
+            "  GValue value = G_VALUE_INIT;\n"
+            "  GParamSpec *pspec;\n"
+            "  _ExtendedGDBusPropertyInfo *info;\n"
+            "  GVariant *ret;\n"
+            % (i.name_lower, i.camel_name, i.ns_upper, i.name_upper)
+        )
+        self.outfile.write(
+            "  ret = NULL;\n"
+            "  info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_%s_interface_info.parent_struct, property_name);\n"
+            "  g_assert (info != NULL);\n"
+            "  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name);\n"
+            "  if (pspec == NULL)\n"
+            "    {\n"
+            '      g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %%s", property_name);\n'
+            "    }\n"
+            "  else\n"
+            "    {\n"
+            "      g_value_init (&value, pspec->value_type);\n"
+            "      g_object_get_property (G_OBJECT (skeleton), info->hyphen_name, &value);\n"
+            "      ret = g_dbus_gvalue_to_gvariant (&value, G_VARIANT_TYPE (info->parent_struct.signature));\n"
+            "      g_value_unset (&value);\n"
+            "    }\n"
+            "  return ret;\n"
+            "}\n"
+            "\n" % (i.name_lower)
+        )
+
+        self.outfile.write(
+            "static gboolean\n"
+            "_%s_skeleton_handle_set_property (\n"
+            "  GDBusConnection *connection G_GNUC_UNUSED,\n"
+            "  const gchar *sender G_GNUC_UNUSED,\n"
+            "  const gchar *object_path G_GNUC_UNUSED,\n"
+            "  const gchar *interface_name G_GNUC_UNUSED,\n"
+            "  const gchar *property_name,\n"
+            "  GVariant *variant,\n"
+            "  GError **error,\n"
+            "  gpointer user_data)\n"
+            "{\n"
+            "  %sSkeleton *skeleton = %s%s_SKELETON (user_data);\n"
+            "  GValue value = G_VALUE_INIT;\n"
+            "  GParamSpec *pspec;\n"
+            "  _ExtendedGDBusPropertyInfo *info;\n"
+            "  gboolean ret;\n" % (i.name_lower, i.camel_name, i.ns_upper, i.name_upper)
+        )
+        self.outfile.write(
+            "  ret = FALSE;\n"
+            "  info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_%s_interface_info.parent_struct, property_name);\n"
+            "  g_assert (info != NULL);\n"
+            "  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name);\n"
+            "  if (pspec == NULL)\n"
+            "    {\n"
+            '      g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %%s", property_name);\n'
+            "    }\n"
+            "  else\n"
+            "    {\n"
+            "      if (info->use_gvariant)\n"
+            "        g_value_set_variant (&value, variant);\n"
+            "      else\n"
+            "        g_dbus_gvariant_to_gvalue (variant, &value);\n"
+            "      g_object_set_property (G_OBJECT (skeleton), info->hyphen_name, &value);\n"
+            "      g_value_unset (&value);\n"
+            "      ret = TRUE;\n"
+            "    }\n"
+            "  return ret;\n"
+            "}\n"
+            "\n" % (i.name_lower)
+        )
+
+        self.outfile.write(
+            "static const GDBusInterfaceVTable _%s_skeleton_vtable =\n"
+            "{\n"
+            "  _%s_skeleton_handle_method_call,\n"
+            "  _%s_skeleton_handle_get_property,\n"
+            "  _%s_skeleton_handle_set_property,\n"
+            "  {NULL}\n"
+            "};\n"
+            "\n" % (i.name_lower, i.name_lower, i.name_lower, i.name_lower)
+        )
+
+        self.outfile.write(
+            "static GDBusInterfaceInfo *\n"
+            "%s_skeleton_dbus_interface_get_info (GDBusInterfaceSkeleton *skeleton G_GNUC_UNUSED)\n"
+            "{\n"
+            "  return %s_interface_info ();\n" % (i.name_lower, i.name_lower)
+        )
+        self.outfile.write("}\n" "\n")
+
+        self.outfile.write(
+            "static GDBusInterfaceVTable *\n"
+            "%s_skeleton_dbus_interface_get_vtable (GDBusInterfaceSkeleton *skeleton G_GNUC_UNUSED)\n"
+            "{\n"
+            "  return (GDBusInterfaceVTable *) &_%s_skeleton_vtable;\n"
+            % (i.name_lower, i.name_lower)
+        )
+        self.outfile.write("}\n" "\n")
+
+        self.outfile.write(
+            "static GVariant *\n"
+            "%s_skeleton_dbus_interface_get_properties (GDBusInterfaceSkeleton *_skeleton)\n"
+            "{\n"
+            "  %sSkeleton *skeleton = %s%s_SKELETON (_skeleton);\n"
+            % (i.name_lower, i.camel_name, i.ns_upper, i.name_upper)
+        )
+        self.outfile.write(
+            "\n"
+            "  GVariantBuilder builder;\n"
+            "  guint n;\n"
+            '  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));\n'
+            "  if (_%s_interface_info.parent_struct.properties == NULL)\n"
+            "    goto out;\n"
+            "  for (n = 0; _%s_interface_info.parent_struct.properties[n] != NULL; n++)\n"
+            "    {\n"
+            "      GDBusPropertyInfo *info = _%s_interface_info.parent_struct.properties[n];\n"
+            "      if (info->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE)\n"
+            "        {\n"
+            "          GVariant *value;\n"
+            '          value = _%s_skeleton_handle_get_property (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)), NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)), "%s", info->name, NULL, skeleton);\n'
+            "          if (value != NULL)\n"
+            "            {\n"
+            "              g_variant_take_ref (value);\n"
+            '              g_variant_builder_add (&builder, "{sv}", info->name, value);\n'
+            "              g_variant_unref (value);\n"
+            "            }\n"
+            "        }\n"
+            "    }\n"
+            "out:\n"
+            "  return g_variant_builder_end (&builder);\n"
+            "}\n"
+            "\n" % (i.name_lower, i.name_lower, i.name_lower, i.name_lower, i.name)
+        )
 
         if len(i.properties) > 0:
-            self.outfile.write('static gboolean _%s_emit_changed (gpointer user_data);\n'
-                               '\n'
-                               %(i.name_lower))
-
-        self.outfile.write('static void\n'
-                           '%s_skeleton_dbus_interface_flush (GDBusInterfaceSkeleton *_skeleton)\n'
-                           '{\n'
-                           %(i.name_lower))
+            self.outfile.write(
+                "static gboolean _%s_emit_changed (gpointer user_data);\n"
+                "\n" % (i.name_lower)
+            )
+
+        self.outfile.write(
+            "static void\n"
+            "%s_skeleton_dbus_interface_flush (GDBusInterfaceSkeleton *_skeleton)\n"
+            "{\n" % (i.name_lower)
+        )
         if len(i.properties) > 0:
-            self.outfile.write('  %sSkeleton *skeleton = %s%s_SKELETON (_skeleton);\n'
-                               '  gboolean emit_changed = FALSE;\n'
-                               '\n'
-                               '  g_mutex_lock (&skeleton->priv->lock);\n'
-                               '  if (skeleton->priv->changed_properties_idle_source != NULL)\n'
-                               '    {\n'
-                               '      g_source_destroy (skeleton->priv->changed_properties_idle_source);\n'
-                               '      skeleton->priv->changed_properties_idle_source = NULL;\n'
-                               '      emit_changed = TRUE;\n'
-                               '    }\n'
-                               '  g_mutex_unlock (&skeleton->priv->lock);\n'
-                               '\n'
-                               '  if (emit_changed)\n'
-                               '    _%s_emit_changed (skeleton);\n'
-                               %(i.camel_name, i.ns_upper, i.name_upper, i.name_lower))
-        self.outfile.write('}\n'
-                           '\n')
+            self.outfile.write(
+                "  %sSkeleton *skeleton = %s%s_SKELETON (_skeleton);\n"
+                "  gboolean emit_changed = FALSE;\n"
+                "\n"
+                "  g_mutex_lock (&skeleton->priv->lock);\n"
+                "  if (skeleton->priv->changed_properties_idle_source != NULL)\n"
+                "    {\n"
+                "      g_source_destroy (skeleton->priv->changed_properties_idle_source);\n"
+                "      skeleton->priv->changed_properties_idle_source = NULL;\n"
+                "      emit_changed = TRUE;\n"
+                "    }\n"
+                "  g_mutex_unlock (&skeleton->priv->lock);\n"
+                "\n"
+                "  if (emit_changed)\n"
+                "    _%s_emit_changed (skeleton);\n"
+                % (i.camel_name, i.ns_upper, i.name_upper, i.name_lower)
+            )
+        self.outfile.write("}\n" "\n")
 
         for s in i.signals:
-            self.outfile.write('static void\n'
-                               '_%s_on_signal_%s (\n'
-                               '    %s *object'%(i.name_lower, s.name_lower, i.camel_name))
+            self.outfile.write(
+                "static void\n"
+                "_%s_on_signal_%s (\n"
+                "    %s *object" % (i.name_lower, s.name_lower, i.camel_name)
+            )
             for a in s.args:
-                self.outfile.write(',\n    %sarg_%s'%(a.ctype_in, a.name))
-            self.outfile.write(')\n'
-                               '{\n'
-                               '  %sSkeleton *skeleton = %s%s_SKELETON (object);\n\n'
-                               '  GList      *connections, *l;\n'
-                               '  GVariant   *signal_variant;\n'
-                               '  connections = g_dbus_interface_skeleton_get_connections (G_DBUS_INTERFACE_SKELETON (skeleton));\n'
-                               %(i.camel_name, i.ns_upper, i.name_upper))
-            self.outfile.write('\n'
-                               '  signal_variant = g_variant_ref_sink (g_variant_new ("(')
+                self.outfile.write(",\n    %sarg_%s" % (a.ctype_in, a.name))
+            self.outfile.write(
+                ")\n"
+                "{\n"
+                "  %sSkeleton *skeleton = %s%s_SKELETON (object);\n\n"
+                "  GList      *connections, *l;\n"
+                "  GVariant   *signal_variant;\n"
+                "  connections = g_dbus_interface_skeleton_get_connections (G_DBUS_INTERFACE_SKELETON (skeleton));\n"
+                % (i.camel_name, i.ns_upper, i.name_upper)
+            )
+            self.outfile.write(
+                "\n" '  signal_variant = g_variant_ref_sink (g_variant_new ("('
+            )
             for a in s.args:
-                self.outfile.write('%s'%(a.format_in))
+                self.outfile.write("%s" % (a.format_in))
             self.outfile.write(')"')
             for a in s.args:
-                self.outfile.write(',\n                   arg_%s'%(a.name))
-            self.outfile.write('));\n')
-
-            self.outfile.write('  for (l = connections; l != NULL; l = l->next)\n'
-                               '    {\n'
-                               '      GDBusConnection *connection = l->data;\n'
-                               '      g_dbus_connection_emit_signal (connection,\n'
-                               '        NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)), "%s", "%s",\n'
-                               '        signal_variant, NULL);\n'
-                               '    }\n'
-                               %(i.name, s.name))
-            self.outfile.write('  g_variant_unref (signal_variant);\n')
-            self.outfile.write('  g_list_free_full (connections, g_object_unref);\n')
-            self.outfile.write('}\n'
-                               '\n')
-
-        self.outfile.write('static void %s_skeleton_iface_init (%sIface *iface);\n'
-                           %(i.name_lower, i.camel_name))
-
-        self.outfile.write('#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38\n')
-        self.outfile.write('G_DEFINE_TYPE_WITH_CODE (%sSkeleton, %s_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON,\n'%(i.camel_name, i.name_lower))
-        self.outfile.write('                         G_ADD_PRIVATE (%sSkeleton)\n'%(i.camel_name))
-        self.outfile.write('                         G_IMPLEMENT_INTERFACE (%sTYPE_%s, %s_skeleton_iface_init))\n\n'%(i.ns_upper, i.name_upper, i.name_lower))
-        self.outfile.write('#else\n')
-        self.outfile.write('G_DEFINE_TYPE_WITH_CODE (%sSkeleton, %s_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON,\n'%(i.camel_name, i.name_lower))
-        self.outfile.write('                         G_IMPLEMENT_INTERFACE (%sTYPE_%s, %s_skeleton_iface_init))\n\n'%(i.ns_upper, i.name_upper, i.name_lower))
-        self.outfile.write('#endif\n')
+                self.outfile.write(",\n                   arg_%s" % (a.name))
+            self.outfile.write("));\n")
+
+            self.outfile.write(
+                "  for (l = connections; l != NULL; l = l->next)\n"
+                "    {\n"
+                "      GDBusConnection *connection = l->data;\n"
+                "      g_dbus_connection_emit_signal (connection,\n"
+                '        NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)), "%s", "%s",\n'
+                "        signal_variant, NULL);\n"
+                "    }\n" % (i.name, s.name)
+            )
+            self.outfile.write("  g_variant_unref (signal_variant);\n")
+            self.outfile.write("  g_list_free_full (connections, g_object_unref);\n")
+            self.outfile.write("}\n" "\n")
+
+        self.outfile.write(
+            "static void %s_skeleton_iface_init (%sIface *iface);\n"
+            % (i.name_lower, i.camel_name)
+        )
+
+        self.outfile.write("#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38\n")
+        self.outfile.write(
+            "G_DEFINE_TYPE_WITH_CODE (%sSkeleton, %s_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON,\n"
+            % (i.camel_name, i.name_lower)
+        )
+        self.outfile.write(
+            "                         G_ADD_PRIVATE (%sSkeleton)\n" % (i.camel_name)
+        )
+        self.outfile.write(
+            "                         G_IMPLEMENT_INTERFACE (%sTYPE_%s, %s_skeleton_iface_init))\n\n"
+            % (i.ns_upper, i.name_upper, i.name_lower)
+        )
+        self.outfile.write("#else\n")
+        self.outfile.write(
+            "G_DEFINE_TYPE_WITH_CODE (%sSkeleton, %s_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON,\n"
+            % (i.camel_name, i.name_lower)
+        )
+        self.outfile.write(
+            "                         G_IMPLEMENT_INTERFACE (%sTYPE_%s, %s_skeleton_iface_init))\n\n"
+            % (i.ns_upper, i.name_upper, i.name_lower)
+        )
+        self.outfile.write("#endif\n")
 
         # finalize
-        self.outfile.write('static void\n'
-                           '%s_skeleton_finalize (GObject *object)\n'
-                           '{\n'%(i.name_lower))
-        self.outfile.write('  %sSkeleton *skeleton = %s%s_SKELETON (object);\n'%(i.camel_name, i.ns_upper, i.name_upper))
+        self.outfile.write(
+            "static void\n"
+            "%s_skeleton_finalize (GObject *object)\n"
+            "{\n" % (i.name_lower)
+        )
+        self.outfile.write(
+            "  %sSkeleton *skeleton = %s%s_SKELETON (object);\n"
+            % (i.camel_name, i.ns_upper, i.name_upper)
+        )
         if len(i.properties) > 0:
-            self.outfile.write('  guint n;\n'
-                               '  for (n = 0; n < %d; n++)\n'
-                               '    g_value_unset (&skeleton->priv->properties[n]);\n'%(len(i.properties)))
-            self.outfile.write('  g_free (skeleton->priv->properties);\n')
-        self.outfile.write('  g_list_free_full (skeleton->priv->changed_properties, (GDestroyNotify) _changed_property_free);\n')
-        self.outfile.write('  if (skeleton->priv->changed_properties_idle_source != NULL)\n')
-        self.outfile.write('    g_source_destroy (skeleton->priv->changed_properties_idle_source);\n')
-        self.outfile.write('  g_main_context_unref (skeleton->priv->context);\n')
-        self.outfile.write('  g_mutex_clear (&skeleton->priv->lock);\n')
-        self.outfile.write('  G_OBJECT_CLASS (%s_skeleton_parent_class)->finalize (object);\n'
-                           '}\n'
-                           '\n'%(i.name_lower))
+            self.outfile.write(
+                "  guint n;\n"
+                "  for (n = 0; n < %d; n++)\n"
+                "    g_value_unset (&skeleton->priv->properties[n]);\n"
+                % (len(i.properties))
+            )
+            self.outfile.write("  g_free (skeleton->priv->properties);\n")
+        self.outfile.write(
+            "  g_list_free_full (skeleton->priv->changed_properties, (GDestroyNotify) _changed_property_free);\n"
+        )
+        self.outfile.write(
+            "  if (skeleton->priv->changed_properties_idle_source != NULL)\n"
+        )
+        self.outfile.write(
+            "    g_source_destroy (skeleton->priv->changed_properties_idle_source);\n"
+        )
+        self.outfile.write("  g_main_context_unref (skeleton->priv->context);\n")
+        self.outfile.write("  g_mutex_clear (&skeleton->priv->lock);\n")
+        self.outfile.write(
+            "  G_OBJECT_CLASS (%s_skeleton_parent_class)->finalize (object);\n"
+            "}\n"
+            "\n" % (i.name_lower)
+        )
 
         # property accessors (TODO: generate PropertiesChanged signals in setter)
         if len(i.properties) > 0:
-            self.outfile.write('static void\n'
-                               '%s_skeleton_get_property (GObject      *object,\n'
-                               '  guint         prop_id,\n'
-                            '  GValue       *value,\n'
-                            '  GParamSpec   *pspec G_GNUC_UNUSED)\n'
-                            '{\n'%(i.name_lower))
-            self.outfile.write('  %sSkeleton *skeleton = %s%s_SKELETON (object);\n'
-                               '  g_assert (prop_id != 0 && prop_id - 1 < %d);\n'
-                               '  g_mutex_lock (&skeleton->priv->lock);\n'
-                               '  g_value_copy (&skeleton->priv->properties[prop_id - 1], value);\n'
-                               '  g_mutex_unlock (&skeleton->priv->lock);\n'
-                               %(i.camel_name, i.ns_upper, i.name_upper, len(i.properties)))
-            self.outfile.write('}\n'
-                               '\n')
+            self.outfile.write(
+                "static void\n"
+                "%s_skeleton_get_property (GObject      *object,\n"
+                "  guint         prop_id,\n"
+                "  GValue       *value,\n"
+                "  GParamSpec   *pspec G_GNUC_UNUSED)\n"
+                "{\n" % (i.name_lower)
+            )
+            self.outfile.write(
+                "  %sSkeleton *skeleton = %s%s_SKELETON (object);\n"
+                "  g_assert (prop_id != 0 && prop_id - 1 < %d);\n"
+                "  g_mutex_lock (&skeleton->priv->lock);\n"
+                "  g_value_copy (&skeleton->priv->properties[prop_id - 1], value);\n"
+                "  g_mutex_unlock (&skeleton->priv->lock);\n"
+                % (i.camel_name, i.ns_upper, i.name_upper, len(i.properties))
+            )
+            self.outfile.write("}\n" "\n")
 
             # if property is already scheduled then re-use entry.. though it could be
             # that the user did
@@ -2895,992 +3911,1281 @@ class CodeGenerator:
             # change event. If the latest value is not different from the original
             # one, we can simply ignore the ChangedProperty
             #
-            self.outfile.write('static gboolean\n'
-                               '_%s_emit_changed (gpointer user_data)\n'
-                               '{\n'
-                               '  %sSkeleton *skeleton = %s%s_SKELETON (user_data);\n'
-                               %(i.name_lower, i.camel_name, i.ns_upper, i.name_upper))
-            self.outfile.write('  GList *l;\n'
-                               '  GVariantBuilder builder;\n'
-                               '  GVariantBuilder invalidated_builder;\n'
-                               '  guint num_changes;\n'
-                               '\n'
-                               '  g_mutex_lock (&skeleton->priv->lock);\n'
-                               '  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));\n'
-                               '  g_variant_builder_init (&invalidated_builder, G_VARIANT_TYPE ("as"));\n'
-                               '  for (l = skeleton->priv->changed_properties, num_changes = 0; l != NULL; l = l->next)\n'
-                               '    {\n'
-                               '      ChangedProperty *cp = l->data;\n'
-                               '      GVariant *variant;\n'
-                               '      const GValue *cur_value;\n'
-                               '\n'
-                               '      cur_value = &skeleton->priv->properties[cp->prop_id - 1];\n'
-                               '      if (!_g_value_equal (cur_value, &cp->orig_value))\n'
-                               '        {\n'
-                               '          variant = g_dbus_gvalue_to_gvariant (cur_value, G_VARIANT_TYPE (cp->info->parent_struct.signature));\n'
-                               '          g_variant_builder_add (&builder, "{sv}", cp->info->parent_struct.name, variant);\n'
-                               '          g_variant_unref (variant);\n'
-                               '          num_changes++;\n'
-                               '        }\n'
-                               '    }\n'
-                               '  if (num_changes > 0)\n'
-                               '    {\n'
-                               '      GList *connections, *ll;\n'
-                               '      GVariant *signal_variant;'
-                               '\n'
-                               '      signal_variant = g_variant_ref_sink (g_variant_new ("(sa{sv}as)", "%s",\n'
-                               '                                           &builder, &invalidated_builder));\n'
-                               '      connections = g_dbus_interface_skeleton_get_connections (G_DBUS_INTERFACE_SKELETON (skeleton));\n'
-                               '      for (ll = connections; ll != NULL; ll = ll->next)\n'
-                               '        {\n'
-                               '          GDBusConnection *connection = ll->data;\n'
-                               '\n'
-                               '          g_dbus_connection_emit_signal (connection,\n'
-                               '                                         NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)),\n'
-                               '                                         "org.freedesktop.DBus.Properties",\n'
-                               '                                         "PropertiesChanged",\n'
-                               '                                         signal_variant,\n'
-                               '                                         NULL);\n'
-                               '        }\n'
-                               '      g_variant_unref (signal_variant);\n'
-                               '      g_list_free_full (connections, g_object_unref);\n'
-                               '    }\n'
-                               '  else\n'
-                               '    {\n'
-                               '      g_variant_builder_clear (&builder);\n'
-                               '      g_variant_builder_clear (&invalidated_builder);\n'
-                               '    }\n'
-                               %(i.name))
-            self.outfile.write('  g_list_free_full (skeleton->priv->changed_properties, (GDestroyNotify) _changed_property_free);\n')
-            self.outfile.write('  skeleton->priv->changed_properties = NULL;\n')
-            self.outfile.write('  skeleton->priv->changed_properties_idle_source = NULL;\n')
-            self.outfile.write('  g_mutex_unlock (&skeleton->priv->lock);\n')
-            self.outfile.write('  return FALSE;\n'
-                               '}\n'
-                               '\n')
+            self.outfile.write(
+                "static gboolean\n"
+                "_%s_emit_changed (gpointer user_data)\n"
+                "{\n"
+                "  %sSkeleton *skeleton = %s%s_SKELETON (user_data);\n"
+                % (i.name_lower, i.camel_name, i.ns_upper, i.name_upper)
+            )
+            self.outfile.write(
+                "  GList *l;\n"
+                "  GVariantBuilder builder;\n"
+                "  GVariantBuilder invalidated_builder;\n"
+                "  guint num_changes;\n"
+                "\n"
+                "  g_mutex_lock (&skeleton->priv->lock);\n"
+                '  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));\n'
+                '  g_variant_builder_init (&invalidated_builder, G_VARIANT_TYPE ("as"));\n'
+                "  for (l = skeleton->priv->changed_properties, num_changes = 0; l != NULL; l = l->next)\n"
+                "    {\n"
+                "      ChangedProperty *cp = l->data;\n"
+                "      GVariant *variant;\n"
+                "      const GValue *cur_value;\n"
+                "\n"
+                "      cur_value = &skeleton->priv->properties[cp->prop_id - 1];\n"
+                "      if (!_g_value_equal (cur_value, &cp->orig_value))\n"
+                "        {\n"
+                "          variant = g_dbus_gvalue_to_gvariant (cur_value, G_VARIANT_TYPE (cp->info->parent_struct.signature));\n"
+                '          g_variant_builder_add (&builder, "{sv}", cp->info->parent_struct.name, variant);\n'
+                "          g_variant_unref (variant);\n"
+                "          num_changes++;\n"
+                "        }\n"
+                "    }\n"
+                "  if (num_changes > 0)\n"
+                "    {\n"
+                "      GList *connections, *ll;\n"
+                "      GVariant *signal_variant;"
+                "\n"
+                '      signal_variant = g_variant_ref_sink (g_variant_new ("(sa{sv}as)", "%s",\n'
+                "                                           &builder, &invalidated_builder));\n"
+                "      connections = g_dbus_interface_skeleton_get_connections (G_DBUS_INTERFACE_SKELETON (skeleton));\n"
+                "      for (ll = connections; ll != NULL; ll = ll->next)\n"
+                "        {\n"
+                "          GDBusConnection *connection = ll->data;\n"
+                "\n"
+                "          g_dbus_connection_emit_signal (connection,\n"
+                "                                         NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)),\n"
+                '                                         "org.freedesktop.DBus.Properties",\n'
+                '                                         "PropertiesChanged",\n'
+                "                                         signal_variant,\n"
+                "                                         NULL);\n"
+                "        }\n"
+                "      g_variant_unref (signal_variant);\n"
+                "      g_list_free_full (connections, g_object_unref);\n"
+                "    }\n"
+                "  else\n"
+                "    {\n"
+                "      g_variant_builder_clear (&builder);\n"
+                "      g_variant_builder_clear (&invalidated_builder);\n"
+                "    }\n" % (i.name)
+            )
+            self.outfile.write(
+                "  g_list_free_full (skeleton->priv->changed_properties, (GDestroyNotify) _changed_property_free);\n"
+            )
+            self.outfile.write("  skeleton->priv->changed_properties = NULL;\n")
+            self.outfile.write(
+                "  skeleton->priv->changed_properties_idle_source = NULL;\n"
+            )
+            self.outfile.write("  g_mutex_unlock (&skeleton->priv->lock);\n")
+            self.outfile.write("  return FALSE;\n" "}\n" "\n")
             # holding lock while being called
-            self.outfile.write('static void\n'
-                               '_%s_schedule_emit_changed (%sSkeleton *skeleton, const _ExtendedGDBusPropertyInfo *info, guint prop_id, const GValue *orig_value)\n'
-                               '{\n'
-                               '  ChangedProperty *cp;\n'
-                               '  GList *l;\n'
-                               '  cp = NULL;\n'
-                               '  for (l = skeleton->priv->changed_properties; l != NULL; l = l->next)\n'
-                               '    {\n'
-                               '      ChangedProperty *i_cp = l->data;\n'
-                               '      if (i_cp->info == info)\n'
-                               '        {\n'
-                               '          cp = i_cp;\n'
-                               '          break;\n'
-                               '        }\n'
-                               '    }\n'
-                               %(i.name_lower, i.camel_name))
-            self.outfile.write('  if (cp == NULL)\n'
-                               '    {\n'
-                               '      cp = g_new0 (ChangedProperty, 1);\n'
-                               '      cp->prop_id = prop_id;\n'
-                               '      cp->info = info;\n'
-                               '      skeleton->priv->changed_properties = g_list_prepend (skeleton->priv->changed_properties, cp);\n'
-                               '      g_value_init (&cp->orig_value, G_VALUE_TYPE (orig_value));\n'
-                               '      g_value_copy (orig_value, &cp->orig_value);\n'
-                               '    }\n'
-                               '}\n'
-                               '\n'
-                               %())
+            self.outfile.write(
+                "static void\n"
+                "_%s_schedule_emit_changed (%sSkeleton *skeleton, const _ExtendedGDBusPropertyInfo *info, guint prop_id, const GValue *orig_value)\n"
+                "{\n"
+                "  ChangedProperty *cp;\n"
+                "  GList *l;\n"
+                "  cp = NULL;\n"
+                "  for (l = skeleton->priv->changed_properties; l != NULL; l = l->next)\n"
+                "    {\n"
+                "      ChangedProperty *i_cp = l->data;\n"
+                "      if (i_cp->info == info)\n"
+                "        {\n"
+                "          cp = i_cp;\n"
+                "          break;\n"
+                "        }\n"
+                "    }\n" % (i.name_lower, i.camel_name)
+            )
+            self.outfile.write(
+                "  if (cp == NULL)\n"
+                "    {\n"
+                "      cp = g_new0 (ChangedProperty, 1);\n"
+                "      cp->prop_id = prop_id;\n"
+                "      cp->info = info;\n"
+                "      skeleton->priv->changed_properties = g_list_prepend (skeleton->priv->changed_properties, cp);\n"
+                "      g_value_init (&cp->orig_value, G_VALUE_TYPE (orig_value));\n"
+                "      g_value_copy (orig_value, &cp->orig_value);\n"
+                "    }\n"
+                "}\n"
+                "\n"
+            )
 
             # Postpone setting up the refresh source until the ::notify signal is emitted as
             # this allows use of g_object_freeze_notify()/g_object_thaw_notify() ...
             # This is useful when updating several properties from another thread than
             # where the idle will be emitted from
-            self.outfile.write('static void\n'
-                               '%s_skeleton_notify (GObject      *object,\n'
-                               '  GParamSpec *pspec G_GNUC_UNUSED)\n'
-                               '{\n'
-                               '  %sSkeleton *skeleton = %s%s_SKELETON (object);\n'
-                               '  g_mutex_lock (&skeleton->priv->lock);\n'
-                               '  if (skeleton->priv->changed_properties != NULL &&\n'
-                               '      skeleton->priv->changed_properties_idle_source == NULL)\n'
-                               '    {\n'
-                               '      skeleton->priv->changed_properties_idle_source = g_idle_source_new ();\n'
-                               '      g_source_set_priority (skeleton->priv->changed_properties_idle_source, G_PRIORITY_DEFAULT);\n'
-                               '      g_source_set_callback (skeleton->priv->changed_properties_idle_source, _%s_emit_changed, g_object_ref (skeleton), (GDestroyNotify) g_object_unref);\n'
-                               '      g_source_set_name (skeleton->priv->changed_properties_idle_source, "[generated] _%s_emit_changed");\n'
-                               '      g_source_attach (skeleton->priv->changed_properties_idle_source, skeleton->priv->context);\n'
-                               '      g_source_unref (skeleton->priv->changed_properties_idle_source);\n'
-                               '    }\n'
-                               '  g_mutex_unlock (&skeleton->priv->lock);\n'
-                               '}\n'
-                               '\n'
-                               %(i.name_lower, i.camel_name, i.ns_upper, i.name_upper, i.name_lower, i.name_lower))
-
-            self.outfile.write('static void\n'
-                               '%s_skeleton_set_property (GObject      *object,\n'
-                               '  guint         prop_id,\n'
-                               '  const GValue *value,\n'
-                               '  GParamSpec   *pspec)\n'
-                               '{\n'%(i.name_lower))
-            self.outfile.write('  const _ExtendedGDBusPropertyInfo *info;\n'
-                               '  %sSkeleton *skeleton = %s%s_SKELETON (object);\n'
-                               '  g_assert (prop_id != 0 && prop_id - 1 < %d);\n'
-                               '  info = (const _ExtendedGDBusPropertyInfo *) _%s_property_info_pointers[prop_id - 1];\n'
-                               '  g_mutex_lock (&skeleton->priv->lock);\n'
-                               '  g_object_freeze_notify (object);\n'
-                               '  if (!_g_value_equal (value, &skeleton->priv->properties[prop_id - 1]))\n'
-                               '    {\n'
-                               '      if (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)) != NULL &&\n'
-                               '          info->emits_changed_signal)\n'
-                               '        _%s_schedule_emit_changed (skeleton, info, prop_id, &skeleton->priv->properties[prop_id - 1]);\n'
-                               '      g_value_copy (value, &skeleton->priv->properties[prop_id - 1]);\n'
-                               '      g_object_notify_by_pspec (object, pspec);\n'
-                               '    }\n'
-                               '  g_mutex_unlock (&skeleton->priv->lock);\n'
-                               '  g_object_thaw_notify (object);\n'
-                               %(i.camel_name, i.ns_upper, i.name_upper, len(i.properties), i.name_lower, i.name_lower))
-            self.outfile.write('}\n'
-                               '\n')
-
-        self.outfile.write('static void\n'
-                           '%s_skeleton_init (%sSkeleton *skeleton)\n'
-                           '{\n'
-                           '#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38\n'
-                           '  skeleton->priv = %s_skeleton_get_instance_private (skeleton);\n'
-                           '#else\n'
-                           '  skeleton->priv = G_TYPE_INSTANCE_GET_PRIVATE (skeleton, %sTYPE_%s_SKELETON, %sSkeletonPrivate);\n'
-                           '#endif\n\n'
-                           %(i.name_lower, i.camel_name,
-                             i.name_lower,
-                             i.ns_upper, i.name_upper, i.camel_name))
-        self.outfile.write('  g_mutex_init (&skeleton->priv->lock);\n')
-        self.outfile.write('  skeleton->priv->context = g_main_context_ref_thread_default ();\n')
+            self.outfile.write(
+                "static void\n"
+                "%s_skeleton_notify (GObject      *object,\n"
+                "  GParamSpec *pspec G_GNUC_UNUSED)\n"
+                "{\n"
+                "  %sSkeleton *skeleton = %s%s_SKELETON (object);\n"
+                "  g_mutex_lock (&skeleton->priv->lock);\n"
+                "  if (skeleton->priv->changed_properties != NULL &&\n"
+                "      skeleton->priv->changed_properties_idle_source == NULL)\n"
+                "    {\n"
+                "      skeleton->priv->changed_properties_idle_source = g_idle_source_new ();\n"
+                "      g_source_set_priority (skeleton->priv->changed_properties_idle_source, G_PRIORITY_DEFAULT);\n"
+                "      g_source_set_callback (skeleton->priv->changed_properties_idle_source, _%s_emit_changed, g_object_ref (skeleton), (GDestroyNotify) g_object_unref);\n"
+                '      g_source_set_name (skeleton->priv->changed_properties_idle_source, "[generated] _%s_emit_changed");\n'
+                "      g_source_attach (skeleton->priv->changed_properties_idle_source, skeleton->priv->context);\n"
+                "      g_source_unref (skeleton->priv->changed_properties_idle_source);\n"
+                "    }\n"
+                "  g_mutex_unlock (&skeleton->priv->lock);\n"
+                "}\n"
+                "\n"
+                % (
+                    i.name_lower,
+                    i.camel_name,
+                    i.ns_upper,
+                    i.name_upper,
+                    i.name_lower,
+                    i.name_lower,
+                )
+            )
+
+            self.outfile.write(
+                "static void\n"
+                "%s_skeleton_set_property (GObject      *object,\n"
+                "  guint         prop_id,\n"
+                "  const GValue *value,\n"
+                "  GParamSpec   *pspec)\n"
+                "{\n" % (i.name_lower)
+            )
+            self.outfile.write(
+                "  const _ExtendedGDBusPropertyInfo *info;\n"
+                "  %sSkeleton *skeleton = %s%s_SKELETON (object);\n"
+                "  g_assert (prop_id != 0 && prop_id - 1 < %d);\n"
+                "  info = (const _ExtendedGDBusPropertyInfo *) _%s_property_info_pointers[prop_id - 1];\n"
+                "  g_mutex_lock (&skeleton->priv->lock);\n"
+                "  g_object_freeze_notify (object);\n"
+                "  if (!_g_value_equal (value, &skeleton->priv->properties[prop_id - 1]))\n"
+                "    {\n"
+                "      if (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)) != NULL &&\n"
+                "          info->emits_changed_signal)\n"
+                "        _%s_schedule_emit_changed (skeleton, info, prop_id, &skeleton->priv->properties[prop_id - 1]);\n"
+                "      g_value_copy (value, &skeleton->priv->properties[prop_id - 1]);\n"
+                "      g_object_notify_by_pspec (object, pspec);\n"
+                "    }\n"
+                "  g_mutex_unlock (&skeleton->priv->lock);\n"
+                "  g_object_thaw_notify (object);\n"
+                % (
+                    i.camel_name,
+                    i.ns_upper,
+                    i.name_upper,
+                    len(i.properties),
+                    i.name_lower,
+                    i.name_lower,
+                )
+            )
+            self.outfile.write("}\n" "\n")
+
+        self.outfile.write(
+            "static void\n"
+            "%s_skeleton_init (%sSkeleton *skeleton)\n"
+            "{\n"
+            "#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38\n"
+            "  skeleton->priv = %s_skeleton_get_instance_private (skeleton);\n"
+            "#else\n"
+            "  skeleton->priv = G_TYPE_INSTANCE_GET_PRIVATE (skeleton, %sTYPE_%s_SKELETON, %sSkeletonPrivate);\n"
+            "#endif\n\n"
+            % (
+                i.name_lower,
+                i.camel_name,
+                i.name_lower,
+                i.ns_upper,
+                i.name_upper,
+                i.camel_name,
+            )
+        )
+        self.outfile.write("  g_mutex_init (&skeleton->priv->lock);\n")
+        self.outfile.write(
+            "  skeleton->priv->context = g_main_context_ref_thread_default ();\n"
+        )
         if len(i.properties) > 0:
-            self.outfile.write('  skeleton->priv->properties = g_new0 (GValue, %d);\n'%(len(i.properties)))
+            self.outfile.write(
+                "  skeleton->priv->properties = g_new0 (GValue, %d);\n"
+                % (len(i.properties))
+            )
             n = 0
             for p in i.properties:
-                self.outfile.write('  g_value_init (&skeleton->priv->properties[%d], %s);\n'%(n, p.arg.gtype))
+                self.outfile.write(
+                    "  g_value_init (&skeleton->priv->properties[%d], %s);\n"
+                    % (n, p.arg.gtype)
+                )
                 n += 1
-        self.outfile.write('}\n'
-                           '\n')
+        self.outfile.write("}\n" "\n")
 
         # property vfuncs
         n = 0
         for p in i.properties:
-            self.outfile.write('static %s\n'
-                               '%s_skeleton_get_%s (%s *object)\n'
-                               '{\n'
-                               %(p.arg.ctype_in, i.name_lower, p.name_lower, i.camel_name))
-            self.outfile.write('  %sSkeleton *skeleton = %s%s_SKELETON (object);\n'%(i.camel_name, i.ns_upper, i.name_upper))
-            self.outfile.write('  %svalue;\n'
-                               '  g_mutex_lock (&skeleton->priv->lock);\n'
-                               '  value = %s (&(skeleton->priv->properties[%d]));\n'
-                               '  g_mutex_unlock (&skeleton->priv->lock);\n'
-                               %(p.arg.ctype_in_g, p.arg.gvalue_get, n))
-            self.outfile.write('  return value;\n')
-            self.outfile.write('}\n')
-            self.outfile.write('\n')
+            self.outfile.write(
+                "static %s\n"
+                "%s_skeleton_get_%s (%s *object)\n"
+                "{\n" % (p.arg.ctype_in, i.name_lower, p.name_lower, i.camel_name)
+            )
+            self.outfile.write(
+                "  %sSkeleton *skeleton = %s%s_SKELETON (object);\n"
+                % (i.camel_name, i.ns_upper, i.name_upper)
+            )
+            self.outfile.write(
+                "  %svalue;\n"
+                "  g_mutex_lock (&skeleton->priv->lock);\n"
+                "  value = %s (&(skeleton->priv->properties[%d]));\n"
+                "  g_mutex_unlock (&skeleton->priv->lock);\n"
+                % (p.arg.ctype_in_g, p.arg.gvalue_get, n)
+            )
+            self.outfile.write("  return value;\n")
+            self.outfile.write("}\n")
+            self.outfile.write("\n")
             n += 1
 
-        self.outfile.write('static void\n'
-                           '%s_skeleton_class_init (%sSkeletonClass *klass)\n'
-                           '{\n'
-                           '  GObjectClass *gobject_class;\n'
-                           '  GDBusInterfaceSkeletonClass *skeleton_class;\n'
-                           '\n'
-                           '  gobject_class = G_OBJECT_CLASS (klass);\n'
-                           '  gobject_class->finalize = %s_skeleton_finalize;\n'
-                           %(i.name_lower, i.camel_name, i.name_lower))
+        self.outfile.write(
+            "static void\n"
+            "%s_skeleton_class_init (%sSkeletonClass *klass)\n"
+            "{\n"
+            "  GObjectClass *gobject_class;\n"
+            "  GDBusInterfaceSkeletonClass *skeleton_class;\n"
+            "\n"
+            "  gobject_class = G_OBJECT_CLASS (klass);\n"
+            "  gobject_class->finalize = %s_skeleton_finalize;\n"
+            % (i.name_lower, i.camel_name, i.name_lower)
+        )
         if len(i.properties) > 0:
-            self.outfile.write('  gobject_class->get_property = %s_skeleton_get_property;\n'
-                               '  gobject_class->set_property = %s_skeleton_set_property;\n'
-                               '  gobject_class->notify       = %s_skeleton_notify;\n'
-                               '\n'%(i.name_lower, i.name_lower, i.name_lower))
-            self.outfile.write('\n'
-                               '  %s_override_properties (gobject_class, 1);\n'%(i.name_lower))
-        self.outfile.write('\n'
-                           '  skeleton_class = G_DBUS_INTERFACE_SKELETON_CLASS (klass);\n');
-        self.outfile.write('  skeleton_class->get_info = %s_skeleton_dbus_interface_get_info;\n'%(i.name_lower))
-        self.outfile.write('  skeleton_class->get_properties = %s_skeleton_dbus_interface_get_properties;\n'%(i.name_lower))
-        self.outfile.write('  skeleton_class->flush = %s_skeleton_dbus_interface_flush;\n'%(i.name_lower))
-        self.outfile.write('  skeleton_class->get_vtable = %s_skeleton_dbus_interface_get_vtable;\n'%(i.name_lower))
-
-        self.outfile.write('\n'
-                           '#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_38\n'
-                           '  g_type_class_add_private (klass, sizeof (%sSkeletonPrivate));\n'
-                           '#endif\n'%(i.camel_name))
-
-        self.outfile.write('}\n'
-                           '\n')
-
-        self.outfile.write('static void\n'
-                           '%s_skeleton_iface_init (%sIface *iface)\n'
-                           '{\n'
-                           %(i.name_lower, i.camel_name))
+            self.outfile.write(
+                "  gobject_class->get_property = %s_skeleton_get_property;\n"
+                "  gobject_class->set_property = %s_skeleton_set_property;\n"
+                "  gobject_class->notify       = %s_skeleton_notify;\n"
+                "\n" % (i.name_lower, i.name_lower, i.name_lower)
+            )
+            self.outfile.write(
+                "\n" "  %s_override_properties (gobject_class, 1);\n" % (i.name_lower)
+            )
+        self.outfile.write(
+            "\n" "  skeleton_class = G_DBUS_INTERFACE_SKELETON_CLASS (klass);\n"
+        )
+        self.outfile.write(
+            "  skeleton_class->get_info = %s_skeleton_dbus_interface_get_info;\n"
+            % (i.name_lower)
+        )
+        self.outfile.write(
+            "  skeleton_class->get_properties = %s_skeleton_dbus_interface_get_properties;\n"
+            % (i.name_lower)
+        )
+        self.outfile.write(
+            "  skeleton_class->flush = %s_skeleton_dbus_interface_flush;\n"
+            % (i.name_lower)
+        )
+        self.outfile.write(
+            "  skeleton_class->get_vtable = %s_skeleton_dbus_interface_get_vtable;\n"
+            % (i.name_lower)
+        )
+
+        self.outfile.write(
+            "\n"
+            "#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_38\n"
+            "  g_type_class_add_private (klass, sizeof (%sSkeletonPrivate));\n"
+            "#endif\n" % (i.camel_name)
+        )
+
+        self.outfile.write("}\n" "\n")
+
+        self.outfile.write(
+            "static void\n"
+            "%s_skeleton_iface_init (%sIface *iface)\n"
+            "{\n" % (i.name_lower, i.camel_name)
+        )
         for s in i.signals:
-            self.outfile.write('  iface->%s = _%s_on_signal_%s;\n'
-                               %(s.name_lower, i.name_lower, s.name_lower))
+            self.outfile.write(
+                "  iface->%s = _%s_on_signal_%s;\n"
+                % (s.name_lower, i.name_lower, s.name_lower)
+            )
         for p in i.properties:
-            self.outfile.write('  iface->get_%s = %s_skeleton_get_%s;\n'%(p.name_lower, i.name_lower, p.name_lower))
-        self.outfile.write('}\n'
-                           '\n')
+            self.outfile.write(
+                "  iface->get_%s = %s_skeleton_get_%s;\n"
+                % (p.name_lower, i.name_lower, p.name_lower)
+            )
+        self.outfile.write("}\n" "\n")
 
         # constructors
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * %s_skeleton_new:\n'
-                ' *\n'
-                ' * Creates a skeleton object for the D-Bus interface #%s.\n'
-                ' *\n'
-                ' * Returns: (transfer full) (type %sSkeleton): The skeleton object.\n'
-                %(i.name_lower, i.name, i.camel_name), False))
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %s_skeleton_new:\n"
+                " *\n"
+                " * Creates a skeleton object for the D-Bus interface #%s.\n"
+                " *\n"
+                " * Returns: (transfer full) (type %sSkeleton): The skeleton object.\n"
+                % (i.name_lower, i.name, i.camel_name),
+                False,
+            )
+        )
         self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0)
-        self.outfile.write('%s *\n'
-                           '%s_skeleton_new (void)\n'
-                           '{\n'
-                           '  return %s%s (g_object_new (%sTYPE_%s_SKELETON, NULL));\n'
-                           '}\n'
-                           '\n'%(i.camel_name, i.name_lower, i.ns_upper, i.name_upper, i.ns_upper, i.name_upper))
+        self.outfile.write(
+            "%s *\n"
+            "%s_skeleton_new (void)\n"
+            "{\n"
+            "  return %s%s (g_object_new (%sTYPE_%s_SKELETON, NULL));\n"
+            "}\n"
+            "\n"
+            % (
+                i.camel_name,
+                i.name_lower,
+                i.ns_upper,
+                i.name_upper,
+                i.ns_upper,
+                i.name_upper,
+            )
+        )
 
     # ---------------------------------------------------------------------------------------------------
 
     def generate_object(self):
-        self.outfile.write('/* ------------------------------------------------------------------------\n'
-                           ' * Code for Object, ObjectProxy and ObjectSkeleton\n'
-                           ' * ------------------------------------------------------------------------\n'
-                           ' */\n'
-                           '\n')
-
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * SECTION:%sObject\n'
-                ' * @title: %sObject\n'
-                ' * @short_description: Specialized GDBusObject types\n'
-                ' *\n'
-                ' * This section contains the #%sObject, #%sObjectProxy, and #%sObjectSkeleton types which make it easier to work with objects implementing generated types for D-Bus interfaces.\n'
-                ' */\n'
-                %(self.namespace, self.namespace, self.namespace, self.namespace, self.namespace), False))
-        self.outfile.write('\n')
-
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * %sObject:\n'
-                ' *\n'
-                ' * The #%sObject type is a specialized container of interfaces.\n'
-                ' */\n'
-                %(self.namespace, self.namespace), False))
-        self.outfile.write('\n')
-
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * %sObjectIface:\n'
-                ' * @parent_iface: The parent interface.\n'
-                ' *\n'
-                ' * Virtual table for the #%sObject interface.\n'
-                ' */\n'
-                %(self.namespace, self.namespace), False))
-        self.outfile.write('\n')
-
-        self.outfile.write('typedef %sObjectIface %sObjectInterface;\n'%(self.namespace, self.namespace))
-        self.outfile.write('G_DEFINE_INTERFACE_WITH_CODE (%sObject, %sobject, G_TYPE_OBJECT, g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_DBUS_OBJECT);)\n'%(self.namespace, self.ns_lower))
-        self.outfile.write('\n')
-        self.outfile.write('static void\n'
-                           '%sobject_default_init (%sObjectIface *iface)\n'
-                           '{\n'
-                           %(self.ns_lower, self.namespace));
+        self.outfile.write(
+            "/* ------------------------------------------------------------------------\n"
+            " * Code for Object, ObjectProxy and ObjectSkeleton\n"
+            " * ------------------------------------------------------------------------\n"
+            " */\n"
+            "\n"
+        )
+
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * SECTION:%sObject\n"
+                " * @title: %sObject\n"
+                " * @short_description: Specialized GDBusObject types\n"
+                " *\n"
+                " * This section contains the #%sObject, #%sObjectProxy, and #%sObjectSkeleton types which make it easier to work with objects implementing generated types for D-Bus interfaces.\n"
+                " */\n"
+                % (
+                    self.namespace,
+                    self.namespace,
+                    self.namespace,
+                    self.namespace,
+                    self.namespace,
+                ),
+                False,
+            )
+        )
+        self.outfile.write("\n")
+
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %sObject:\n"
+                " *\n"
+                " * The #%sObject type is a specialized container of interfaces.\n"
+                " */\n" % (self.namespace, self.namespace),
+                False,
+            )
+        )
+        self.outfile.write("\n")
+
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %sObjectIface:\n"
+                " * @parent_iface: The parent interface.\n"
+                " *\n"
+                " * Virtual table for the #%sObject interface.\n"
+                " */\n" % (self.namespace, self.namespace),
+                False,
+            )
+        )
+        self.outfile.write("\n")
+
+        self.outfile.write(
+            "typedef %sObjectIface %sObjectInterface;\n"
+            % (self.namespace, self.namespace)
+        )
+        self.outfile.write(
+            "G_DEFINE_INTERFACE_WITH_CODE (%sObject, %sobject, G_TYPE_OBJECT, g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_DBUS_OBJECT);)\n"
+            % (self.namespace, self.ns_lower)
+        )
+        self.outfile.write("\n")
+        self.outfile.write(
+            "static void\n"
+            "%sobject_default_init (%sObjectIface *iface)\n"
+            "{\n" % (self.ns_lower, self.namespace)
+        )
         for i in self.ifaces:
-            self.outfile.write(self.docbook_gen.expand(
-                    '  /**\n'
-                    '   * %sObject:%s:\n'
-                    '   *\n'
-                    '   * The #%s instance corresponding to the D-Bus interface #%s, if any.\n'
-                    '   *\n'
-                    '   * Connect to the #GObject::notify signal to get informed of property changes.\n'
-                    %(self.namespace, i.name_hyphen, i.camel_name, i.name), False))
+            self.outfile.write(
+                self.docbook_gen.expand(
+                    "  /**\n"
+                    "   * %sObject:%s:\n"
+                    "   *\n"
+                    "   * The #%s instance corresponding to the D-Bus interface #%s, if any.\n"
+                    "   *\n"
+                    "   * Connect to the #GObject::notify signal to get informed of property changes.\n"
+                    % (self.namespace, i.name_hyphen, i.camel_name, i.name),
+                    False,
+                )
+            )
             self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 2)
-            flags = 'G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS'
+            flags = "G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS"
             if i.deprecated:
-                flags = 'G_PARAM_DEPRECATED | ' + flags
-            self.outfile.write('  g_object_interface_install_property (iface, g_param_spec_object ("%s", "%s", "%s", %sTYPE_%s, %s));\n'
-                               '\n'
-                               %(i.name_hyphen, i.name_hyphen, i.name_hyphen, self.ns_upper, i.name_upper, flags))
-        self.outfile.write('}\n'
-                           '\n')
+                flags = "G_PARAM_DEPRECATED | " + flags
+            self.outfile.write(
+                '  g_object_interface_install_property (iface, g_param_spec_object ("%s", "%s", "%s", %sTYPE_%s, %s));\n'
+                "\n"
+                % (
+                    i.name_hyphen,
+                    i.name_hyphen,
+                    i.name_hyphen,
+                    self.ns_upper,
+                    i.name_upper,
+                    flags,
+                )
+            )
+        self.outfile.write("}\n" "\n")
 
         for i in self.ifaces:
-            self.outfile.write(self.docbook_gen.expand(
-                    '/**\n'
-                    ' * %sobject_get_%s:\n'
-                    ' * @object: A #%sObject.\n'
-                    ' *\n'
-                    ' * Gets the #%s instance for the D-Bus interface #%s on @object, if any.\n'
-                    ' *\n'
-                    ' * Returns: (transfer full) (nullable): A #%s that must be freed with g_object_unref() or %%NULL if @object does not implement the interface.\n'
-                    %(self.ns_lower, i.name_upper.lower(), self.namespace, i.camel_name, i.name, i.camel_name), False))
+            self.outfile.write(
+                self.docbook_gen.expand(
+                    "/**\n"
+                    " * %sobject_get_%s:\n"
+                    " * @object: A #%sObject.\n"
+                    " *\n"
+                    " * Gets the #%s instance for the D-Bus interface #%s on @object, if any.\n"
+                    " *\n"
+                    " * Returns: (transfer full) (nullable): A #%s that must be freed with g_object_unref() or %%NULL if @object does not implement the interface.\n"
+                    % (
+                        self.ns_lower,
+                        i.name_upper.lower(),
+                        self.namespace,
+                        i.camel_name,
+                        i.name,
+                        i.camel_name,
+                    ),
+                    False,
+                )
+            )
             self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0)
-            self.outfile.write('%s *%sobject_get_%s (%sObject *object)\n'
-                               %(i.camel_name, self.ns_lower, i.name_upper.lower(), self.namespace))
-            self.outfile.write('{\n'
-                               '  GDBusInterface *ret;\n'
-                               '  ret = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "%s");\n'
-                               '  if (ret == NULL)\n'
-                               '    return NULL;\n'
-                               '  return %s%s (ret);\n'
-                               '}\n'
-                               '\n'
-                               %(i.name, self.ns_upper, i.name_upper))
-        self.outfile.write('\n')
+            self.outfile.write(
+                "%s *%sobject_get_%s (%sObject *object)\n"
+                % (i.camel_name, self.ns_lower, i.name_upper.lower(), self.namespace)
+            )
+            self.outfile.write(
+                "{\n"
+                "  GDBusInterface *ret;\n"
+                '  ret = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "%s");\n'
+                "  if (ret == NULL)\n"
+                "    return NULL;\n"
+                "  return %s%s (ret);\n"
+                "}\n"
+                "\n" % (i.name, self.ns_upper, i.name_upper)
+            )
+        self.outfile.write("\n")
         for i in self.ifaces:
-            self.outfile.write(self.docbook_gen.expand(
-                    '/**\n'
-                    ' * %sobject_peek_%s: (skip)\n'
-                    ' * @object: A #%sObject.\n'
-                    ' *\n'
-                    ' * Like %sobject_get_%s() but doesn\'t increase the reference count on the returned object.\n'
-                    ' *\n'
-                    ' * It is not safe to use the returned object if you are on another thread than the one where the #GDBusObjectManagerClient or #GDBusObjectManagerServer for @object is running.\n'
-                    ' *\n'
-                    ' * Returns: (transfer none) (nullable): A #%s or %%NULL if @object does not implement the interface. Do not free the returned object, it is owned by @object.\n'
-                    %(self.ns_lower, i.name_upper.lower(), self.namespace, self.ns_lower, i.name_upper.lower(), i.camel_name), False))
+            self.outfile.write(
+                self.docbook_gen.expand(
+                    "/**\n"
+                    " * %sobject_peek_%s: (skip)\n"
+                    " * @object: A #%sObject.\n"
+                    " *\n"
+                    " * Like %sobject_get_%s() but doesn't increase the reference count on the returned object.\n"
+                    " *\n"
+                    " * It is not safe to use the returned object if you are on another thread than the one where the #GDBusObjectManagerClient or #GDBusObjectManagerServer for @object is running.\n"
+                    " *\n"
+                    " * Returns: (transfer none) (nullable): A #%s or %%NULL if @object does not implement the interface. Do not free the returned object, it is owned by @object.\n"
+                    % (
+                        self.ns_lower,
+                        i.name_upper.lower(),
+                        self.namespace,
+                        self.ns_lower,
+                        i.name_upper.lower(),
+                        i.camel_name,
+                    ),
+                    False,
+                )
+            )
             self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0)
-            self.outfile.write('%s *%sobject_peek_%s (%sObject *object)\n'
-                               %(i.camel_name, self.ns_lower, i.name_upper.lower(), self.namespace))
-            self.outfile.write('{\n'
-                               '  GDBusInterface *ret;\n'
-                               '  ret = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "%s");\n'
-                               '  if (ret == NULL)\n'
-                               '    return NULL;\n'
-                               '  g_object_unref (ret);\n'
-                               '  return %s%s (ret);\n'
-                               '}\n'
-                               '\n'
-                               %(i.name, self.ns_upper, i.name_upper))
-        self.outfile.write('\n')
+            self.outfile.write(
+                "%s *%sobject_peek_%s (%sObject *object)\n"
+                % (i.camel_name, self.ns_lower, i.name_upper.lower(), self.namespace)
+            )
+            self.outfile.write(
+                "{\n"
+                "  GDBusInterface *ret;\n"
+                '  ret = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "%s");\n'
+                "  if (ret == NULL)\n"
+                "    return NULL;\n"
+                "  g_object_unref (ret);\n"
+                "  return %s%s (ret);\n"
+                "}\n"
+                "\n" % (i.name, self.ns_upper, i.name_upper)
+            )
+        self.outfile.write("\n")
         # shared by ObjectProxy and ObjectSkeleton classes
-        self.outfile.write('static void\n'
-                           '%sobject_notify (GDBusObject *object, GDBusInterface *interface)\n'
-                           '{\n'
-                           '  _ExtendedGDBusInterfaceInfo *info = (_ExtendedGDBusInterfaceInfo *) g_dbus_interface_get_info (interface);\n'
-                           '  /* info can be NULL if the other end is using a D-Bus interface we don\'t know\n'
-                           '   * anything about, for example old generated code in this process talking to\n'
-                           '   * newer generated code in the other process. */\n'
-                           '  if (info != NULL)\n'
-                           '    g_object_notify (G_OBJECT (object), info->hyphen_name);\n'
-                           '}\n'
-                           '\n'
-                           %(self.ns_lower))
-
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * %sObjectProxy:\n'
-                ' *\n'
-                ' * The #%sObjectProxy structure contains only private data and should only be accessed using the provided API.\n'
-                %(self.namespace, self.namespace), False))
-        self.outfile.write(' */\n')
-        self.outfile.write('\n')
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * %sObjectProxyClass:\n'
-                ' * @parent_class: The parent class.\n'
-                ' *\n'
-                ' * Class structure for #%sObjectProxy.\n'
-                %(self.namespace, self.namespace), False))
-        self.outfile.write(' */\n')
-        self.outfile.write('\n')
+        self.outfile.write(
+            "static void\n"
+            "%sobject_notify (GDBusObject *object, GDBusInterface *interface)\n"
+            "{\n"
+            "  _ExtendedGDBusInterfaceInfo *info = (_ExtendedGDBusInterfaceInfo *) g_dbus_interface_get_info (interface);\n"
+            "  /* info can be NULL if the other end is using a D-Bus interface we don't know\n"
+            "   * anything about, for example old generated code in this process talking to\n"
+            "   * newer generated code in the other process. */\n"
+            "  if (info != NULL)\n"
+            "    g_object_notify (G_OBJECT (object), info->hyphen_name);\n"
+            "}\n"
+            "\n" % (self.ns_lower)
+        )
+
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %sObjectProxy:\n"
+                " *\n"
+                " * The #%sObjectProxy structure contains only private data and should only be accessed using the provided API.\n"
+                % (self.namespace, self.namespace),
+                False,
+            )
+        )
+        self.outfile.write(" */\n")
+        self.outfile.write("\n")
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %sObjectProxyClass:\n"
+                " * @parent_class: The parent class.\n"
+                " *\n"
+                " * Class structure for #%sObjectProxy.\n"
+                % (self.namespace, self.namespace),
+                False,
+            )
+        )
+        self.outfile.write(" */\n")
+        self.outfile.write("\n")
         # class boilerplate
-        self.outfile.write('static void\n'
-                           '%sobject_proxy__%sobject_iface_init (%sObjectIface *iface G_GNUC_UNUSED)\n'
-                           '{\n'
-                           '}\n'
-                           '\n'
-                           %(self.ns_lower, self.ns_lower, self.namespace))
-        self.outfile.write('static void\n'
-                           '%sobject_proxy__g_dbus_object_iface_init (GDBusObjectIface *iface)\n'
-                           '{\n'
-                           '  iface->interface_added = %sobject_notify;\n'
-                           '  iface->interface_removed = %sobject_notify;\n'
-                           '}\n'
-                           '\n'
-                           %(self.ns_lower, self.ns_lower, self.ns_lower))
-        self.outfile.write('\n')
-        self.outfile.write('G_DEFINE_TYPE_WITH_CODE (%sObjectProxy, %sobject_proxy, G_TYPE_DBUS_OBJECT_PROXY,\n'
-                           '                         G_IMPLEMENT_INTERFACE (%sTYPE_OBJECT, %sobject_proxy__%sobject_iface_init)\n'
-                           '                         G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT, %sobject_proxy__g_dbus_object_iface_init))\n'
-                           '\n'
-                           %(self.namespace, self.ns_lower, self.ns_upper, self.ns_lower, self.ns_lower, self.ns_lower))
+        self.outfile.write(
+            "static void\n"
+            "%sobject_proxy__%sobject_iface_init (%sObjectIface *iface G_GNUC_UNUSED)\n"
+            "{\n"
+            "}\n"
+            "\n" % (self.ns_lower, self.ns_lower, self.namespace)
+        )
+        self.outfile.write(
+            "static void\n"
+            "%sobject_proxy__g_dbus_object_iface_init (GDBusObjectIface *iface)\n"
+            "{\n"
+            "  iface->interface_added = %sobject_notify;\n"
+            "  iface->interface_removed = %sobject_notify;\n"
+            "}\n"
+            "\n" % (self.ns_lower, self.ns_lower, self.ns_lower)
+        )
+        self.outfile.write("\n")
+        self.outfile.write(
+            "G_DEFINE_TYPE_WITH_CODE (%sObjectProxy, %sobject_proxy, G_TYPE_DBUS_OBJECT_PROXY,\n"
+            "                         G_IMPLEMENT_INTERFACE (%sTYPE_OBJECT, %sobject_proxy__%sobject_iface_init)\n"
+            "                         G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT, %sobject_proxy__g_dbus_object_iface_init))\n"
+            "\n"
+            % (
+                self.namespace,
+                self.ns_lower,
+                self.ns_upper,
+                self.ns_lower,
+                self.ns_lower,
+                self.ns_lower,
+            )
+        )
         # class boilerplate
-        self.outfile.write('static void\n'
-                           '%sobject_proxy_init (%sObjectProxy *object G_GNUC_UNUSED)\n'
-                           '{\n'
-                           '}\n'
-                           '\n'%(self.ns_lower, self.namespace))
-        self.outfile.write('static void\n'
-                           '%sobject_proxy_set_property (GObject      *gobject,\n'
-                           '  guint         prop_id,\n'
-                           '  const GValue *value G_GNUC_UNUSED,\n'
-                           '  GParamSpec   *pspec)\n'
-                           '{\n'
-                           '  G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);\n'
-                           %(self.ns_lower))
-        self.outfile.write('}\n'
-                           '\n'%())
-        self.outfile.write('static void\n'
-                           '%sobject_proxy_get_property (GObject      *gobject,\n'
-                           '  guint         prop_id,\n'
-                           '  GValue       *value,\n'
-                           '  GParamSpec   *pspec)\n'
-                           '{\n'
-                           '  %sObjectProxy *object = %sOBJECT_PROXY (gobject);\n'
-                           '  GDBusInterface *interface;\n'
-                           '\n'
-                           '  switch (prop_id)\n'
-                           '    {\n'
-                           %(self.ns_lower, self.namespace, self.ns_upper))
+        self.outfile.write(
+            "static void\n"
+            "%sobject_proxy_init (%sObjectProxy *object G_GNUC_UNUSED)\n"
+            "{\n"
+            "}\n"
+            "\n" % (self.ns_lower, self.namespace)
+        )
+        self.outfile.write(
+            "static void\n"
+            "%sobject_proxy_set_property (GObject      *gobject,\n"
+            "  guint         prop_id,\n"
+            "  const GValue *value G_GNUC_UNUSED,\n"
+            "  GParamSpec   *pspec)\n"
+            "{\n"
+            "  G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);\n"
+            % (self.ns_lower)
+        )
+        self.outfile.write("}\n" "\n")
+        self.outfile.write(
+            "static void\n"
+            "%sobject_proxy_get_property (GObject      *gobject,\n"
+            "  guint         prop_id,\n"
+            "  GValue       *value,\n"
+            "  GParamSpec   *pspec)\n"
+            "{\n"
+            "  %sObjectProxy *object = %sOBJECT_PROXY (gobject);\n"
+            "  GDBusInterface *interface;\n"
+            "\n"
+            "  switch (prop_id)\n"
+            "    {\n" % (self.ns_lower, self.namespace, self.ns_upper)
+        )
         n = 1
         for i in self.ifaces:
-            self.outfile.write('    case %d:\n'
-                               '      interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "%s");\n'
-                               '      g_value_take_object (value, interface);\n'
-                               '      break;\n'
-                               '\n'
-                               %(n, i.name))
+            self.outfile.write(
+                "    case %d:\n"
+                '      interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "%s");\n'
+                "      g_value_take_object (value, interface);\n"
+                "      break;\n"
+                "\n" % (n, i.name)
+            )
             n += 1
-        self.outfile.write('    default:\n'
-                           '      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);\n'
-                           '      break;\n'
-                           '  }\n'
-                           '}\n'
-                           '\n'%())
-        self.outfile.write('static void\n'
-                           '%sobject_proxy_class_init (%sObjectProxyClass *klass)\n'
-                           '{\n'
-                           '  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);\n'
-                           '\n'
-                           '  gobject_class->set_property = %sobject_proxy_set_property;\n'
-                           '  gobject_class->get_property = %sobject_proxy_get_property;\n'
-                           '\n'
-                           %(self.ns_lower, self.namespace, self.ns_lower, self.ns_lower))
+        self.outfile.write(
+            "    default:\n"
+            "      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);\n"
+            "      break;\n"
+            "  }\n"
+            "}\n"
+            "\n"
+        )
+        self.outfile.write(
+            "static void\n"
+            "%sobject_proxy_class_init (%sObjectProxyClass *klass)\n"
+            "{\n"
+            "  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);\n"
+            "\n"
+            "  gobject_class->set_property = %sobject_proxy_set_property;\n"
+            "  gobject_class->get_property = %sobject_proxy_get_property;\n"
+            "\n" % (self.ns_lower, self.namespace, self.ns_lower, self.ns_lower)
+        )
         n = 1
         for i in self.ifaces:
-            self.outfile.write('  g_object_class_override_property (gobject_class, %d, "%s");'
-                               '\n'
-                               %(n, i.name_hyphen))
+            self.outfile.write(
+                '  g_object_class_override_property (gobject_class, %d, "%s");'
+                "\n" % (n, i.name_hyphen)
+            )
             n += 1
-        self.outfile.write('}\n'
-                           '\n')
-
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * %sobject_proxy_new:\n'
-                ' * @connection: A #GDBusConnection.\n'
-                ' * @object_path: An object path.\n'
-                ' *\n'
-                ' * Creates a new proxy object.\n'
-                ' *\n'
-                ' * Returns: (transfer full): The proxy object.\n'
-                ' */\n'
-                %(self.ns_lower), False))
-        self.outfile.write('%sObjectProxy *\n'
-                     '%sobject_proxy_new (GDBusConnection *connection,\n'
-                     '  const gchar *object_path)\n'
-                     '{\n'
-                     '  g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);\n'
-                     '  g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);\n'
-                     '  return %sOBJECT_PROXY (g_object_new (%sTYPE_OBJECT_PROXY, "g-connection", connection, "g-object-path", object_path, NULL));\n'
-                     '}\n'
-                     '\n'%(self.namespace, self.ns_lower, self.ns_upper, self.ns_upper))
-
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * %sObjectSkeleton:\n'
-                ' *\n'
-                ' * The #%sObjectSkeleton structure contains only private data and should only be accessed using the provided API.\n'
-                %(self.namespace, self.namespace), False))
-        self.outfile.write(' */\n')
-        self.outfile.write('\n')
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * %sObjectSkeletonClass:\n'
-                ' * @parent_class: The parent class.\n'
-                ' *\n'
-                ' * Class structure for #%sObjectSkeleton.\n'
-                %(self.namespace, self.namespace), False))
-        self.outfile.write(' */\n')
-        self.outfile.write('\n')
+        self.outfile.write("}\n" "\n")
+
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %sobject_proxy_new:\n"
+                " * @connection: A #GDBusConnection.\n"
+                " * @object_path: An object path.\n"
+                " *\n"
+                " * Creates a new proxy object.\n"
+                " *\n"
+                " * Returns: (transfer full): The proxy object.\n"
+                " */\n" % (self.ns_lower),
+                False,
+            )
+        )
+        self.outfile.write(
+            "%sObjectProxy *\n"
+            "%sobject_proxy_new (GDBusConnection *connection,\n"
+            "  const gchar *object_path)\n"
+            "{\n"
+            "  g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);\n"
+            "  g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);\n"
+            '  return %sOBJECT_PROXY (g_object_new (%sTYPE_OBJECT_PROXY, "g-connection", connection, "g-object-path", object_path, NULL));\n'
+            "}\n"
+            "\n" % (self.namespace, self.ns_lower, self.ns_upper, self.ns_upper)
+        )
+
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %sObjectSkeleton:\n"
+                " *\n"
+                " * The #%sObjectSkeleton structure contains only private data and should only be accessed using the provided API.\n"
+                % (self.namespace, self.namespace),
+                False,
+            )
+        )
+        self.outfile.write(" */\n")
+        self.outfile.write("\n")
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %sObjectSkeletonClass:\n"
+                " * @parent_class: The parent class.\n"
+                " *\n"
+                " * Class structure for #%sObjectSkeleton.\n"
+                % (self.namespace, self.namespace),
+                False,
+            )
+        )
+        self.outfile.write(" */\n")
+        self.outfile.write("\n")
         # class boilerplate
-        self.outfile.write('static void\n'
-                           '%sobject_skeleton__%sobject_iface_init (%sObjectIface *iface G_GNUC_UNUSED)\n'
-                           '{\n'
-                           '}\n'
-                           '\n'
-                           %(self.ns_lower, self.ns_lower, self.namespace))
-        self.outfile.write('\n')
-        self.outfile.write('static void\n'
-                           '%sobject_skeleton__g_dbus_object_iface_init (GDBusObjectIface *iface)\n'
-                           '{\n'
-                           '  iface->interface_added = %sobject_notify;\n'
-                           '  iface->interface_removed = %sobject_notify;\n'
-                           '}\n'
-                           '\n'
-                           %(self.ns_lower, self.ns_lower, self.ns_lower))
-        self.outfile.write('G_DEFINE_TYPE_WITH_CODE (%sObjectSkeleton, %sobject_skeleton, G_TYPE_DBUS_OBJECT_SKELETON,\n'
-                           '                         G_IMPLEMENT_INTERFACE (%sTYPE_OBJECT, %sobject_skeleton__%sobject_iface_init)\n'
-                           '                         G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT, %sobject_skeleton__g_dbus_object_iface_init))\n'
-                           '\n'
-                           %(self.namespace, self.ns_lower, self.ns_upper, self.ns_lower, self.ns_lower, self.ns_lower))
+        self.outfile.write(
+            "static void\n"
+            "%sobject_skeleton__%sobject_iface_init (%sObjectIface *iface G_GNUC_UNUSED)\n"
+            "{\n"
+            "}\n"
+            "\n" % (self.ns_lower, self.ns_lower, self.namespace)
+        )
+        self.outfile.write("\n")
+        self.outfile.write(
+            "static void\n"
+            "%sobject_skeleton__g_dbus_object_iface_init (GDBusObjectIface *iface)\n"
+            "{\n"
+            "  iface->interface_added = %sobject_notify;\n"
+            "  iface->interface_removed = %sobject_notify;\n"
+            "}\n"
+            "\n" % (self.ns_lower, self.ns_lower, self.ns_lower)
+        )
+        self.outfile.write(
+            "G_DEFINE_TYPE_WITH_CODE (%sObjectSkeleton, %sobject_skeleton, G_TYPE_DBUS_OBJECT_SKELETON,\n"
+            "                         G_IMPLEMENT_INTERFACE (%sTYPE_OBJECT, %sobject_skeleton__%sobject_iface_init)\n"
+            "                         G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT, %sobject_skeleton__g_dbus_object_iface_init))\n"
+            "\n"
+            % (
+                self.namespace,
+                self.ns_lower,
+                self.ns_upper,
+                self.ns_lower,
+                self.ns_lower,
+                self.ns_lower,
+            )
+        )
         # class boilerplate
-        self.outfile.write('static void\n'
-                           '%sobject_skeleton_init (%sObjectSkeleton *object G_GNUC_UNUSED)\n'
-                           '{\n'
-                           '}\n'
-                           '\n'%(self.ns_lower, self.namespace))
-        self.outfile.write('static void\n'
-                           '%sobject_skeleton_set_property (GObject      *gobject,\n'
-                           '  guint         prop_id,\n'
-                           '  const GValue *value,\n'
-                           '  GParamSpec   *pspec)\n'
-                           '{\n'
-                           '  %sObjectSkeleton *object = %sOBJECT_SKELETON (gobject);\n'
-                           '  GDBusInterfaceSkeleton *interface;\n'
-                           '\n'
-                           '  switch (prop_id)\n'
-                           '    {\n'
-                           %(self.ns_lower, self.namespace, self.ns_upper))
+        self.outfile.write(
+            "static void\n"
+            "%sobject_skeleton_init (%sObjectSkeleton *object G_GNUC_UNUSED)\n"
+            "{\n"
+            "}\n"
+            "\n" % (self.ns_lower, self.namespace)
+        )
+        self.outfile.write(
+            "static void\n"
+            "%sobject_skeleton_set_property (GObject      *gobject,\n"
+            "  guint         prop_id,\n"
+            "  const GValue *value,\n"
+            "  GParamSpec   *pspec)\n"
+            "{\n"
+            "  %sObjectSkeleton *object = %sOBJECT_SKELETON (gobject);\n"
+            "  GDBusInterfaceSkeleton *interface;\n"
+            "\n"
+            "  switch (prop_id)\n"
+            "    {\n" % (self.ns_lower, self.namespace, self.ns_upper)
+        )
         n = 1
         for i in self.ifaces:
-            self.outfile.write('    case %d:\n'
-                               '      interface = g_value_get_object (value);\n'
-                               '      if (interface != NULL)\n'
-                               '        {\n'
-                               '          g_warn_if_fail (%sIS_%s (interface));\n'
-                               '          g_dbus_object_skeleton_add_interface (G_DBUS_OBJECT_SKELETON (object), interface);\n'
-                               '        }\n'
-                               '      else\n'
-                               '        {\n'
-                               '          g_dbus_object_skeleton_remove_interface_by_name (G_DBUS_OBJECT_SKELETON (object), "%s");\n'
-                               '        }\n'
-                               '      break;\n'
-                               '\n'
-                               %(n, self.ns_upper, i.name_upper, i.name))
+            self.outfile.write(
+                "    case %d:\n"
+                "      interface = g_value_get_object (value);\n"
+                "      if (interface != NULL)\n"
+                "        {\n"
+                "          g_warn_if_fail (%sIS_%s (interface));\n"
+                "          g_dbus_object_skeleton_add_interface (G_DBUS_OBJECT_SKELETON (object), interface);\n"
+                "        }\n"
+                "      else\n"
+                "        {\n"
+                '          g_dbus_object_skeleton_remove_interface_by_name (G_DBUS_OBJECT_SKELETON (object), "%s");\n'
+                "        }\n"
+                "      break;\n"
+                "\n" % (n, self.ns_upper, i.name_upper, i.name)
+            )
             n += 1
-        self.outfile.write('    default:\n'
-                     '      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);\n'
-                     '      break;\n'
-                     '  }\n'
-                     '}\n'
-                     '\n'%())
-        self.outfile.write('static void\n'
-                           '%sobject_skeleton_get_property (GObject      *gobject,\n'
-                           '  guint         prop_id,\n'
-                           '  GValue       *value,\n'
-                           '  GParamSpec   *pspec)\n'
-                           '{\n'
-                           '  %sObjectSkeleton *object = %sOBJECT_SKELETON (gobject);\n'
-                           '  GDBusInterface *interface;\n'
-                           '\n'
-                           '  switch (prop_id)\n'
-                           '    {\n'
-                           %(self.ns_lower, self.namespace, self.ns_upper))
+        self.outfile.write(
+            "    default:\n"
+            "      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);\n"
+            "      break;\n"
+            "  }\n"
+            "}\n"
+            "\n"
+        )
+        self.outfile.write(
+            "static void\n"
+            "%sobject_skeleton_get_property (GObject      *gobject,\n"
+            "  guint         prop_id,\n"
+            "  GValue       *value,\n"
+            "  GParamSpec   *pspec)\n"
+            "{\n"
+            "  %sObjectSkeleton *object = %sOBJECT_SKELETON (gobject);\n"
+            "  GDBusInterface *interface;\n"
+            "\n"
+            "  switch (prop_id)\n"
+            "    {\n" % (self.ns_lower, self.namespace, self.ns_upper)
+        )
         n = 1
         for i in self.ifaces:
-            self.outfile.write('    case %d:\n'
-                               '      interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "%s");\n'
-                               '      g_value_take_object (value, interface);\n'
-                               '      break;\n'
-                               '\n'
-                               %(n, i.name))
+            self.outfile.write(
+                "    case %d:\n"
+                '      interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "%s");\n'
+                "      g_value_take_object (value, interface);\n"
+                "      break;\n"
+                "\n" % (n, i.name)
+            )
             n += 1
-        self.outfile.write('    default:\n'
-                           '      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);\n'
-                           '      break;\n'
-                           '  }\n'
-                           '}\n'
-                           '\n'%())
-        self.outfile.write('static void\n'
-                           '%sobject_skeleton_class_init (%sObjectSkeletonClass *klass)\n'
-                           '{\n'
-                           '  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);\n'
-                           '\n'
-                           '  gobject_class->set_property = %sobject_skeleton_set_property;\n'
-                           '  gobject_class->get_property = %sobject_skeleton_get_property;\n'
-                           '\n'
-                           %(self.ns_lower, self.namespace, self.ns_lower, self.ns_lower))
+        self.outfile.write(
+            "    default:\n"
+            "      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);\n"
+            "      break;\n"
+            "  }\n"
+            "}\n"
+            "\n"
+        )
+        self.outfile.write(
+            "static void\n"
+            "%sobject_skeleton_class_init (%sObjectSkeletonClass *klass)\n"
+            "{\n"
+            "  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);\n"
+            "\n"
+            "  gobject_class->set_property = %sobject_skeleton_set_property;\n"
+            "  gobject_class->get_property = %sobject_skeleton_get_property;\n"
+            "\n" % (self.ns_lower, self.namespace, self.ns_lower, self.ns_lower)
+        )
         n = 1
         for i in self.ifaces:
-            self.outfile.write('  g_object_class_override_property (gobject_class, %d, "%s");'
-                               '\n'
-                               %(n, i.name_hyphen))
+            self.outfile.write(
+                '  g_object_class_override_property (gobject_class, %d, "%s");'
+                "\n" % (n, i.name_hyphen)
+            )
             n += 1
-        self.outfile.write('}\n'
-                           '\n')
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * %sobject_skeleton_new:\n'
-                ' * @object_path: An object path.\n'
-                ' *\n'
-                ' * Creates a new skeleton object.\n'
-                ' *\n'
-                ' * Returns: (transfer full): The skeleton object.\n'
-                ' */\n'
-                %(self.ns_lower), False))
-        self.outfile.write('%sObjectSkeleton *\n'
-                           '%sobject_skeleton_new (const gchar *object_path)\n'
-                           '{\n'
-                           '  g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);\n'
-                           '  return %sOBJECT_SKELETON (g_object_new (%sTYPE_OBJECT_SKELETON, "g-object-path", object_path, NULL));\n'
-                           '}\n'
-                           '\n'%(self.namespace, self.ns_lower, self.ns_upper, self.ns_upper))
+        self.outfile.write("}\n" "\n")
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %sobject_skeleton_new:\n"
+                " * @object_path: An object path.\n"
+                " *\n"
+                " * Creates a new skeleton object.\n"
+                " *\n"
+                " * Returns: (transfer full): The skeleton object.\n"
+                " */\n" % (self.ns_lower),
+                False,
+            )
+        )
+        self.outfile.write(
+            "%sObjectSkeleton *\n"
+            "%sobject_skeleton_new (const gchar *object_path)\n"
+            "{\n"
+            "  g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);\n"
+            '  return %sOBJECT_SKELETON (g_object_new (%sTYPE_OBJECT_SKELETON, "g-object-path", object_path, NULL));\n'
+            "}\n"
+            "\n" % (self.namespace, self.ns_lower, self.ns_upper, self.ns_upper)
+        )
         for i in self.ifaces:
-            self.outfile.write(self.docbook_gen.expand(
-                    '/**\n'
-                    ' * %sobject_skeleton_set_%s:\n'
-                    ' * @object: A #%sObjectSkeleton.\n'
-                    ' * @interface_: (nullable): A #%s or %%NULL to clear the interface.\n'
-                    ' *\n'
-                    ' * Sets the #%s instance for the D-Bus interface #%s on @object.\n'
-                    %(self.ns_lower, i.name_upper.lower(), self.namespace, i.camel_name, i.camel_name, i.name), False))
+            self.outfile.write(
+                self.docbook_gen.expand(
+                    "/**\n"
+                    " * %sobject_skeleton_set_%s:\n"
+                    " * @object: A #%sObjectSkeleton.\n"
+                    " * @interface_: (nullable): A #%s or %%NULL to clear the interface.\n"
+                    " *\n"
+                    " * Sets the #%s instance for the D-Bus interface #%s on @object.\n"
+                    % (
+                        self.ns_lower,
+                        i.name_upper.lower(),
+                        self.namespace,
+                        i.camel_name,
+                        i.camel_name,
+                        i.name,
+                    ),
+                    False,
+                )
+            )
             self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0)
-            self.outfile.write('void %sobject_skeleton_set_%s (%sObjectSkeleton *object, %s *interface_)\n'
-                               %(self.ns_lower, i.name_upper.lower(), self.namespace, i.camel_name))
-            self.outfile.write('{\n'
-                               '  g_object_set (G_OBJECT (object), "%s", interface_, NULL);\n'
-                               '}\n'
-                               '\n'
-                               %(i.name_hyphen))
-        self.outfile.write('\n')
-
+            self.outfile.write(
+                "void %sobject_skeleton_set_%s (%sObjectSkeleton *object, %s *interface_)\n"
+                % (self.ns_lower, i.name_upper.lower(), self.namespace, i.camel_name)
+            )
+            self.outfile.write(
+                "{\n"
+                '  g_object_set (G_OBJECT (object), "%s", interface_, NULL);\n'
+                "}\n"
+                "\n" % (i.name_hyphen)
+            )
+        self.outfile.write("\n")
 
     def generate_object_manager_client(self):
-        self.outfile.write('/* ------------------------------------------------------------------------\n'
-                           ' * Code for ObjectManager client\n'
-                           ' * ------------------------------------------------------------------------\n'
-                           ' */\n'
-                           '\n')
-
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * SECTION:%sObjectManagerClient\n'
-                ' * @title: %sObjectManagerClient\n'
-                ' * @short_description: Generated GDBusObjectManagerClient type\n'
-                ' *\n'
-                ' * This section contains a #GDBusObjectManagerClient that uses %sobject_manager_client_get_proxy_type() as the #GDBusProxyTypeFunc.\n'
-                ' */\n'
-                %(self.namespace, self.namespace, self.ns_lower), False))
-        self.outfile.write('\n')
-
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * %sObjectManagerClient:\n'
-                ' *\n'
-                ' * The #%sObjectManagerClient structure contains only private data and should only be accessed using the provided API.\n'
-                %(self.namespace, self.namespace), False))
-        self.outfile.write(' */\n')
-        self.outfile.write('\n')
-
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * %sObjectManagerClientClass:\n'
-                ' * @parent_class: The parent class.\n'
-                ' *\n'
-                ' * Class structure for #%sObjectManagerClient.\n'
-                %(self.namespace, self.namespace), False))
-        self.outfile.write(' */\n')
-        self.outfile.write('\n')
+        self.outfile.write(
+            "/* ------------------------------------------------------------------------\n"
+            " * Code for ObjectManager client\n"
+            " * ------------------------------------------------------------------------\n"
+            " */\n"
+            "\n"
+        )
+
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * SECTION:%sObjectManagerClient\n"
+                " * @title: %sObjectManagerClient\n"
+                " * @short_description: Generated GDBusObjectManagerClient type\n"
+                " *\n"
+                " * This section contains a #GDBusObjectManagerClient that uses %sobject_manager_client_get_proxy_type() as the #GDBusProxyTypeFunc.\n"
+                " */\n" % (self.namespace, self.namespace, self.ns_lower),
+                False,
+            )
+        )
+        self.outfile.write("\n")
+
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %sObjectManagerClient:\n"
+                " *\n"
+                " * The #%sObjectManagerClient structure contains only private data and should only be accessed using the provided API.\n"
+                % (self.namespace, self.namespace),
+                False,
+            )
+        )
+        self.outfile.write(" */\n")
+        self.outfile.write("\n")
+
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %sObjectManagerClientClass:\n"
+                " * @parent_class: The parent class.\n"
+                " *\n"
+                " * Class structure for #%sObjectManagerClient.\n"
+                % (self.namespace, self.namespace),
+                False,
+            )
+        )
+        self.outfile.write(" */\n")
+        self.outfile.write("\n")
 
         # class boilerplate
-        self.outfile.write('G_DEFINE_TYPE (%sObjectManagerClient, %sobject_manager_client, G_TYPE_DBUS_OBJECT_MANAGER_CLIENT)\n'
-                           '\n'
-                           %(self.namespace, self.ns_lower))
+        self.outfile.write(
+            "G_DEFINE_TYPE (%sObjectManagerClient, %sobject_manager_client, G_TYPE_DBUS_OBJECT_MANAGER_CLIENT)\n"
+            "\n" % (self.namespace, self.ns_lower)
+        )
 
         # class boilerplate
-        self.outfile.write('static void\n'
-                           '%sobject_manager_client_init (%sObjectManagerClient *manager G_GNUC_UNUSED)\n'
-                           '{\n'
-                           '}\n'
-                           '\n'%(self.ns_lower, self.namespace))
-        self.outfile.write('static void\n'
-                           '%sobject_manager_client_class_init (%sObjectManagerClientClass *klass G_GNUC_UNUSED)\n'
-                           '{\n'
-                           '}\n'
-                           '\n'%(self.ns_lower, self.namespace))
-
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * %sobject_manager_client_get_proxy_type:\n'
-                ' * @manager: A #GDBusObjectManagerClient.\n'
-                ' * @object_path: The object path of the remote object (unused).\n'
-                ' * @interface_name: (nullable): Interface name of the remote object or %%NULL to get the object proxy #GType.\n'
-                ' * @user_data: User data (unused).\n'
-                ' *\n'
-                ' * A #GDBusProxyTypeFunc that maps @interface_name to the generated #GDBusObjectProxy derived and #GDBusProxy derived types.\n'
-                ' *\n'
-                ' * Returns: A #GDBusProxy derived #GType if @interface_name is not %%NULL, otherwise the #GType for #%sObjectProxy.\n'
-                %(self.ns_lower, self.namespace), False))
-        self.outfile.write(' */\n')
-        self.outfile.write('GType\n'
-                           '%sobject_manager_client_get_proxy_type (GDBusObjectManagerClient *manager G_GNUC_UNUSED, const gchar *object_path G_GNUC_UNUSED, const gchar *interface_name, gpointer user_data G_GNUC_UNUSED)\n'
-                           '{\n'
-                           %(self.ns_lower))
-        self.outfile.write('  static gsize once_init_value = 0;\n'
-                           '  static GHashTable *lookup_hash;\n'
-                           '  GType ret;\n'
-                           '\n'
-                           '  if (interface_name == NULL)\n'
-                           '    return %sTYPE_OBJECT_PROXY;\n'
-                           '  if (g_once_init_enter (&once_init_value))\n'
-                           '    {\n'
-                           '      lookup_hash = g_hash_table_new (g_str_hash, g_str_equal);\n'
-                           %(self.ns_upper))
+        self.outfile.write(
+            "static void\n"
+            "%sobject_manager_client_init (%sObjectManagerClient *manager G_GNUC_UNUSED)\n"
+            "{\n"
+            "}\n"
+            "\n" % (self.ns_lower, self.namespace)
+        )
+        self.outfile.write(
+            "static void\n"
+            "%sobject_manager_client_class_init (%sObjectManagerClientClass *klass G_GNUC_UNUSED)\n"
+            "{\n"
+            "}\n"
+            "\n" % (self.ns_lower, self.namespace)
+        )
+
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %sobject_manager_client_get_proxy_type:\n"
+                " * @manager: A #GDBusObjectManagerClient.\n"
+                " * @object_path: The object path of the remote object (unused).\n"
+                " * @interface_name: (nullable): Interface name of the remote object or %%NULL to get the object proxy #GType.\n"
+                " * @user_data: User data (unused).\n"
+                " *\n"
+                " * A #GDBusProxyTypeFunc that maps @interface_name to the generated #GDBusObjectProxy derived and #GDBusProxy derived types.\n"
+                " *\n"
+                " * Returns: A #GDBusProxy derived #GType if @interface_name is not %%NULL, otherwise the #GType for #%sObjectProxy.\n"
+                % (self.ns_lower, self.namespace),
+                False,
+            )
+        )
+        self.outfile.write(" */\n")
+        self.outfile.write(
+            "GType\n"
+            "%sobject_manager_client_get_proxy_type (GDBusObjectManagerClient *manager G_GNUC_UNUSED, const gchar *object_path G_GNUC_UNUSED, const gchar *interface_name, gpointer user_data G_GNUC_UNUSED)\n"
+            "{\n" % (self.ns_lower)
+        )
+        self.outfile.write(
+            "  static gsize once_init_value = 0;\n"
+            "  static GHashTable *lookup_hash;\n"
+            "  GType ret;\n"
+            "\n"
+            "  if (interface_name == NULL)\n"
+            "    return %sTYPE_OBJECT_PROXY;\n"
+            "  if (g_once_init_enter (&once_init_value))\n"
+            "    {\n"
+            "      lookup_hash = g_hash_table_new (g_str_hash, g_str_equal);\n"
+            % (self.ns_upper)
+        )
         for i in self.ifaces:
-            self.outfile.write('      g_hash_table_insert (lookup_hash, (gpointer) "%s", GSIZE_TO_POINTER (%sTYPE_%s_PROXY));\n'
-                               %(i.name, i.ns_upper, i.name_upper))
-        self.outfile.write('      g_once_init_leave (&once_init_value, 1);\n'
-                           '    }\n')
-        self.outfile.write('  ret = (GType) GPOINTER_TO_SIZE (g_hash_table_lookup (lookup_hash, interface_name));\n'
-                           '  if (ret == (GType) 0)\n'
-                           '    ret = G_TYPE_DBUS_PROXY;\n')
-        self.outfile.write('  return ret;\n'
-                           '}\n'
-                           '\n')
+            self.outfile.write(
+                '      g_hash_table_insert (lookup_hash, (gpointer) "%s", GSIZE_TO_POINTER (%sTYPE_%s_PROXY));\n'
+                % (i.name, i.ns_upper, i.name_upper)
+            )
+        self.outfile.write("      g_once_init_leave (&once_init_value, 1);\n" "    }\n")
+        self.outfile.write(
+            "  ret = (GType) GPOINTER_TO_SIZE (g_hash_table_lookup (lookup_hash, interface_name));\n"
+            "  if (ret == (GType) 0)\n"
+            "    ret = G_TYPE_DBUS_PROXY;\n"
+        )
+        self.outfile.write("  return ret;\n" "}\n" "\n")
 
         # constructors
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * %sobject_manager_client_new:\n'
-                ' * @connection: A #GDBusConnection.\n'
-                ' * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.\n'
-                ' * @name: (nullable): A bus name (well-known or unique) or %%NULL if @connection is not a message bus connection.\n'
-                ' * @object_path: An object path.\n'
-                ' * @cancellable: (nullable): A #GCancellable or %%NULL.\n'
-                ' * @callback: A #GAsyncReadyCallback to call when the request is satisfied.\n'
-                ' * @user_data: User data to pass to @callback.\n'
-                ' *\n'
-                ' * Asynchronously creates #GDBusObjectManagerClient using %sobject_manager_client_get_proxy_type() as the #GDBusProxyTypeFunc. See g_dbus_object_manager_client_new() for more details.\n'
-                ' *\n'
-                ' * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from (see g_main_context_push_thread_default()).\n'
-                ' * You can then call %sobject_manager_client_new_finish() to get the result of the operation.\n'
-                ' *\n'
-                ' * See %sobject_manager_client_new_sync() for the synchronous, blocking version of this constructor.\n'
-                %(self.ns_lower, self.ns_lower, self.ns_lower, self.ns_lower), False))
-        self.outfile.write(' */\n')
-        self.outfile.write('void\n'
-                           '%sobject_manager_client_new (\n'
-                           '    GDBusConnection        *connection,\n'
-                           '    GDBusObjectManagerClientFlags  flags,\n'
-                           '    const gchar            *name,\n'
-                           '    const gchar            *object_path,\n'
-                           '    GCancellable           *cancellable,\n'
-                           '    GAsyncReadyCallback     callback,\n'
-                           '    gpointer                user_data)\n'
-                           '{\n'
-                           '  g_async_initable_new_async (%sTYPE_OBJECT_MANAGER_CLIENT, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "flags", flags, "name", name, "connection", connection, "object-path", object_path, "get-proxy-type-func", %sobject_manager_client_get_proxy_type, NULL);\n'
-                           '}\n'
-                           '\n'
-                           %(self.ns_lower, self.ns_upper, self.ns_lower))
-        self.outfile.write('/**\n'
-                           ' * %sobject_manager_client_new_finish:\n'
-                           ' * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %sobject_manager_client_new().\n'
-                           ' * @error: Return location for error or %%NULL\n'
-                           ' *\n'
-                           ' * Finishes an operation started with %sobject_manager_client_new().\n'
-                           ' *\n'
-                           ' * Returns: (transfer full) (type %sObjectManagerClient): The constructed object manager client or %%NULL if @error is set.\n'
-                           %(self.ns_lower, self.ns_lower, self.ns_lower, self.namespace))
-        self.outfile.write(' */\n')
-        self.outfile.write('GDBusObjectManager *\n'
-                           '%sobject_manager_client_new_finish (\n'
-                           '    GAsyncResult        *res,\n'
-                           '    GError             **error)\n'
-                           '{\n'
-                           '  GObject *ret;\n'
-                           '  GObject *source_object;\n'
-                           '  source_object = g_async_result_get_source_object (res);\n'
-                           '  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);\n'
-                           '  g_object_unref (source_object);\n'
-                           '  if (ret != NULL)\n'
-                           '    return G_DBUS_OBJECT_MANAGER (ret);\n'
-                           '  else\n'
-                           '    return NULL;\n'
-                           '}\n'
-                           '\n'
-                           %(self.ns_lower))
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * %sobject_manager_client_new_sync:\n'
-                ' * @connection: A #GDBusConnection.\n'
-                ' * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.\n'
-                ' * @name: (nullable): A bus name (well-known or unique) or %%NULL if @connection is not a message bus connection.\n'
-                ' * @object_path: An object path.\n'
-                ' * @cancellable: (nullable): A #GCancellable or %%NULL.\n'
-                ' * @error: Return location for error or %%NULL\n'
-                ' *\n'
-                ' * Synchronously creates #GDBusObjectManagerClient using %sobject_manager_client_get_proxy_type() as the #GDBusProxyTypeFunc. See g_dbus_object_manager_client_new_sync() for more details.\n'
-                ' *\n'
-                ' * The calling thread is blocked until a reply is received.\n'
-                ' *\n'
-                ' * See %sobject_manager_client_new() for the asynchronous version of this constructor.\n'
-                ' *\n'
-                ' * Returns: (transfer full) (type %sObjectManagerClient): The constructed object manager client or %%NULL if @error is set.\n'
-                %(self.ns_lower, self.ns_lower, self.ns_lower, self.namespace), False))
-        self.outfile.write(' */\n')
-        self.outfile.write('GDBusObjectManager *\n'
-                           '%sobject_manager_client_new_sync (\n'
-                           '    GDBusConnection        *connection,\n'
-                           '    GDBusObjectManagerClientFlags  flags,\n'
-                           '    const gchar            *name,\n'
-                           '    const gchar            *object_path,\n'
-                           '    GCancellable           *cancellable,\n'
-                           '    GError                **error)\n'
-                           '{\n'
-                           '  GInitable *ret;\n'
-                           '  ret = g_initable_new (%sTYPE_OBJECT_MANAGER_CLIENT, cancellable, error, "flags", flags, "name", name, "connection", connection, "object-path", object_path, "get-proxy-type-func", %sobject_manager_client_get_proxy_type, NULL);\n'
-                           '  if (ret != NULL)\n'
-                           '    return G_DBUS_OBJECT_MANAGER (ret);\n'
-                           '  else\n'
-                           '    return NULL;\n'
-                           '}\n'
-                           '\n'
-                           %(self.ns_lower, self.ns_upper, self.ns_lower))
-        self.outfile.write('\n')
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * %sobject_manager_client_new_for_bus:\n'
-                ' * @bus_type: A #GBusType.\n'
-                ' * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.\n'
-                ' * @name: A bus name (well-known or unique).\n'
-                ' * @object_path: An object path.\n'
-                ' * @cancellable: (nullable): A #GCancellable or %%NULL.\n'
-                ' * @callback: A #GAsyncReadyCallback to call when the request is satisfied.\n'
-                ' * @user_data: User data to pass to @callback.\n'
-                ' *\n'
-                ' * Like %sobject_manager_client_new() but takes a #GBusType instead of a #GDBusConnection.\n'
-                ' *\n'
-                ' * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from (see g_main_context_push_thread_default()).\n'
-                ' * You can then call %sobject_manager_client_new_for_bus_finish() to get the result of the operation.\n'
-                ' *\n'
-                ' * See %sobject_manager_client_new_for_bus_sync() for the synchronous, blocking version of this constructor.\n'
-                %(self.ns_lower, self.ns_lower, self.ns_lower, self.ns_lower), False))
-        self.outfile.write(' */\n')
-        self.outfile.write('void\n'
-                           '%sobject_manager_client_new_for_bus (\n'
-                           '    GBusType                bus_type,\n'
-                           '    GDBusObjectManagerClientFlags  flags,\n'
-                           '    const gchar            *name,\n'
-                           '    const gchar            *object_path,\n'
-                           '    GCancellable           *cancellable,\n'
-                           '    GAsyncReadyCallback     callback,\n'
-                           '    gpointer                user_data)\n'
-                           '{\n'
-                           '  g_async_initable_new_async (%sTYPE_OBJECT_MANAGER_CLIENT, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "flags", flags, "name", name, "bus-type", bus_type, "object-path", object_path, "get-proxy-type-func", %sobject_manager_client_get_proxy_type, NULL);\n'
-                           '}\n'
-                           '\n'
-                           %(self.ns_lower, self.ns_upper, self.ns_lower))
-        self.outfile.write('/**\n'
-                           ' * %sobject_manager_client_new_for_bus_finish:\n'
-                           ' * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %sobject_manager_client_new_for_bus().\n'
-                           ' * @error: Return location for error or %%NULL\n'
-                           ' *\n'
-                           ' * Finishes an operation started with %sobject_manager_client_new_for_bus().\n'
-                           ' *\n'
-                           ' * Returns: (transfer full) (type %sObjectManagerClient): The constructed object manager client or %%NULL if @error is set.\n'
-                           %(self.ns_lower, self.ns_lower, self.ns_lower, self.namespace))
-        self.outfile.write(' */\n')
-        self.outfile.write('GDBusObjectManager *\n'
-                           '%sobject_manager_client_new_for_bus_finish (\n'
-                           '    GAsyncResult        *res,\n'
-                           '    GError             **error)\n'
-                           '{\n'
-                           '  GObject *ret;\n'
-                           '  GObject *source_object;\n'
-                           '  source_object = g_async_result_get_source_object (res);\n'
-                           '  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);\n'
-                           '  g_object_unref (source_object);\n'
-                           '  if (ret != NULL)\n'
-                           '    return G_DBUS_OBJECT_MANAGER (ret);\n'
-                           '  else\n'
-                           '    return NULL;\n'
-                           '}\n'
-                           '\n'
-                           %(self.ns_lower))
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * %sobject_manager_client_new_for_bus_sync:\n'
-                ' * @bus_type: A #GBusType.\n'
-                ' * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.\n'
-                ' * @name: A bus name (well-known or unique).\n'
-                ' * @object_path: An object path.\n'
-                ' * @cancellable: (nullable): A #GCancellable or %%NULL.\n'
-                ' * @error: Return location for error or %%NULL\n'
-                ' *\n'
-                ' * Like %sobject_manager_client_new_sync() but takes a #GBusType instead of a #GDBusConnection.\n'
-                ' *\n'
-                ' * The calling thread is blocked until a reply is received.\n'
-                ' *\n'
-                ' * See %sobject_manager_client_new_for_bus() for the asynchronous version of this constructor.\n'
-                ' *\n'
-                ' * Returns: (transfer full) (type %sObjectManagerClient): The constructed object manager client or %%NULL if @error is set.\n'
-                %(self.ns_lower, self.ns_lower, self.ns_lower, self.namespace), False))
-        self.outfile.write(' */\n')
-        self.outfile.write('GDBusObjectManager *\n'
-                           '%sobject_manager_client_new_for_bus_sync (\n'
-                           '    GBusType                bus_type,\n'
-                           '    GDBusObjectManagerClientFlags  flags,\n'
-                           '    const gchar            *name,\n'
-                           '    const gchar            *object_path,\n'
-                           '    GCancellable           *cancellable,\n'
-                           '    GError                **error)\n'
-                           '{\n'
-                           '  GInitable *ret;\n'
-                           '  ret = g_initable_new (%sTYPE_OBJECT_MANAGER_CLIENT, cancellable, error, "flags", flags, "name", name, "bus-type", bus_type, "object-path", object_path, "get-proxy-type-func", %sobject_manager_client_get_proxy_type, NULL);\n'
-                           '  if (ret != NULL)\n'
-                           '    return G_DBUS_OBJECT_MANAGER (ret);\n'
-                           '  else\n'
-                           '    return NULL;\n'
-                           '}\n'
-                           '\n'
-                           %(self.ns_lower, self.ns_upper, self.ns_lower))
-        self.outfile.write('\n')
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %sobject_manager_client_new:\n"
+                " * @connection: A #GDBusConnection.\n"
+                " * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.\n"
+                " * @name: (nullable): A bus name (well-known or unique) or %%NULL if @connection is not a message bus connection.\n"
+                " * @object_path: An object path.\n"
+                " * @cancellable: (nullable): A #GCancellable or %%NULL.\n"
+                " * @callback: A #GAsyncReadyCallback to call when the request is satisfied.\n"
+                " * @user_data: User data to pass to @callback.\n"
+                " *\n"
+                " * Asynchronously creates #GDBusObjectManagerClient using %sobject_manager_client_get_proxy_type() as the #GDBusProxyTypeFunc. See g_dbus_object_manager_client_new() for more details.\n"
+                " *\n"
+                " * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from (see g_main_context_push_thread_default()).\n"
+                " * You can then call %sobject_manager_client_new_finish() to get the result of the operation.\n"
+                " *\n"
+                " * See %sobject_manager_client_new_sync() for the synchronous, blocking version of this constructor.\n"
+                % (self.ns_lower, self.ns_lower, self.ns_lower, self.ns_lower),
+                False,
+            )
+        )
+        self.outfile.write(" */\n")
+        self.outfile.write(
+            "void\n"
+            "%sobject_manager_client_new (\n"
+            "    GDBusConnection        *connection,\n"
+            "    GDBusObjectManagerClientFlags  flags,\n"
+            "    const gchar            *name,\n"
+            "    const gchar            *object_path,\n"
+            "    GCancellable           *cancellable,\n"
+            "    GAsyncReadyCallback     callback,\n"
+            "    gpointer                user_data)\n"
+            "{\n"
+            '  g_async_initable_new_async (%sTYPE_OBJECT_MANAGER_CLIENT, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "flags", flags, "name", name, "connection", connection, "object-path", object_path, "get-proxy-type-func", %sobject_manager_client_get_proxy_type, NULL);\n'
+            "}\n"
+            "\n" % (self.ns_lower, self.ns_upper, self.ns_lower)
+        )
+        self.outfile.write(
+            "/**\n"
+            " * %sobject_manager_client_new_finish:\n"
+            " * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %sobject_manager_client_new().\n"
+            " * @error: Return location for error or %%NULL\n"
+            " *\n"
+            " * Finishes an operation started with %sobject_manager_client_new().\n"
+            " *\n"
+            " * Returns: (transfer full) (type %sObjectManagerClient): The constructed object manager client or %%NULL if @error is set.\n"
+            % (self.ns_lower, self.ns_lower, self.ns_lower, self.namespace)
+        )
+        self.outfile.write(" */\n")
+        self.outfile.write(
+            "GDBusObjectManager *\n"
+            "%sobject_manager_client_new_finish (\n"
+            "    GAsyncResult        *res,\n"
+            "    GError             **error)\n"
+            "{\n"
+            "  GObject *ret;\n"
+            "  GObject *source_object;\n"
+            "  source_object = g_async_result_get_source_object (res);\n"
+            "  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);\n"
+            "  g_object_unref (source_object);\n"
+            "  if (ret != NULL)\n"
+            "    return G_DBUS_OBJECT_MANAGER (ret);\n"
+            "  else\n"
+            "    return NULL;\n"
+            "}\n"
+            "\n" % (self.ns_lower)
+        )
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %sobject_manager_client_new_sync:\n"
+                " * @connection: A #GDBusConnection.\n"
+                " * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.\n"
+                " * @name: (nullable): A bus name (well-known or unique) or %%NULL if @connection is not a message bus connection.\n"
+                " * @object_path: An object path.\n"
+                " * @cancellable: (nullable): A #GCancellable or %%NULL.\n"
+                " * @error: Return location for error or %%NULL\n"
+                " *\n"
+                " * Synchronously creates #GDBusObjectManagerClient using %sobject_manager_client_get_proxy_type() as the #GDBusProxyTypeFunc. See g_dbus_object_manager_client_new_sync() for more details.\n"
+                " *\n"
+                " * The calling thread is blocked until a reply is received.\n"
+                " *\n"
+                " * See %sobject_manager_client_new() for the asynchronous version of this constructor.\n"
+                " *\n"
+                " * Returns: (transfer full) (type %sObjectManagerClient): The constructed object manager client or %%NULL if @error is set.\n"
+                % (self.ns_lower, self.ns_lower, self.ns_lower, self.namespace),
+                False,
+            )
+        )
+        self.outfile.write(" */\n")
+        self.outfile.write(
+            "GDBusObjectManager *\n"
+            "%sobject_manager_client_new_sync (\n"
+            "    GDBusConnection        *connection,\n"
+            "    GDBusObjectManagerClientFlags  flags,\n"
+            "    const gchar            *name,\n"
+            "    const gchar            *object_path,\n"
+            "    GCancellable           *cancellable,\n"
+            "    GError                **error)\n"
+            "{\n"
+            "  GInitable *ret;\n"
+            '  ret = g_initable_new (%sTYPE_OBJECT_MANAGER_CLIENT, cancellable, error, "flags", flags, "name", name, "connection", connection, "object-path", object_path, "get-proxy-type-func", %sobject_manager_client_get_proxy_type, NULL);\n'
+            "  if (ret != NULL)\n"
+            "    return G_DBUS_OBJECT_MANAGER (ret);\n"
+            "  else\n"
+            "    return NULL;\n"
+            "}\n"
+            "\n" % (self.ns_lower, self.ns_upper, self.ns_lower)
+        )
+        self.outfile.write("\n")
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %sobject_manager_client_new_for_bus:\n"
+                " * @bus_type: A #GBusType.\n"
+                " * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.\n"
+                " * @name: A bus name (well-known or unique).\n"
+                " * @object_path: An object path.\n"
+                " * @cancellable: (nullable): A #GCancellable or %%NULL.\n"
+                " * @callback: A #GAsyncReadyCallback to call when the request is satisfied.\n"
+                " * @user_data: User data to pass to @callback.\n"
+                " *\n"
+                " * Like %sobject_manager_client_new() but takes a #GBusType instead of a #GDBusConnection.\n"
+                " *\n"
+                " * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from (see g_main_context_push_thread_default()).\n"
+                " * You can then call %sobject_manager_client_new_for_bus_finish() to get the result of the operation.\n"
+                " *\n"
+                " * See %sobject_manager_client_new_for_bus_sync() for the synchronous, blocking version of this constructor.\n"
+                % (self.ns_lower, self.ns_lower, self.ns_lower, self.ns_lower),
+                False,
+            )
+        )
+        self.outfile.write(" */\n")
+        self.outfile.write(
+            "void\n"
+            "%sobject_manager_client_new_for_bus (\n"
+            "    GBusType                bus_type,\n"
+            "    GDBusObjectManagerClientFlags  flags,\n"
+            "    const gchar            *name,\n"
+            "    const gchar            *object_path,\n"
+            "    GCancellable           *cancellable,\n"
+            "    GAsyncReadyCallback     callback,\n"
+            "    gpointer                user_data)\n"
+            "{\n"
+            '  g_async_initable_new_async (%sTYPE_OBJECT_MANAGER_CLIENT, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "flags", flags, "name", name, "bus-type", bus_type, "object-path", object_path, "get-proxy-type-func", %sobject_manager_client_get_proxy_type, NULL);\n'
+            "}\n"
+            "\n" % (self.ns_lower, self.ns_upper, self.ns_lower)
+        )
+        self.outfile.write(
+            "/**\n"
+            " * %sobject_manager_client_new_for_bus_finish:\n"
+            " * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %sobject_manager_client_new_for_bus().\n"
+            " * @error: Return location for error or %%NULL\n"
+            " *\n"
+            " * Finishes an operation started with %sobject_manager_client_new_for_bus().\n"
+            " *\n"
+            " * Returns: (transfer full) (type %sObjectManagerClient): The constructed object manager client or %%NULL if @error is set.\n"
+            % (self.ns_lower, self.ns_lower, self.ns_lower, self.namespace)
+        )
+        self.outfile.write(" */\n")
+        self.outfile.write(
+            "GDBusObjectManager *\n"
+            "%sobject_manager_client_new_for_bus_finish (\n"
+            "    GAsyncResult        *res,\n"
+            "    GError             **error)\n"
+            "{\n"
+            "  GObject *ret;\n"
+            "  GObject *source_object;\n"
+            "  source_object = g_async_result_get_source_object (res);\n"
+            "  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);\n"
+            "  g_object_unref (source_object);\n"
+            "  if (ret != NULL)\n"
+            "    return G_DBUS_OBJECT_MANAGER (ret);\n"
+            "  else\n"
+            "    return NULL;\n"
+            "}\n"
+            "\n" % (self.ns_lower)
+        )
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * %sobject_manager_client_new_for_bus_sync:\n"
+                " * @bus_type: A #GBusType.\n"
+                " * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.\n"
+                " * @name: A bus name (well-known or unique).\n"
+                " * @object_path: An object path.\n"
+                " * @cancellable: (nullable): A #GCancellable or %%NULL.\n"
+                " * @error: Return location for error or %%NULL\n"
+                " *\n"
+                " * Like %sobject_manager_client_new_sync() but takes a #GBusType instead of a #GDBusConnection.\n"
+                " *\n"
+                " * The calling thread is blocked until a reply is received.\n"
+                " *\n"
+                " * See %sobject_manager_client_new_for_bus() for the asynchronous version of this constructor.\n"
+                " *\n"
+                " * Returns: (transfer full) (type %sObjectManagerClient): The constructed object manager client or %%NULL if @error is set.\n"
+                % (self.ns_lower, self.ns_lower, self.ns_lower, self.namespace),
+                False,
+            )
+        )
+        self.outfile.write(" */\n")
+        self.outfile.write(
+            "GDBusObjectManager *\n"
+            "%sobject_manager_client_new_for_bus_sync (\n"
+            "    GBusType                bus_type,\n"
+            "    GDBusObjectManagerClientFlags  flags,\n"
+            "    const gchar            *name,\n"
+            "    const gchar            *object_path,\n"
+            "    GCancellable           *cancellable,\n"
+            "    GError                **error)\n"
+            "{\n"
+            "  GInitable *ret;\n"
+            '  ret = g_initable_new (%sTYPE_OBJECT_MANAGER_CLIENT, cancellable, error, "flags", flags, "name", name, "bus-type", bus_type, "object-path", object_path, "get-proxy-type-func", %sobject_manager_client_get_proxy_type, NULL);\n'
+            "  if (ret != NULL)\n"
+            "    return G_DBUS_OBJECT_MANAGER (ret);\n"
+            "  else\n"
+            "    return NULL;\n"
+            "}\n"
+            "\n" % (self.ns_lower, self.ns_upper, self.ns_lower)
+        )
+        self.outfile.write("\n")
 
     # ---------------------------------------------------------------------------------------------------
 
     def write_gtkdoc_deprecated_and_since_and_close(self, obj, f, indent):
         if len(obj.since) > 0:
-            f.write('%*s *\n'
-                    '%*s * Since: %s\n'
-                    %(indent, '', indent, '', obj.since))
+            f.write("%*s *\n" "%*s * Since: %s\n" % (indent, "", indent, "", obj.since))
         if obj.deprecated:
             if isinstance(obj, dbustypes.Interface):
-                thing = 'The D-Bus interface'
+                thing = "The D-Bus interface"
             elif isinstance(obj, dbustypes.Method):
-                thing = 'The D-Bus method'
+                thing = "The D-Bus method"
             elif isinstance(obj, dbustypes.Signal):
-                thing = 'The D-Bus signal'
+                thing = "The D-Bus signal"
             elif isinstance(obj, dbustypes.Property):
-                thing = 'The D-Bus property'
+                thing = "The D-Bus property"
             else:
                 print_error('Cannot handle object "{}"'.format(obj))
-            f.write(self.docbook_gen.expand(
-                    '%*s *\n'
-                    '%*s * Deprecated: %s has been deprecated.\n'
-                    %(indent, '', indent, '', thing), False))
-        f.write('%*s */\n'%(indent, ''))
+            f.write(
+                self.docbook_gen.expand(
+                    "%*s *\n"
+                    "%*s * Deprecated: %s has been deprecated.\n"
+                    % (indent, "", indent, "", thing),
+                    False,
+                )
+            )
+        f.write("%*s */\n" % (indent, ""))
 
     # ---------------------------------------------------------------------------------------------------
 
     def generate_interface_intro(self, i):
-        self.outfile.write('/* ------------------------------------------------------------------------\n'
-                           ' * Code for interface %s\n'
-                           ' * ------------------------------------------------------------------------\n'
-                           ' */\n'
-                           '\n'%(i.name))
-
-        self.outfile.write(self.docbook_gen.expand(
-                '/**\n'
-                ' * SECTION:%s\n'
-                ' * @title: %s\n'
-                ' * @short_description: Generated C code for the %s D-Bus interface\n'
-                ' *\n'
-                ' * This section contains code for working with the #%s D-Bus interface in C.\n'
-                ' */\n'
-                %(i.camel_name, i.camel_name, i.name, i.name), False))
-        self.outfile.write('\n')
+        self.outfile.write(
+            "/* ------------------------------------------------------------------------\n"
+            " * Code for interface %s\n"
+            " * ------------------------------------------------------------------------\n"
+            " */\n"
+            "\n" % (i.name)
+        )
+
+        self.outfile.write(
+            self.docbook_gen.expand(
+                "/**\n"
+                " * SECTION:%s\n"
+                " * @title: %s\n"
+                " * @short_description: Generated C code for the %s D-Bus interface\n"
+                " *\n"
+                " * This section contains code for working with the #%s D-Bus interface in C.\n"
+                " */\n" % (i.camel_name, i.camel_name, i.name, i.name),
+                False,
+            )
+        )
+        self.outfile.write("\n")
 
     def generate(self):
         self.generate_body_preamble()
index c08aa1a..4b69e29 100644 (file)
 #
 # Author: David Zeuthen <davidz@redhat.com>
 
-import sys
 import re
 from os import path
 
-from . import config
 from . import utils
-from . import dbustypes
-from . import parser
+
+
+# Disable line length warnings as wrapping the Docbook templates would be hard
+# flake8: noqa: E501
+
 
 # ----------------------------------------------------------------------------------------------------
 
+
 class DocbookCodeGenerator:
     def __init__(self, ifaces):
         self.ifaces = ifaces
@@ -57,23 +59,36 @@ class DocbookCodeGenerator:
                 max_signature_len = max(len(a.signature), max_signature_len)
 
         if in_synopsis:
-            self.out.write('<link linkend="gdbus-method-%s.%s">%s</link>%*s ('
-                           %(utils.dots_to_hyphens(i.name), m.name, m.name, max_method_len - len(m.name), ''))
+            self.out.write(
+                '<link linkend="gdbus-method-%s.%s">%s</link>%*s ('
+                % (
+                    utils.dots_to_hyphens(i.name),
+                    m.name,
+                    m.name,
+                    max_method_len - len(m.name),
+                    "",
+                )
+            )
         else:
-            self.out.write('%s%*s ('
-                           %(m.name, max_method_len - len(m.name), ''))
+            self.out.write("%s%*s (" % (m.name, max_method_len - len(m.name), ""))
         count = 0
         for a in m.in_args:
-            if (count > 0):
-                self.out.write(',\n%*s'%(max_method_len + 2, ''))
-            self.out.write('IN  %s%*s %s'%(a.signature, max_signature_len - len(a.signature), '', a.name))
+            if count > 0:
+                self.out.write(",\n%*s" % (max_method_len + 2, ""))
+            self.out.write(
+                "IN  %s%*s %s"
+                % (a.signature, max_signature_len - len(a.signature), "", a.name)
+            )
             count = count + 1
         for a in m.out_args:
-            if (count > 0):
-                self.out.write(',\n%*s'%(max_method_len + 2, ''))
-            self.out.write('OUT %s%*s %s'%(a.signature, max_signature_len - len(a.signature), '', a.name))
+            if count > 0:
+                self.out.write(",\n%*s" % (max_method_len + 2, ""))
+            self.out.write(
+                "OUT %s%*s %s"
+                % (a.signature, max_signature_len - len(a.signature), "", a.name)
+            )
             count = count + 1
-        self.out.write(');\n')
+        self.out.write(");\n")
 
     def print_signal_prototype(self, i, s, in_synopsis):
         max_signal_len = 0
@@ -93,18 +108,28 @@ class DocbookCodeGenerator:
                 max_signature_len = max(len(a.signature), max_signature_len)
 
         if in_synopsis:
-            self.out.write('<link linkend="gdbus-signal-%s.%s">%s</link>%*s ('
-                           %(utils.dots_to_hyphens(i.name), s.name, s.name, max_signal_len - len(s.name), ''))
+            self.out.write(
+                '<link linkend="gdbus-signal-%s.%s">%s</link>%*s ('
+                % (
+                    utils.dots_to_hyphens(i.name),
+                    s.name,
+                    s.name,
+                    max_signal_len - len(s.name),
+                    "",
+                )
+            )
         else:
-            self.out.write('%s%*s ('
-                           %(s.name, max_signal_len - len(s.name), ''))
+            self.out.write("%s%*s (" % (s.name, max_signal_len - len(s.name), ""))
         count = 0
         for a in s.args:
-            if (count > 0):
-                self.out.write(',\n%*s'%(max_signal_len + 2, ''))
-            self.out.write('%s%*s %s'%(a.signature, max_signature_len - len(a.signature), '', a.name))
+            if count > 0:
+                self.out.write(",\n%*s" % (max_signal_len + 2, ""))
+            self.out.write(
+                "%s%*s %s"
+                % (a.signature, max_signature_len - len(a.signature), "", a.name)
+            )
             count = count + 1
-        self.out.write(');\n')
+        self.out.write(");\n")
 
     def print_property_prototype(self, i, p, in_synopsis):
         max_property_len = 0
@@ -122,109 +147,181 @@ class DocbookCodeGenerator:
             max_signature_len = max(len(p.signature), max_signature_len)
 
         if in_synopsis:
-            self.out.write('<link linkend="gdbus-property-%s.%s">%s</link>%*s'
-                           %(utils.dots_to_hyphens(i.name), p.name, p.name, max_property_len - len(p.name), ''))
+            self.out.write(
+                '<link linkend="gdbus-property-%s.%s">%s</link>%*s'
+                % (
+                    utils.dots_to_hyphens(i.name),
+                    p.name,
+                    p.name,
+                    max_property_len - len(p.name),
+                    "",
+                )
+            )
         else:
-            self.out.write('%s%*s'
-                           %(p.name, max_property_len - len(p.name), ''))
+            self.out.write("%s%*s" % (p.name, max_property_len - len(p.name), ""))
         if p.readable and p.writable:
-            access = 'readwrite'
+            access = "readwrite"
         elif p.readable:
-            access = 'readable '
+            access = "readable "
         else:
-            access = 'writable '
-        self.out.write('  %s  %s\n'%(access, p.signature))
-
+            access = "writable "
+        self.out.write("  %s  %s\n" % (access, p.signature))
 
     def print_synopsis_methods(self, i):
-        self.out.write('  <refsynopsisdiv role="synopsis">\n'%())
-        self.out.write('    <title role="synopsis.title">Methods</title>\n'%())
-        self.out.write('    <synopsis>\n'%())
+        self.out.write('  <refsynopsisdiv role="synopsis">\n')
+        self.out.write('    <title role="synopsis.title">Methods</title>\n')
+        self.out.write("    <synopsis>\n")
         for m in i.methods:
             self.print_method_prototype(i, m, in_synopsis=True)
-        self.out.write('</synopsis>\n'%())
-        self.out.write('  </refsynopsisdiv>\n'%())
+        self.out.write("</synopsis>\n")
+        self.out.write("  </refsynopsisdiv>\n")
 
     def print_synopsis_signals(self, i):
-        self.out.write('  <refsect1 role="signal_proto">\n'%())
-        self.out.write('    <title role="signal_proto.title">Signals</title>\n'%())
-        self.out.write('    <synopsis>\n'%())
+        self.out.write('  <refsect1 role="signal_proto">\n')
+        self.out.write('    <title role="signal_proto.title">Signals</title>\n')
+        self.out.write("    <synopsis>\n")
         for s in i.signals:
             self.print_signal_prototype(i, s, in_synopsis=True)
-        self.out.write('</synopsis>\n'%())
-        self.out.write('  </refsect1>\n'%())
+        self.out.write("</synopsis>\n")
+        self.out.write("  </refsect1>\n")
 
     def print_synopsis_properties(self, i):
-        self.out.write('  <refsect1 role="properties">\n'%())
-        self.out.write('    <title role="properties.title">Properties</title>\n'%())
-        self.out.write('    <synopsis>\n'%())
+        self.out.write('  <refsect1 role="properties">\n')
+        self.out.write('    <title role="properties.title">Properties</title>\n')
+        self.out.write("    <synopsis>\n")
         for p in i.properties:
             self.print_property_prototype(i, p, in_synopsis=True)
-        self.out.write('</synopsis>\n'%())
-        self.out.write('  </refsect1>\n'%())
+        self.out.write("</synopsis>\n")
+        self.out.write("  </refsect1>\n")
 
     def print_method(self, i, m):
-        self.out.write('<refsect2 role="method" id="gdbus-method-%s.%s">\n'%(utils.dots_to_hyphens(i.name), m.name))
-        self.out.write('  <title>The %s() method</title>\n'%(m.name))
-        self.out.write('  <indexterm zone="gdbus-method-%s.%s"><primary sortas="%s.%s">%s.%s()</primary></indexterm>\n'%(utils.dots_to_hyphens(i.name), m.name, i.name_without_prefix, m.name, i.name, m.name))
-        self.out.write('<programlisting>\n')
+        self.out.write(
+            '<refsect2 role="method" id="gdbus-method-%s.%s">\n'
+            % (utils.dots_to_hyphens(i.name), m.name)
+        )
+        self.out.write("  <title>The %s() method</title>\n" % (m.name))
+        self.out.write(
+            '  <indexterm zone="gdbus-method-%s.%s"><primary sortas="%s.%s">%s.%s()</primary></indexterm>\n'
+            % (
+                utils.dots_to_hyphens(i.name),
+                m.name,
+                i.name_without_prefix,
+                m.name,
+                i.name,
+                m.name,
+            )
+        )
+        self.out.write("<programlisting>\n")
         self.print_method_prototype(i, m, in_synopsis=False)
-        self.out.write('</programlisting>\n')
-        self.out.write('%s\n'%(self.expand_paras(m.doc_string, True)))
+        self.out.write("</programlisting>\n")
+        self.out.write("%s\n" % (self.expand_paras(m.doc_string, True)))
         if m.in_args or m.out_args:
             self.out.write('<variablelist role="params">\n')
             for a in m.in_args:
-                self.out.write('<varlistentry>\n'%())
-                self.out.write('  <term><literal>IN %s <parameter>%s</parameter></literal>:</term>\n'%(a.signature, a.name))
-                self.out.write('  <listitem>%s</listitem>\n'%(self.expand_paras(a.doc_string, True)))
-                self.out.write('</varlistentry>\n'%())
+                self.out.write("<varlistentry>\n")
+                self.out.write(
+                    "  <term><literal>IN %s <parameter>%s</parameter></literal>:</term>\n"
+                    % (a.signature, a.name)
+                )
+                self.out.write(
+                    "  <listitem>%s</listitem>\n"
+                    % (self.expand_paras(a.doc_string, True))
+                )
+                self.out.write("</varlistentry>\n")
             for a in m.out_args:
-                self.out.write('<varlistentry>\n'%())
-                self.out.write('  <term><literal>OUT %s <parameter>%s</parameter></literal>:</term>\n'%(a.signature, a.name))
-                self.out.write('  <listitem>%s</listitem>\n'%(self.expand_paras(a.doc_string, True)))
-                self.out.write('</varlistentry>\n'%())
-            self.out.write('</variablelist>\n')
+                self.out.write("<varlistentry>\n")
+                self.out.write(
+                    "  <term><literal>OUT %s <parameter>%s</parameter></literal>:</term>\n"
+                    % (a.signature, a.name)
+                )
+                self.out.write(
+                    "  <listitem>%s</listitem>\n"
+                    % (self.expand_paras(a.doc_string, True))
+                )
+                self.out.write("</varlistentry>\n")
+            self.out.write("</variablelist>\n")
         if len(m.since) > 0:
-            self.out.write('<para role="since">Since %s</para>\n'%(m.since))
+            self.out.write('<para role="since">Since %s</para>\n' % (m.since))
         if m.deprecated:
-            self.out.write('<warning><para>The %s() method is deprecated.</para></warning>'%(m.name))
-        self.out.write('</refsect2>\n')
+            self.out.write(
+                "<warning><para>The %s() method is deprecated.</para></warning>"
+                % (m.name)
+            )
+        self.out.write("</refsect2>\n")
 
     def print_signal(self, i, s):
-        self.out.write('<refsect2 role="signal" id="gdbus-signal-%s.%s">\n'%(utils.dots_to_hyphens(i.name), s.name))
-        self.out.write('  <title>The "%s" signal</title>\n'%(s.name))
-        self.out.write('  <indexterm zone="gdbus-signal-%s.%s"><primary sortas="%s::%s">%s::%s</primary></indexterm>\n'%(utils.dots_to_hyphens(i.name), s.name, i.name_without_prefix, s.name, i.name, s.name))
-        self.out.write('<programlisting>\n')
+        self.out.write(
+            '<refsect2 role="signal" id="gdbus-signal-%s.%s">\n'
+            % (utils.dots_to_hyphens(i.name), s.name)
+        )
+        self.out.write('  <title>The "%s" signal</title>\n' % (s.name))
+        self.out.write(
+            '  <indexterm zone="gdbus-signal-%s.%s"><primary sortas="%s::%s">%s::%s</primary></indexterm>\n'
+            % (
+                utils.dots_to_hyphens(i.name),
+                s.name,
+                i.name_without_prefix,
+                s.name,
+                i.name,
+                s.name,
+            )
+        )
+        self.out.write("<programlisting>\n")
         self.print_signal_prototype(i, s, in_synopsis=False)
-        self.out.write('</programlisting>\n')
-        self.out.write('%s\n'%(self.expand_paras(s.doc_string, True)))
+        self.out.write("</programlisting>\n")
+        self.out.write("%s\n" % (self.expand_paras(s.doc_string, True)))
         if s.args:
             self.out.write('<variablelist role="params">\n')
             for a in s.args:
-                self.out.write('<varlistentry>\n'%())
-                self.out.write('  <term><literal>%s <parameter>%s</parameter></literal>:</term>\n'%(a.signature, a.name))
-                self.out.write('  <listitem>%s</listitem>\n'%(self.expand_paras(a.doc_string, True)))
-                self.out.write('</varlistentry>\n'%())
-            self.out.write('</variablelist>\n')
+                self.out.write("<varlistentry>\n")
+                self.out.write(
+                    "  <term><literal>%s <parameter>%s</parameter></literal>:</term>\n"
+                    % (a.signature, a.name)
+                )
+                self.out.write(
+                    "  <listitem>%s</listitem>\n"
+                    % (self.expand_paras(a.doc_string, True))
+                )
+                self.out.write("</varlistentry>\n")
+            self.out.write("</variablelist>\n")
         if len(s.since) > 0:
-            self.out.write('<para role="since">Since %s</para>\n'%(s.since))
+            self.out.write('<para role="since">Since %s</para>\n' % (s.since))
         if s.deprecated:
-            self.out.write('<warning><para>The "%s" signal is deprecated.</para></warning>'%(s.name))
-        self.out.write('</refsect2>\n')
+            self.out.write(
+                '<warning><para>The "%s" signal is deprecated.</para></warning>'
+                % (s.name)
+            )
+        self.out.write("</refsect2>\n")
 
     def print_property(self, i, p):
-        self.out.write('<refsect2 role="property" id="gdbus-property-%s.%s">\n'%(utils.dots_to_hyphens(i.name), p.name))
-        self.out.write('  <title>The "%s" property</title>\n'%(p.name))
-        self.out.write('  <indexterm zone="gdbus-property-%s.%s"><primary sortas="%s:%s">%s:%s</primary></indexterm>\n'%(utils.dots_to_hyphens(i.name), p.name, i.name_without_prefix, p.name, i.name, p.name))
-        self.out.write('<programlisting>\n')
+        self.out.write(
+            '<refsect2 role="property" id="gdbus-property-%s.%s">\n'
+            % (utils.dots_to_hyphens(i.name), p.name)
+        )
+        self.out.write('  <title>The "%s" property</title>\n' % (p.name))
+        self.out.write(
+            '  <indexterm zone="gdbus-property-%s.%s"><primary sortas="%s:%s">%s:%s</primary></indexterm>\n'
+            % (
+                utils.dots_to_hyphens(i.name),
+                p.name,
+                i.name_without_prefix,
+                p.name,
+                i.name,
+                p.name,
+            )
+        )
+        self.out.write("<programlisting>\n")
         self.print_property_prototype(i, p, in_synopsis=False)
-        self.out.write('</programlisting>\n')
-        self.out.write('%s\n'%(self.expand_paras(p.doc_string, True)))
+        self.out.write("</programlisting>\n")
+        self.out.write("%s\n" % (self.expand_paras(p.doc_string, True)))
         if len(p.since) > 0:
-            self.out.write('<para role="since">Since %s</para>\n'%(p.since))
+            self.out.write('<para role="since">Since %s</para>\n' % (p.since))
         if p.deprecated:
-            self.out.write('<warning><para>The "%s" property is deprecated.</para></warning>'%(p.name))
-        self.out.write('</refsect2>\n')
+            self.out.write(
+                '<warning><para>The "%s" property is deprecated.</para></warning>'
+                % (p.name)
+            )
+        self.out.write("</refsect2>\n")
 
     def expand(self, s, expandParamsAndConstants):
         for key in self.expand_member_dict_keys:
@@ -233,9 +330,17 @@ class DocbookCodeGenerator:
             s = s.replace(key, self.expand_iface_dict[key])
         if expandParamsAndConstants:
             # replace @foo with <parameter>foo</parameter>
-            s = re.sub('@[a-zA-Z0-9_]*', lambda m: '<parameter>' + m.group(0)[1:] + '</parameter>', s)
+            s = re.sub(
+                "@[a-zA-Z0-9_]*",
+                lambda m: "<parameter>" + m.group(0)[1:] + "</parameter>",
+                s,
+            )
             # replace e.g. %TRUE with <constant>TRUE</constant>
-            s = re.sub('%[a-zA-Z0-9_]*', lambda m: '<constant>' + m.group(0)[1:] + '</constant>', s)
+            s = re.sub(
+                "%[a-zA-Z0-9_]*",
+                lambda m: "<constant>" + m.group(0)[1:] + "</constant>",
+                s,
+            )
         return s
 
     def expand_paras(self, s, expandParamsAndConstants):
@@ -248,44 +353,73 @@ class DocbookCodeGenerator:
         self.expand_member_dict = {}
         self.expand_iface_dict = {}
         for i in self.ifaces:
-            key = '#%s'%(i.name)
-            value = '<link linkend="gdbus-interface-%s.top_of_page">%s</link>'%(utils.dots_to_hyphens(i.name), i.name)
+            key = "#%s" % (i.name)
+            value = '<link linkend="gdbus-interface-%s.top_of_page">%s</link>' % (
+                utils.dots_to_hyphens(i.name),
+                i.name,
+            )
             self.expand_iface_dict[key] = value
             for m in i.methods:
-                key = '%s.%s()'%(i.name, m.name)
-                value = '<link linkend="gdbus-method-%s.%s">%s()</link>'%(utils.dots_to_hyphens(i.name), m.name, m.name)
+                key = "%s.%s()" % (i.name, m.name)
+                value = '<link linkend="gdbus-method-%s.%s">%s()</link>' % (
+                    utils.dots_to_hyphens(i.name),
+                    m.name,
+                    m.name,
+                )
                 self.expand_member_dict[key] = value
             for s in i.signals:
-                key = '#%s::%s'%(i.name, s.name)
-                value = '<link linkend="gdbus-signal-%s.%s">"%s"</link>'%(utils.dots_to_hyphens(i.name), s.name, s.name)
+                key = "#%s::%s" % (i.name, s.name)
+                value = '<link linkend="gdbus-signal-%s.%s">"%s"</link>' % (
+                    utils.dots_to_hyphens(i.name),
+                    s.name,
+                    s.name,
+                )
                 self.expand_member_dict[key] = value
             for p in i.properties:
-                key = '#%s:%s'%(i.name, p.name)
-                value = '<link linkend="gdbus-property-%s.%s">"%s"</link>'%(utils.dots_to_hyphens(i.name), p.name, p.name)
+                key = "#%s:%s" % (i.name, p.name)
+                value = '<link linkend="gdbus-property-%s.%s">"%s"</link>' % (
+                    utils.dots_to_hyphens(i.name),
+                    p.name,
+                    p.name,
+                )
                 self.expand_member_dict[key] = value
         # Make sure to expand the keys in reverse order so e.g. #org.foo.Iface:MediaCompat
         # is evaluated before #org.foo.Iface:Media ...
-        self.expand_member_dict_keys = sorted(self.expand_member_dict.keys(), reverse=True)
-        self.expand_iface_dict_keys = sorted(self.expand_iface_dict.keys(), reverse=True)
+        self.expand_member_dict_keys = sorted(
+            self.expand_member_dict.keys(), reverse=True
+        )
+        self.expand_iface_dict_keys = sorted(
+            self.expand_iface_dict.keys(), reverse=True
+        )
 
     def generate(self, docbook, outdir):
         for i in self.ifaces:
-            self.out = open(path.join(outdir, '%s-%s.xml'%(docbook, i.name)), 'w')
-            self.out.write(''%())
-            self.out.write('<?xml version="1.0" encoding="utf-8"?>\n'%())
-            self.out.write('<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"\n'%())
-            self.out.write('               "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [\n'%())
-            self.out.write(']>\n'%())
-            self.out.write('<refentry id="gdbus-%s">\n'%(i.name))
-            self.out.write('  <refmeta>'%())
-            self.out.write('    <refentrytitle role="top_of_page" id="gdbus-interface-%s.top_of_page">%s</refentrytitle>\n'%(utils.dots_to_hyphens(i.name), i.name))
-            self.out.write('  <indexterm zone="gdbus-interface-%s.top_of_page"><primary sortas="%s">%s</primary></indexterm>\n'%(utils.dots_to_hyphens(i.name), i.name_without_prefix, i.name))
-            self.out.write('  </refmeta>'%())
-
-            self.out.write('  <refnamediv>'%())
-            self.out.write('    <refname>%s</refname>'%(i.name))
-            self.out.write('    <refpurpose>%s</refpurpose>'%(i.doc_string_brief))
-            self.out.write('  </refnamediv>'%())
+            self.out = open(path.join(outdir, "%s-%s.xml" % (docbook, i.name)), "w")
+            self.out.write("")
+            self.out.write('<?xml version="1.0" encoding="utf-8"?>\n')
+            self.out.write(
+                '<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"\n'
+            )
+            self.out.write(
+                '               "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [\n'
+            )
+            self.out.write("]>\n")
+            self.out.write('<refentry id="gdbus-%s">\n' % (i.name))
+            self.out.write("  <refmeta>")
+            self.out.write(
+                '    <refentrytitle role="top_of_page" id="gdbus-interface-%s.top_of_page">%s</refentrytitle>\n'
+                % (utils.dots_to_hyphens(i.name), i.name)
+            )
+            self.out.write(
+                '  <indexterm zone="gdbus-interface-%s.top_of_page"><primary sortas="%s">%s</primary></indexterm>\n'
+                % (utils.dots_to_hyphens(i.name), i.name_without_prefix, i.name)
+            )
+            self.out.write("  </refmeta>")
+
+            self.out.write("  <refnamediv>")
+            self.out.write("    <refname>%s</refname>" % (i.name))
+            self.out.write("    <refpurpose>%s</refpurpose>" % (i.doc_string_brief))
+            self.out.write("  </refnamediv>")
 
             if len(i.methods) > 0:
                 self.print_synopsis_methods(i)
@@ -294,36 +428,49 @@ class DocbookCodeGenerator:
             if len(i.properties) > 0:
                 self.print_synopsis_properties(i)
 
-            self.out.write('<refsect1 role="desc" id="gdbus-interface-%s">\n'%(utils.dots_to_hyphens(i.name)))
-            self.out.write('  <title role="desc.title">Description</title>\n'%())
-            self.out.write('  %s\n'%(self.expand_paras(i.doc_string, True)))
+            self.out.write(
+                '<refsect1 role="desc" id="gdbus-interface-%s">\n'
+                % (utils.dots_to_hyphens(i.name))
+            )
+            self.out.write('  <title role="desc.title">Description</title>\n')
+            self.out.write("  %s\n" % (self.expand_paras(i.doc_string, True)))
             if len(i.since) > 0:
-                self.out.write('  <para role="since">Since %s</para>\n'%(i.since))
+                self.out.write('  <para role="since">Since %s</para>\n' % (i.since))
             if i.deprecated:
-                self.out.write('<warning><para>The %s interface is deprecated.</para></warning>'%(i.name))
-            self.out.write('</refsect1>\n'%())
+                self.out.write(
+                    "<warning><para>The %s interface is deprecated.</para></warning>"
+                    % (i.name)
+                )
+            self.out.write("</refsect1>\n")
 
             if len(i.methods) > 0:
-                self.out.write('<refsect1 role="details" id="gdbus-methods-%s">\n'%(i.name))
-                self.out.write('  <title role="details.title">Method Details</title>\n'%())
+                self.out.write(
+                    '<refsect1 role="details" id="gdbus-methods-%s">\n' % (i.name)
+                )
+                self.out.write('  <title role="details.title">Method Details</title>\n')
                 for m in i.methods:
                     self.print_method(i, m)
-                self.out.write('</refsect1>\n'%())
+                self.out.write("</refsect1>\n")
 
             if len(i.signals) > 0:
-                self.out.write('<refsect1 role="details" id="gdbus-signals-%s">\n'%(i.name))
-                self.out.write('  <title role="details.title">Signal Details</title>\n'%())
+                self.out.write(
+                    '<refsect1 role="details" id="gdbus-signals-%s">\n' % (i.name)
+                )
+                self.out.write('  <title role="details.title">Signal Details</title>\n')
                 for s in i.signals:
                     self.print_signal(i, s)
-                self.out.write('</refsect1>\n'%())
+                self.out.write("</refsect1>\n")
 
             if len(i.properties) > 0:
-                self.out.write('<refsect1 role="details" id="gdbus-properties-%s">\n'%(i.name))
-                self.out.write('  <title role="details.title">Property Details</title>\n'%())
+                self.out.write(
+                    '<refsect1 role="details" id="gdbus-properties-%s">\n' % (i.name)
+                )
+                self.out.write(
+                    '  <title role="details.title">Property Details</title>\n'
+                )
                 for s in i.properties:
                     self.print_property(i, s)
-                self.out.write('</refsect1>\n'%())
-
-            self.out.write('</refentry>\n')
-            self.out.write('\n')
+                self.out.write("</refsect1>\n")
 
+            self.out.write("</refentry>\n")
+            self.out.write("\n")
index bd7fef5..dc0177f 100644 (file)
@@ -32,30 +32,35 @@ from . import codegen
 from . import codegen_docbook
 from .utils import print_error, print_warning
 
+
 def find_arg(arg_list, arg_name):
     for a in arg_list:
         if a.name == arg_name:
             return a
     return None
 
+
 def find_method(iface, method):
     for m in iface.methods:
         if m.name == method:
             return m
     return None
 
+
 def find_signal(iface, signal):
     for m in iface.signals:
         if m.name == signal:
             return m
     return None
 
+
 def find_prop(iface, prop):
     for m in iface.properties:
         if m.name == prop:
             return m
     return None
 
+
 def apply_annotation(iface_list, iface, method, signal, prop, arg, key, value):
     iface_obj = None
     for i in iface_list:
@@ -74,10 +79,14 @@ def apply_annotation(iface_list, iface, method, signal, prop, arg, key, value):
             print_error('No method "{}" on interface "{}"'.format(method, iface))
         if arg:
             arg_obj = find_arg(method_obj.in_args, arg)
-            if (arg_obj is None):
+            if arg_obj is None:
                 arg_obj = find_arg(method_obj.out_args, arg)
-                if (arg_obj is None):
-                    print_error('No arg "{}" on method "{}" on interface "{}"'.format(arg, method, iface))
+                if arg_obj is None:
+                    print_error(
+                        'No arg "{}" on method "{}" on interface "{}"'.format(
+                            arg, method, iface
+                        )
+                    )
             target_obj = arg_obj
         else:
             target_obj = method_obj
@@ -87,8 +96,12 @@ def apply_annotation(iface_list, iface, method, signal, prop, arg, key, value):
             print_error('No signal "{}" on interface "{}"'.format(signal, iface))
         if arg:
             arg_obj = find_arg(signal_obj.args, arg)
-            if (arg_obj is None):
-                print_error('No arg "{}" on signal "{}" on interface "{}"'.format(arg, signal, iface))
+            if arg_obj is None:
+                print_error(
+                    'No arg "{}" on signal "{}" on interface "{}"'.format(
+                        arg, signal, iface
+                    )
+                )
             target_obj = arg_obj
         else:
             target_obj = signal_obj
@@ -105,198 +118,294 @@ def apply_annotation(iface_list, iface, method, signal, prop, arg, key, value):
 def apply_annotations(iface_list, annotation_list):
     # apply annotations given on the command line
     for (what, key, value) in annotation_list:
-        pos = what.find('::')
+        pos = what.find("::")
         if pos != -1:
             # signal
-            iface = what[0:pos];
-            signal = what[pos + 2:]
-            pos = signal.find('[')
+            iface = what[0:pos]
+            signal = what[pos + 2 :]
+            pos = signal.find("[")
             if pos != -1:
-                arg = signal[pos + 1:]
+                arg = signal[pos + 1 :]
                 signal = signal[0:pos]
-                pos = arg.find(']')
+                pos = arg.find("]")
                 arg = arg[0:pos]
                 apply_annotation(iface_list, iface, None, signal, None, arg, key, value)
             else:
-                apply_annotation(iface_list, iface, None, signal, None, None, key, value)
+                apply_annotation(
+                    iface_list, iface, None, signal, None, None, key, value
+                )
         else:
-            pos = what.find(':')
+            pos = what.find(":")
             if pos != -1:
                 # property
-                iface = what[0:pos];
-                prop = what[pos + 1:]
+                iface = what[0:pos]
+                prop = what[pos + 1 :]
                 apply_annotation(iface_list, iface, None, None, prop, None, key, value)
             else:
-                pos = what.find('()')
+                pos = what.find("()")
                 if pos != -1:
                     # method
                     combined = what[0:pos]
-                    pos = combined.rfind('.')
+                    pos = combined.rfind(".")
                     iface = combined[0:pos]
-                    method = combined[pos + 1:]
-                    pos = what.find('[')
+                    method = combined[pos + 1 :]
+                    pos = what.find("[")
                     if pos != -1:
-                        arg = what[pos + 1:]
-                        pos = arg.find(']')
+                        arg = what[pos + 1 :]
+                        pos = arg.find("]")
                         arg = arg[0:pos]
-                        apply_annotation(iface_list, iface, method, None, None, arg, key, value)
+                        apply_annotation(
+                            iface_list, iface, method, None, None, arg, key, value
+                        )
                     else:
-                        apply_annotation(iface_list, iface, method, None, None, None, key, value)
+                        apply_annotation(
+                            iface_list, iface, method, None, None, None, key, value
+                        )
                 else:
                     # must be an interface
                     iface = what
-                    apply_annotation(iface_list, iface, None, None, None, None, key, value)
+                    apply_annotation(
+                        iface_list, iface, None, None, None, None, key, value
+                    )
+
 
 def codegen_main():
-    arg_parser = argparse.ArgumentParser(description='D-Bus code and documentation generator')
-    arg_parser.add_argument('files', metavar='FILE', nargs='+',
-                            help='D-Bus introspection XML file')
-    arg_parser.add_argument('--xml-files', metavar='FILE', action='append', default=[],
-                            help=argparse.SUPPRESS)
-    arg_parser.add_argument('--interface-prefix', metavar='PREFIX', default='',
-                            help='String to strip from D-Bus interface names for code and docs')
-    arg_parser.add_argument('--c-namespace', metavar='NAMESPACE', default='',
-                            help='The namespace to use for generated C code')
-    arg_parser.add_argument('--c-generate-object-manager', action='store_true',
-                            help='Generate a GDBusObjectManagerClient subclass when generating C code')
-    arg_parser.add_argument('--c-generate-autocleanup', choices=['none', 'objects', 'all'], default='objects',
-                            help='Generate autocleanup support')
-    arg_parser.add_argument('--generate-docbook', metavar='OUTFILES',
-                            help='Generate Docbook in OUTFILES-org.Project.IFace.xml')
-    arg_parser.add_argument('--pragma-once', action='store_true',
-                            help='Use "pragma once" as the inclusion guard')
-    arg_parser.add_argument('--annotate', nargs=3, action='append', metavar='WHAT KEY VALUE',
-                            help='Add annotation (may be used several times)')
-    arg_parser.add_argument('--glib-min-required', metavar='VERSION',
-                            help='Minimum version of GLib to be supported by the outputted code (default: 2.30)')
-    arg_parser.add_argument('--glib-max-allowed', metavar='VERSION',
-                            help='Maximum version of GLib to be used by the outputted code (default: current GLib version)')
-    arg_parser.add_argument('--symbol-decorator',
-                            help='Macro used to decorate a symbol in the outputted header, possibly to export symbols')
-    arg_parser.add_argument('--symbol-decorator-header',
-                            help='Additional header required for decorator specified by --symbol-decorator')
-    arg_parser.add_argument('--symbol-decorator-define',
-                            help='Additional define required for decorator specified by --symbol-decorator')
+    arg_parser = argparse.ArgumentParser(
+        description="D-Bus code and documentation generator"
+    )
+    arg_parser.add_argument(
+        "files", metavar="FILE", nargs="+", help="D-Bus introspection XML file"
+    )
+    arg_parser.add_argument(
+        "--xml-files",
+        metavar="FILE",
+        action="append",
+        default=[],
+        help=argparse.SUPPRESS,
+    )
+    arg_parser.add_argument(
+        "--interface-prefix",
+        metavar="PREFIX",
+        default="",
+        help="String to strip from D-Bus interface names for code and docs",
+    )
+    arg_parser.add_argument(
+        "--c-namespace",
+        metavar="NAMESPACE",
+        default="",
+        help="The namespace to use for generated C code",
+    )
+    arg_parser.add_argument(
+        "--c-generate-object-manager",
+        action="store_true",
+        help="Generate a GDBusObjectManagerClient subclass when generating C code",
+    )
+    arg_parser.add_argument(
+        "--c-generate-autocleanup",
+        choices=["none", "objects", "all"],
+        default="objects",
+        help="Generate autocleanup support",
+    )
+    arg_parser.add_argument(
+        "--generate-docbook",
+        metavar="OUTFILES",
+        help="Generate Docbook in OUTFILES-org.Project.IFace.xml",
+    )
+    arg_parser.add_argument(
+        "--pragma-once",
+        action="store_true",
+        help='Use "pragma once" as the inclusion guard',
+    )
+    arg_parser.add_argument(
+        "--annotate",
+        nargs=3,
+        action="append",
+        metavar="WHAT KEY VALUE",
+        help="Add annotation (may be used several times)",
+    )
+    arg_parser.add_argument(
+        "--glib-min-required",
+        metavar="VERSION",
+        help="Minimum version of GLib to be supported by the outputted code "
+        "(default: 2.30)",
+    )
+    arg_parser.add_argument(
+        "--glib-max-allowed",
+        metavar="VERSION",
+        help="Maximum version of GLib to be used by the outputted code "
+        "(default: current GLib version)",
+    )
+    arg_parser.add_argument(
+        "--symbol-decorator",
+        help="Macro used to decorate a symbol in the outputted header, "
+        "possibly to export symbols",
+    )
+    arg_parser.add_argument(
+        "--symbol-decorator-header",
+        help="Additional header required for decorator specified by "
+        "--symbol-decorator",
+    )
+    arg_parser.add_argument(
+        "--symbol-decorator-define",
+        help="Additional define required for decorator specified by "
+        "--symbol-decorator",
+    )
 
     group = arg_parser.add_mutually_exclusive_group()
-    group.add_argument('--generate-c-code', metavar='OUTFILES',
-                       help='Generate C code in OUTFILES.[ch]')
-    group.add_argument('--header', action='store_true',
-                       help='Generate C headers')
-    group.add_argument('--body', action='store_true',
-                       help='Generate C code')
-    group.add_argument('--interface-info-header', action='store_true',
-                       help='Generate GDBusInterfaceInfo C header')
-    group.add_argument('--interface-info-body', action='store_true',
-                       help='Generate GDBusInterfaceInfo C code')
+    group.add_argument(
+        "--generate-c-code", metavar="OUTFILES", help="Generate C code in OUTFILES.[ch]"
+    )
+    group.add_argument("--header", action="store_true", help="Generate C headers")
+    group.add_argument("--body", action="store_true", help="Generate C code")
+    group.add_argument(
+        "--interface-info-header",
+        action="store_true",
+        help="Generate GDBusInterfaceInfo C header",
+    )
+    group.add_argument(
+        "--interface-info-body",
+        action="store_true",
+        help="Generate GDBusInterfaceInfo C code",
+    )
 
     group = arg_parser.add_mutually_exclusive_group()
-    group.add_argument('--output', metavar='FILE',
-                       help='Write output into the specified file')
-    group.add_argument('--output-directory', metavar='OUTDIR', default='',
-                       help='Location to output generated files')
-
-    args = arg_parser.parse_args();
+    group.add_argument(
+        "--output", metavar="FILE", help="Write output into the specified file"
+    )
+    group.add_argument(
+        "--output-directory",
+        metavar="OUTDIR",
+        default="",
+        help="Location to output generated files",
+    )
+
+    args = arg_parser.parse_args()
 
     if len(args.xml_files) > 0:
-        print_warning('The "--xml-files" option is deprecated; use positional arguments instead')
-
-    if ((args.generate_c_code is not None or args.generate_docbook is not None) and
-            args.output is not None):
-        print_error('Using --generate-c-code or --generate-docbook and '
-                    '--output at the same time is not allowed')
+        print_warning(
+            'The "--xml-files" option is deprecated; use positional arguments instead'
+        )
+
+    if (
+        args.generate_c_code is not None or args.generate_docbook is not None
+    ) and args.output is not None:
+        print_error(
+            "Using --generate-c-code or --generate-docbook and "
+            "--output at the same time is not allowed"
+        )
 
     if args.generate_c_code:
-        header_name = args.generate_c_code + '.h'
+        header_name = args.generate_c_code + ".h"
         h_file = os.path.join(args.output_directory, header_name)
         args.header = True
-        c_file = os.path.join(args.output_directory, args.generate_c_code + '.c')
+        c_file = os.path.join(args.output_directory, args.generate_c_code + ".c")
         args.body = True
     elif args.header:
         if args.output is None:
-            print_error('Using --header requires --output')
+            print_error("Using --header requires --output")
 
         h_file = args.output
         header_name = os.path.basename(h_file)
     elif args.body:
         if args.output is None:
-            print_error('Using --body requires --output')
+            print_error("Using --body requires --output")
 
         c_file = args.output
-        header_name = os.path.splitext(os.path.basename(c_file))[0] + '.h'
+        header_name = os.path.splitext(os.path.basename(c_file))[0] + ".h"
     elif args.interface_info_header:
         if args.output is None:
-            print_error('Using --interface-info-header requires --output')
+            print_error("Using --interface-info-header requires --output")
         if args.c_generate_object_manager:
-            print_error('--c-generate-object-manager is incompatible with '
-                        '--interface-info-header')
+            print_error(
+                "--c-generate-object-manager is incompatible with "
+                "--interface-info-header"
+            )
 
         h_file = args.output
         header_name = os.path.basename(h_file)
     elif args.interface_info_body:
         if args.output is None:
-            print_error('Using --interface-info-body requires --output')
+            print_error("Using --interface-info-body requires --output")
         if args.c_generate_object_manager:
-            print_error('--c-generate-object-manager is incompatible with '
-                        '--interface-info-body')
+            print_error(
+                "--c-generate-object-manager is incompatible with "
+                "--interface-info-body"
+            )
 
         c_file = args.output
-        header_name = os.path.splitext(os.path.basename(c_file))[0] + '.h'
+        header_name = os.path.splitext(os.path.basename(c_file))[0] + ".h"
 
     # Check the minimum GLib version. The minimum --glib-min-required is 2.30,
     # because that’s when gdbus-codegen was introduced. Support 1, 2 or 3
     # component versions, but ignore the micro component if it’s present.
     if args.glib_min_required:
         try:
-            parts = args.glib_min_required.split('.', 3)
-            glib_min_required = (int(parts[0]),
-                                 int(parts[1] if len(parts) > 1 else 0))
+            parts = args.glib_min_required.split(".", 3)
+            glib_min_required = (int(parts[0]), int(parts[1] if len(parts) > 1 else 0))
             # Ignore micro component, but still validate it:
             _ = int(parts[2] if len(parts) > 2 else 0)
         except (ValueError, IndexError):
-            print_error('Unrecognized --glib-min-required string ‘{}’'.format(
-                args.glib_min_required))
+            print_error(
+                "Unrecognized --glib-min-required string ‘{}’".format(
+                    args.glib_min_required
+                )
+            )
 
         if glib_min_required < (2, 30):
-            print_error('Invalid --glib-min-required string ‘{}’: minimum '
-                        'version is 2.30'.format(args.glib_min_required))
+            print_error(
+                "Invalid --glib-min-required string ‘{}’: minimum "
+                "version is 2.30".format(args.glib_min_required)
+            )
     else:
         glib_min_required = (2, 30)
 
     # And the maximum GLib version.
     if args.glib_max_allowed:
         try:
-            parts = args.glib_max_allowed.split('.', 3)
-            glib_max_allowed = (int(parts[0]),
-                                int(parts[1] if len(parts) > 1 else 0))
+            parts = args.glib_max_allowed.split(".", 3)
+            glib_max_allowed = (int(parts[0]), int(parts[1] if len(parts) > 1 else 0))
             # Ignore micro component, but still validate it:
             _ = int(parts[2] if len(parts) > 2 else 0)
         except (ValueError, IndexError):
-            print_error('Unrecognized --glib-max-allowed string ‘{}’'.format(
-                args.glib_max_allowed))
+            print_error(
+                "Unrecognized --glib-max-allowed string ‘{}’".format(
+                    args.glib_max_allowed
+                )
+            )
     else:
         glib_max_allowed = (config.MAJOR_VERSION, config.MINOR_VERSION)
 
-    # Only allow --symbol-decorator-define and --symbol-decorator-header if --symbol-decorator is used
+    # Only allow --symbol-decorator-define and --symbol-decorator-header if
+    # --symbol-decorator is used
     if args.symbol_decorator is None:
         if args.symbol_decorator_header or args.symbol_decorator_define:
-            print_error('--symbol-decorator-define and --symbol-decorator-header must be used with --symbol-decorator')
+            print_error(
+                "--symbol-decorator-define and --symbol-decorator-header must "
+                "be used with --symbol-decorator"
+            )
 
     # Round --glib-max-allowed up to the next stable release.
-    glib_max_allowed = \
-        (glib_max_allowed[0], glib_max_allowed[1] + (glib_max_allowed[1] % 2))
+    glib_max_allowed = (
+        glib_max_allowed[0],
+        glib_max_allowed[1] + (glib_max_allowed[1] % 2),
+    )
 
     if glib_max_allowed < glib_min_required:
-        print_error('Invalid versions: --glib-min-required ({}) must be '
-                    'less than or equal to --glib-max-allowed ({})'.format(glib_min_required, glib_max_allowed))
+        print_error(
+            "Invalid versions: --glib-min-required ({}) must be "
+            "less than or equal to --glib-max-allowed ({})".format(
+                glib_min_required, glib_max_allowed
+            )
+        )
 
     all_ifaces = []
     input_files_basenames = []
     for fname in sorted(args.files + args.xml_files):
-        with open(fname, 'rb') as f:
+        with open(fname, "rb") as f:
             xml_data = f.read()
-        parsed_ifaces = parser.parse_dbus_xml(xml_data,
-                                              h_type_implies_unix_fd=(glib_min_required >= (2, 64)))
+        parsed_ifaces = parser.parse_dbus_xml(
+            xml_data, h_type_implies_unix_fd=(glib_min_required >= (2, 64))
+        )
         all_ifaces.extend(parsed_ifaces)
         input_files_basenames.append(os.path.basename(fname))
 
@@ -307,63 +416,72 @@ def codegen_main():
         i.post_process(args.interface_prefix, args.c_namespace)
 
     docbook = args.generate_docbook
-    docbook_gen = codegen_docbook.DocbookCodeGenerator(all_ifaces);
+    docbook_gen = codegen_docbook.DocbookCodeGenerator(all_ifaces)
     if docbook:
-        ret = docbook_gen.generate(docbook, args.output_directory)
+        docbook_gen.generate(docbook, args.output_directory)
 
     if args.header:
-        with open(h_file, 'w') as outfile:
-            gen = codegen.HeaderCodeGenerator(all_ifaces,
-                                              args.c_namespace,
-                                              args.c_generate_object_manager,
-                                              args.c_generate_autocleanup,
-                                              header_name,
-                                              input_files_basenames,
-                                              args.pragma_once,
-                                              glib_min_required,
-                                              args.symbol_decorator,
-                                              args.symbol_decorator_header,
-                                              outfile)
+        with open(h_file, "w") as outfile:
+            gen = codegen.HeaderCodeGenerator(
+                all_ifaces,
+                args.c_namespace,
+                args.c_generate_object_manager,
+                args.c_generate_autocleanup,
+                header_name,
+                input_files_basenames,
+                args.pragma_once,
+                glib_min_required,
+                args.symbol_decorator,
+                args.symbol_decorator_header,
+                outfile,
+            )
             gen.generate()
 
     if args.body:
-        with open(c_file, 'w') as outfile:
-            gen = codegen.CodeGenerator(all_ifaces,
-                                        args.c_namespace,
-                                        args.c_generate_object_manager,
-                                        header_name,
-                                        input_files_basenames,
-                                        docbook_gen,
-                                        glib_min_required,
-                                        args.symbol_decorator_define,
-                                        outfile)
+        with open(c_file, "w") as outfile:
+            gen = codegen.CodeGenerator(
+                all_ifaces,
+                args.c_namespace,
+                args.c_generate_object_manager,
+                header_name,
+                input_files_basenames,
+                docbook_gen,
+                glib_min_required,
+                args.symbol_decorator_define,
+                outfile,
+            )
             gen.generate()
 
     if args.interface_info_header:
-        with open(h_file, 'w') as outfile:
-            gen = codegen.InterfaceInfoHeaderCodeGenerator(all_ifaces,
-                                                           args.c_namespace,
-                                                           header_name,
-                                                           input_files_basenames,
-                                                           args.pragma_once,
-                                                           glib_min_required,
-                                                           args.symbol_decorator,
-                                                           args.symbol_decorator_header,
-                                                           outfile)
+        with open(h_file, "w") as outfile:
+            gen = codegen.InterfaceInfoHeaderCodeGenerator(
+                all_ifaces,
+                args.c_namespace,
+                header_name,
+                input_files_basenames,
+                args.pragma_once,
+                glib_min_required,
+                args.symbol_decorator,
+                args.symbol_decorator_header,
+                outfile,
+            )
             gen.generate()
 
     if args.interface_info_body:
-        with open(c_file, 'w') as outfile:
-            gen = codegen.InterfaceInfoBodyCodeGenerator(all_ifaces,
-                                                         args.c_namespace,
-                                                         header_name,
-                                                         input_files_basenames,
-                                                         glib_min_required,
-                                                         args.symbol_decorator_define,
-                                                         outfile)
+        with open(c_file, "w") as outfile:
+            gen = codegen.InterfaceInfoBodyCodeGenerator(
+                all_ifaces,
+                args.c_namespace,
+                header_name,
+                input_files_basenames,
+                glib_min_required,
+                args.symbol_decorator_define,
+                outfile,
+            )
             gen.generate()
 
     sys.exit(0)
 
+
 if __name__ == "__main__":
     codegen_main()
index 415a5cc..bbe5c4e 100644 (file)
 from . import utils
 from .utils import print_error
 
+
 class Annotation:
     def __init__(self, key, value):
         self.key = key
         self.value = value
         self.annotations = []
-        self.since = ''
+        self.since = ""
 
     def post_process(self, interface_prefix, cns, cns_upper, cns_lower, container):
         key = self.key
-        overridden_key = utils.lookup_annotation(self.annotations, 'org.gtk.GDBus.C.Name')
+        overridden_key = utils.lookup_annotation(
+            self.annotations, "org.gtk.GDBus.C.Name"
+        )
         if utils.is_ugly_case(overridden_key):
             self.key_lower = overridden_key.lower()
         else:
             if overridden_key:
                 key = overridden_key
-            self.key_lower = utils.camel_case_to_uscore(key).lower().replace('-', '_').replace('.', '_')
+            self.key_lower = (
+                utils.camel_case_to_uscore(key)
+                .lower()
+                .replace("-", "_")
+                .replace(".", "_")
+            )
 
         if len(self.since) == 0:
             self.since = utils.lookup_since(self.annotations)
@@ -47,13 +55,14 @@ class Annotation:
         for a in self.annotations:
             a.post_process(interface_prefix, cns, cns_upper, cns_lower, self)
 
+
 class Arg:
     def __init__(self, name, signature):
         self.name = name
         self.signature = signature
         self.annotations = []
-        self.doc_string = ''
-        self.since = ''
+        self.doc_string = ""
+        self.since = ""
 
     def post_process(self, interface_prefix, cns, cns_upper, cns_lower, arg_number):
         if len(self.doc_string) == 0:
@@ -62,195 +71,198 @@ class Arg:
             self.since = utils.lookup_since(self.annotations)
 
         if self.name is None:
-            self.name = 'unnamed_arg%d'%arg_number
+            self.name = "unnamed_arg%d" % arg_number
         # default to GVariant
-        self.ctype_in_g  = 'GVariant *'
-        self.ctype_in  = 'GVariant *'
-        self.ctype_in_dup  = 'GVariant *'
-        self.ctype_out = 'GVariant **'
-        self.gtype = 'G_TYPE_VARIANT'
-        self.free_func = 'g_variant_unref'
-        self.format_in = '@' + self.signature
-        self.format_out = '@' + self.signature
-        self.gvariant_get = 'XXX'
-        self.gvalue_get = 'g_value_get_variant'
-        self.array_annotation = ''
-
-        if not utils.lookup_annotation(self.annotations, 'org.gtk.GDBus.C.ForceGVariant'):
-            if self.signature == 'b':
-                self.ctype_in_g  = 'gboolean '
-                self.ctype_in  = 'gboolean '
-                self.ctype_out = 'gboolean *'
-                self.gtype = 'G_TYPE_BOOLEAN'
+        self.ctype_in_g = "GVariant *"
+        self.ctype_in = "GVariant *"
+        self.ctype_in_dup = "GVariant *"
+        self.ctype_out = "GVariant **"
+        self.gtype = "G_TYPE_VARIANT"
+        self.free_func = "g_variant_unref"
+        self.format_in = "@" + self.signature
+        self.format_out = "@" + self.signature
+        self.gvariant_get = "XXX"
+        self.gvalue_get = "g_value_get_variant"
+        self.array_annotation = ""
+
+        if not utils.lookup_annotation(
+            self.annotations, "org.gtk.GDBus.C.ForceGVariant"
+        ):
+            if self.signature == "b":
+                self.ctype_in_g = "gboolean "
+                self.ctype_in = "gboolean "
+                self.ctype_out = "gboolean *"
+                self.gtype = "G_TYPE_BOOLEAN"
                 self.free_func = None
-                self.format_in = 'b'
-                self.format_out = 'b'
-                self.gvariant_get = 'g_variant_get_boolean'
-                self.gvalue_get = 'g_value_get_boolean'
-            elif self.signature == 'y':
-                self.ctype_in_g  = 'guchar '
-                self.ctype_in  = 'guchar '
-                self.ctype_out = 'guchar *'
-                self.gtype = 'G_TYPE_UCHAR'
+                self.format_in = "b"
+                self.format_out = "b"
+                self.gvariant_get = "g_variant_get_boolean"
+                self.gvalue_get = "g_value_get_boolean"
+            elif self.signature == "y":
+                self.ctype_in_g = "guchar "
+                self.ctype_in = "guchar "
+                self.ctype_out = "guchar *"
+                self.gtype = "G_TYPE_UCHAR"
                 self.free_func = None
-                self.format_in = 'y'
-                self.format_out = 'y'
-                self.gvariant_get = 'g_variant_get_byte'
-                self.gvalue_get = 'g_value_get_uchar'
-            elif self.signature == 'n':
-                self.ctype_in_g  = 'gint '
-                self.ctype_in  = 'gint16 '
-                self.ctype_out = 'gint16 *'
-                self.gtype = 'G_TYPE_INT'
+                self.format_in = "y"
+                self.format_out = "y"
+                self.gvariant_get = "g_variant_get_byte"
+                self.gvalue_get = "g_value_get_uchar"
+            elif self.signature == "n":
+                self.ctype_in_g = "gint "
+                self.ctype_in = "gint16 "
+                self.ctype_out = "gint16 *"
+                self.gtype = "G_TYPE_INT"
                 self.free_func = None
-                self.format_in = 'n'
-                self.format_out = 'n'
-                self.gvariant_get = 'g_variant_get_int16'
-                self.gvalue_get = 'g_value_get_int'
-            elif self.signature == 'q':
-                self.ctype_in_g  = 'guint '
-                self.ctype_in  = 'guint16 '
-                self.ctype_out = 'guint16 *'
-                self.gtype = 'G_TYPE_UINT'
+                self.format_in = "n"
+                self.format_out = "n"
+                self.gvariant_get = "g_variant_get_int16"
+                self.gvalue_get = "g_value_get_int"
+            elif self.signature == "q":
+                self.ctype_in_g = "guint "
+                self.ctype_in = "guint16 "
+                self.ctype_out = "guint16 *"
+                self.gtype = "G_TYPE_UINT"
                 self.free_func = None
-                self.format_in = 'q'
-                self.format_out = 'q'
-                self.gvariant_get = 'g_variant_get_uint16'
-                self.gvalue_get = 'g_value_get_uint'
-            elif self.signature == 'i':
-                self.ctype_in_g  = 'gint '
-                self.ctype_in  = 'gint '
-                self.ctype_out = 'gint *'
-                self.gtype = 'G_TYPE_INT'
+                self.format_in = "q"
+                self.format_out = "q"
+                self.gvariant_get = "g_variant_get_uint16"
+                self.gvalue_get = "g_value_get_uint"
+            elif self.signature == "i":
+                self.ctype_in_g = "gint "
+                self.ctype_in = "gint "
+                self.ctype_out = "gint *"
+                self.gtype = "G_TYPE_INT"
                 self.free_func = None
-                self.format_in = 'i'
-                self.format_out = 'i'
-                self.gvariant_get = 'g_variant_get_int32'
-                self.gvalue_get = 'g_value_get_int'
-            elif self.signature == 'u':
-                self.ctype_in_g  = 'guint '
-                self.ctype_in  = 'guint '
-                self.ctype_out = 'guint *'
-                self.gtype = 'G_TYPE_UINT'
+                self.format_in = "i"
+                self.format_out = "i"
+                self.gvariant_get = "g_variant_get_int32"
+                self.gvalue_get = "g_value_get_int"
+            elif self.signature == "u":
+                self.ctype_in_g = "guint "
+                self.ctype_in = "guint "
+                self.ctype_out = "guint *"
+                self.gtype = "G_TYPE_UINT"
                 self.free_func = None
-                self.format_in = 'u'
-                self.format_out = 'u'
-                self.gvariant_get = 'g_variant_get_uint32'
-                self.gvalue_get = 'g_value_get_uint'
-            elif self.signature == 'x':
-                self.ctype_in_g  = 'gint64 '
-                self.ctype_in  = 'gint64 '
-                self.ctype_out = 'gint64 *'
-                self.gtype = 'G_TYPE_INT64'
+                self.format_in = "u"
+                self.format_out = "u"
+                self.gvariant_get = "g_variant_get_uint32"
+                self.gvalue_get = "g_value_get_uint"
+            elif self.signature == "x":
+                self.ctype_in_g = "gint64 "
+                self.ctype_in = "gint64 "
+                self.ctype_out = "gint64 *"
+                self.gtype = "G_TYPE_INT64"
                 self.free_func = None
-                self.format_in = 'x'
-                self.format_out = 'x'
-                self.gvariant_get = 'g_variant_get_int64'
-                self.gvalue_get = 'g_value_get_int64'
-            elif self.signature == 't':
-                self.ctype_in_g  = 'guint64 '
-                self.ctype_in  = 'guint64 '
-                self.ctype_out = 'guint64 *'
-                self.gtype = 'G_TYPE_UINT64'
+                self.format_in = "x"
+                self.format_out = "x"
+                self.gvariant_get = "g_variant_get_int64"
+                self.gvalue_get = "g_value_get_int64"
+            elif self.signature == "t":
+                self.ctype_in_g = "guint64 "
+                self.ctype_in = "guint64 "
+                self.ctype_out = "guint64 *"
+                self.gtype = "G_TYPE_UINT64"
                 self.free_func = None
-                self.format_in = 't'
-                self.format_out = 't'
-                self.gvariant_get = 'g_variant_get_uint64'
-                self.gvalue_get = 'g_value_get_uint64'
-            elif self.signature == 'd':
-                self.ctype_in_g  = 'gdouble '
-                self.ctype_in  = 'gdouble '
-                self.ctype_out = 'gdouble *'
-                self.gtype = 'G_TYPE_DOUBLE'
+                self.format_in = "t"
+                self.format_out = "t"
+                self.gvariant_get = "g_variant_get_uint64"
+                self.gvalue_get = "g_value_get_uint64"
+            elif self.signature == "d":
+                self.ctype_in_g = "gdouble "
+                self.ctype_in = "gdouble "
+                self.ctype_out = "gdouble *"
+                self.gtype = "G_TYPE_DOUBLE"
                 self.free_func = None
-                self.format_in = 'd'
-                self.format_out = 'd'
-                self.gvariant_get = 'g_variant_get_double'
-                self.gvalue_get = 'g_value_get_double'
-            elif self.signature == 's':
-                self.ctype_in_g  = 'const gchar *'
-                self.ctype_in  = 'const gchar *'
-                self.ctype_in_dup  = 'gchar *'
-                self.ctype_out = 'gchar **'
-                self.gtype = 'G_TYPE_STRING'
-                self.free_func = 'g_free'
-                self.format_in = 's'
-                self.format_out = 's'
-                self.gvariant_get = 'g_variant_get_string'
-                self.gvalue_get = 'g_value_get_string'
-            elif self.signature == 'o':
-                self.ctype_in_g  = 'const gchar *'
-                self.ctype_in  = 'const gchar *'
-                self.ctype_in_dup  = 'gchar *'
-                self.ctype_out = 'gchar **'
-                self.gtype = 'G_TYPE_STRING'
-                self.free_func = 'g_free'
-                self.format_in = 'o'
-                self.format_out = 'o'
-                self.gvariant_get = 'g_variant_get_string'
-                self.gvalue_get = 'g_value_get_string'
-            elif self.signature == 'g':
-                self.ctype_in_g  = 'const gchar *'
-                self.ctype_in  = 'const gchar *'
-                self.ctype_in_dup  = 'gchar *'
-                self.ctype_out = 'gchar **'
-                self.gtype = 'G_TYPE_STRING'
-                self.free_func = 'g_free'
-                self.format_in = 'g'
-                self.format_out = 'g'
-                self.gvariant_get = 'g_variant_get_string'
-                self.gvalue_get = 'g_value_get_string'
-            elif self.signature == 'ay':
-                self.ctype_in_g  = 'const gchar *'
-                self.ctype_in  = 'const gchar *'
-                self.ctype_in_dup  = 'gchar *'
-                self.ctype_out = 'gchar **'
-                self.gtype = 'G_TYPE_STRING'
-                self.free_func = 'g_free'
-                self.format_in = '^ay'
-                self.format_out = '^ay'
-                self.gvariant_get = 'g_variant_get_bytestring'
-                self.gvalue_get = 'g_value_get_string'
-            elif self.signature == 'as':
-                self.ctype_in_g  = 'const gchar *const *'
-                self.ctype_in  = 'const gchar *const *'
-                self.ctype_in_dup  = 'gchar **'
-                self.ctype_out = 'gchar ***'
-                self.gtype = 'G_TYPE_STRV'
-                self.free_func = 'g_strfreev'
-                self.format_in = '^as'
-                self.format_out = '^as'
-                self.gvariant_get = 'g_variant_get_strv'
-                self.gvalue_get = 'g_value_get_boxed'
-                self.array_annotation = '(array zero-terminated=1)'
-            elif self.signature == 'ao':
-                self.ctype_in_g  = 'const gchar *const *'
-                self.ctype_in  = 'const gchar *const *'
-                self.ctype_in_dup  = 'gchar **'
-                self.ctype_out = 'gchar ***'
-                self.gtype = 'G_TYPE_STRV'
-                self.free_func = 'g_strfreev'
-                self.format_in = '^ao'
-                self.format_out = '^ao'
-                self.gvariant_get = 'g_variant_get_objv'
-                self.gvalue_get = 'g_value_get_boxed'
-                self.array_annotation = '(array zero-terminated=1)'
-            elif self.signature == 'aay':
-                self.ctype_in_g  = 'const gchar *const *'
-                self.ctype_in  = 'const gchar *const *'
-                self.ctype_in_dup  = 'gchar **'
-                self.ctype_out = 'gchar ***'
-                self.gtype = 'G_TYPE_STRV'
-                self.free_func = 'g_strfreev'
-                self.format_in = '^aay'
-                self.format_out = '^aay'
-                self.gvariant_get = 'g_variant_get_bytestring_array'
-                self.gvalue_get = 'g_value_get_boxed'
-                self.array_annotation = '(array zero-terminated=1)'
+                self.format_in = "d"
+                self.format_out = "d"
+                self.gvariant_get = "g_variant_get_double"
+                self.gvalue_get = "g_value_get_double"
+            elif self.signature == "s":
+                self.ctype_in_g = "const gchar *"
+                self.ctype_in = "const gchar *"
+                self.ctype_in_dup = "gchar *"
+                self.ctype_out = "gchar **"
+                self.gtype = "G_TYPE_STRING"
+                self.free_func = "g_free"
+                self.format_in = "s"
+                self.format_out = "s"
+                self.gvariant_get = "g_variant_get_string"
+                self.gvalue_get = "g_value_get_string"
+            elif self.signature == "o":
+                self.ctype_in_g = "const gchar *"
+                self.ctype_in = "const gchar *"
+                self.ctype_in_dup = "gchar *"
+                self.ctype_out = "gchar **"
+                self.gtype = "G_TYPE_STRING"
+                self.free_func = "g_free"
+                self.format_in = "o"
+                self.format_out = "o"
+                self.gvariant_get = "g_variant_get_string"
+                self.gvalue_get = "g_value_get_string"
+            elif self.signature == "g":
+                self.ctype_in_g = "const gchar *"
+                self.ctype_in = "const gchar *"
+                self.ctype_in_dup = "gchar *"
+                self.ctype_out = "gchar **"
+                self.gtype = "G_TYPE_STRING"
+                self.free_func = "g_free"
+                self.format_in = "g"
+                self.format_out = "g"
+                self.gvariant_get = "g_variant_get_string"
+                self.gvalue_get = "g_value_get_string"
+            elif self.signature == "ay":
+                self.ctype_in_g = "const gchar *"
+                self.ctype_in = "const gchar *"
+                self.ctype_in_dup = "gchar *"
+                self.ctype_out = "gchar **"
+                self.gtype = "G_TYPE_STRING"
+                self.free_func = "g_free"
+                self.format_in = "^ay"
+                self.format_out = "^ay"
+                self.gvariant_get = "g_variant_get_bytestring"
+                self.gvalue_get = "g_value_get_string"
+            elif self.signature == "as":
+                self.ctype_in_g = "const gchar *const *"
+                self.ctype_in = "const gchar *const *"
+                self.ctype_in_dup = "gchar **"
+                self.ctype_out = "gchar ***"
+                self.gtype = "G_TYPE_STRV"
+                self.free_func = "g_strfreev"
+                self.format_in = "^as"
+                self.format_out = "^as"
+                self.gvariant_get = "g_variant_get_strv"
+                self.gvalue_get = "g_value_get_boxed"
+                self.array_annotation = "(array zero-terminated=1)"
+            elif self.signature == "ao":
+                self.ctype_in_g = "const gchar *const *"
+                self.ctype_in = "const gchar *const *"
+                self.ctype_in_dup = "gchar **"
+                self.ctype_out = "gchar ***"
+                self.gtype = "G_TYPE_STRV"
+                self.free_func = "g_strfreev"
+                self.format_in = "^ao"
+                self.format_out = "^ao"
+                self.gvariant_get = "g_variant_get_objv"
+                self.gvalue_get = "g_value_get_boxed"
+                self.array_annotation = "(array zero-terminated=1)"
+            elif self.signature == "aay":
+                self.ctype_in_g = "const gchar *const *"
+                self.ctype_in = "const gchar *const *"
+                self.ctype_in_dup = "gchar **"
+                self.ctype_out = "gchar ***"
+                self.gtype = "G_TYPE_STRV"
+                self.free_func = "g_strfreev"
+                self.format_in = "^aay"
+                self.format_out = "^aay"
+                self.gvariant_get = "g_variant_get_bytestring_array"
+                self.gvalue_get = "g_value_get_boxed"
+                self.array_annotation = "(array zero-terminated=1)"
 
         for a in self.annotations:
             a.post_process(interface_prefix, cns, cns_upper, cns_lower, self)
 
+
 class Method:
     def __init__(self, name, h_type_implies_unix_fd=True):
         self.name = name
@@ -258,12 +270,14 @@ class Method:
         self.in_args = []
         self.out_args = []
         self.annotations = []
-        self.doc_string = ''
-        self.since = ''
+        self.doc_string = ""
+        self.since = ""
         self.deprecated = False
         self.unix_fd = False
 
-    def post_process(self, interface_prefix, cns, cns_upper, cns_lower, containing_iface):
+    def post_process(
+        self, interface_prefix, cns, cns_upper, cns_lower, containing_iface
+    ):
         if len(self.doc_string) == 0:
             self.doc_string = utils.lookup_docs(self.annotations)
         if len(self.since) == 0:
@@ -272,47 +286,55 @@ class Method:
                 self.since = containing_iface.since
 
         name = self.name
-        overridden_name = utils.lookup_annotation(self.annotations, 'org.gtk.GDBus.C.Name')
+        overridden_name = utils.lookup_annotation(
+            self.annotations, "org.gtk.GDBus.C.Name"
+        )
         if utils.is_ugly_case(overridden_name):
             self.name_lower = overridden_name.lower()
         else:
             if overridden_name:
                 name = overridden_name
-            self.name_lower = utils.camel_case_to_uscore(name).lower().replace('-', '_')
-        self.name_hyphen = self.name_lower.replace('_', '-')
+            self.name_lower = utils.camel_case_to_uscore(name).lower().replace("-", "_")
+        self.name_hyphen = self.name_lower.replace("_", "-")
 
         arg_count = 0
         for a in self.in_args:
             a.post_process(interface_prefix, cns, cns_upper, cns_lower, arg_count)
             arg_count += 1
-            if self.h_type_implies_unix_fd and 'h' in a.signature:
+            if self.h_type_implies_unix_fd and "h" in a.signature:
                 self.unix_fd = True
 
         for a in self.out_args:
             a.post_process(interface_prefix, cns, cns_upper, cns_lower, arg_count)
             arg_count += 1
-            if self.h_type_implies_unix_fd and 'h' in a.signature:
+            if self.h_type_implies_unix_fd and "h" in a.signature:
                 self.unix_fd = True
 
-        if utils.lookup_annotation(self.annotations, 'org.freedesktop.DBus.Deprecated') == 'true':
+        if (
+            utils.lookup_annotation(self.annotations, "org.freedesktop.DBus.Deprecated")
+            == "true"
+        ):
             self.deprecated = True
 
-        if utils.lookup_annotation(self.annotations, 'org.gtk.GDBus.C.UnixFD'):
+        if utils.lookup_annotation(self.annotations, "org.gtk.GDBus.C.UnixFD"):
             self.unix_fd = True
 
         for a in self.annotations:
             a.post_process(interface_prefix, cns, cns_upper, cns_lower, self)
 
+
 class Signal:
     def __init__(self, name):
         self.name = name
         self.args = []
         self.annotations = []
-        self.doc_string = ''
-        self.since = ''
+        self.doc_string = ""
+        self.since = ""
         self.deprecated = False
 
-    def post_process(self, interface_prefix, cns, cns_upper, cns_lower, containing_iface):
+    def post_process(
+        self, interface_prefix, cns, cns_upper, cns_lower, containing_iface
+    ):
         if len(self.doc_string) == 0:
             self.doc_string = utils.lookup_docs(self.annotations)
         if len(self.since) == 0:
@@ -321,51 +343,59 @@ class Signal:
                 self.since = containing_iface.since
 
         name = self.name
-        overridden_name = utils.lookup_annotation(self.annotations, 'org.gtk.GDBus.C.Name')
+        overridden_name = utils.lookup_annotation(
+            self.annotations, "org.gtk.GDBus.C.Name"
+        )
         if utils.is_ugly_case(overridden_name):
             self.name_lower = overridden_name.lower()
         else:
             if overridden_name:
                 name = overridden_name
-            self.name_lower = utils.camel_case_to_uscore(name).lower().replace('-', '_')
-        self.name_hyphen = self.name_lower.replace('_', '-')
+            self.name_lower = utils.camel_case_to_uscore(name).lower().replace("-", "_")
+        self.name_hyphen = self.name_lower.replace("_", "-")
 
         arg_count = 0
         for a in self.args:
             a.post_process(interface_prefix, cns, cns_upper, cns_lower, arg_count)
             arg_count += 1
 
-        if utils.lookup_annotation(self.annotations, 'org.freedesktop.DBus.Deprecated') == 'true':
+        if (
+            utils.lookup_annotation(self.annotations, "org.freedesktop.DBus.Deprecated")
+            == "true"
+        ):
             self.deprecated = True
 
         for a in self.annotations:
             a.post_process(interface_prefix, cns, cns_upper, cns_lower, self)
 
+
 class Property:
     def __init__(self, name, signature, access):
         self.name = name
         self.signature = signature
         self.access = access
         self.annotations = []
-        self.arg = Arg('value', self.signature)
+        self.arg = Arg("value", self.signature)
         self.arg.annotations = self.annotations
         self.readable = False
         self.writable = False
-        if self.access == 'readwrite':
+        if self.access == "readwrite":
             self.readable = True
             self.writable = True
-        elif self.access == 'read':
+        elif self.access == "read":
             self.readable = True
-        elif self.access == 'write':
+        elif self.access == "write":
             self.writable = True
         else:
             print_error('Invalid access type "{}"'.format(self.access))
-        self.doc_string = ''
-        self.since = ''
+        self.doc_string = ""
+        self.since = ""
         self.deprecated = False
         self.emits_changed_signal = True
 
-    def post_process(self, interface_prefix, cns, cns_upper, cns_lower, containing_iface):
+    def post_process(
+        self, interface_prefix, cns, cns_upper, cns_lower, containing_iface
+    ):
         if len(self.doc_string) == 0:
             self.doc_string = utils.lookup_docs(self.annotations)
         if len(self.since) == 0:
@@ -374,34 +404,44 @@ class Property:
                 self.since = containing_iface.since
 
         name = self.name
-        overridden_name = utils.lookup_annotation(self.annotations, 'org.gtk.GDBus.C.Name')
+        overridden_name = utils.lookup_annotation(
+            self.annotations, "org.gtk.GDBus.C.Name"
+        )
         if utils.is_ugly_case(overridden_name):
             self.name_lower = overridden_name.lower()
         else:
             if overridden_name:
                 name = overridden_name
-            self.name_lower = utils.camel_case_to_uscore(name).lower().replace('-', '_')
-        self.name_hyphen = self.name_lower.replace('_', '-')
-        # don't clash with the GType getter, e.g.: GType foo_bar_get_type (void); G_GNUC_CONST
-        if self.name_lower == 'type':
-            self.name_lower = 'type_'
+            self.name_lower = utils.camel_case_to_uscore(name).lower().replace("-", "_")
+        self.name_hyphen = self.name_lower.replace("_", "-")
+        # don't clash with the GType getter, e.g.:
+        # GType foo_bar_get_type (void); G_GNUC_CONST
+        if self.name_lower == "type":
+            self.name_lower = "type_"
 
         # recalculate arg
         self.arg.annotations = self.annotations
         self.arg.post_process(interface_prefix, cns, cns_upper, cns_lower, 0)
 
-        if utils.lookup_annotation(self.annotations, 'org.freedesktop.DBus.Deprecated') == 'true':
+        if (
+            utils.lookup_annotation(self.annotations, "org.freedesktop.DBus.Deprecated")
+            == "true"
+        ):
             self.deprecated = True
 
         for a in self.annotations:
             a.post_process(interface_prefix, cns, cns_upper, cns_lower, self)
 
-        # FIXME: for now we only support 'false' and 'const' on the signal itself, see #674913 and
+        # FIXME: for now we only support 'false' and 'const' on the signal itself,
+        # see #674913 and
         # http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format
         # for details
-        if utils.lookup_annotation(self.annotations, 'org.freedesktop.DBus.Property.EmitsChangedSignal') in ('false', 'const'):
+        if utils.lookup_annotation(
+            self.annotations, "org.freedesktop.DBus.Property.EmitsChangedSignal"
+        ) in ("false", "const"):
             self.emits_changed_signal = False
 
+
 class Interface:
     def __init__(self, name):
         self.name = name
@@ -409,9 +449,9 @@ class Interface:
         self.signals = []
         self.properties = []
         self.annotations = []
-        self.doc_string = ''
-        self.doc_string_brief = ''
-        self.since = ''
+        self.doc_string = ""
+        self.doc_string_brief = ""
+        self.since = ""
         self.deprecated = False
 
     def post_process(self, interface_prefix, c_namespace):
@@ -424,21 +464,23 @@ class Interface:
 
         if len(c_namespace) > 0:
             if utils.is_ugly_case(c_namespace):
-                cns = c_namespace.replace('_', '')
-                cns_upper = c_namespace.upper() + '_'
-                cns_lower = c_namespace.lower() + '_'
+                cns = c_namespace.replace("_", "")
+                cns_upper = c_namespace.upper() + "_"
+                cns_lower = c_namespace.lower() + "_"
             else:
                 cns = c_namespace
-                cns_upper = utils.camel_case_to_uscore(c_namespace).upper() + '_'
-                cns_lower = utils.camel_case_to_uscore(c_namespace).lower() + '_'
+                cns_upper = utils.camel_case_to_uscore(c_namespace).upper() + "_"
+                cns_lower = utils.camel_case_to_uscore(c_namespace).lower() + "_"
         else:
-            cns = ''
-            cns_upper = ''
-            cns_lower = ''
+            cns = ""
+            cns_upper = ""
+            cns_lower = ""
 
-        overridden_name = utils.lookup_annotation(self.annotations, 'org.gtk.GDBus.C.Name')
+        overridden_name = utils.lookup_annotation(
+            self.annotations, "org.gtk.GDBus.C.Name"
+        )
         if utils.is_ugly_case(overridden_name):
-            name = overridden_name.replace('_', '')
+            name = overridden_name.replace("_", "")
             name_with_ns = cns + name
             self.name_without_prefix = name
             self.camel_name = name_with_ns
@@ -446,25 +488,28 @@ class Interface:
             self.name_lower = cns_lower + overridden_name.lower()
             self.name_upper = overridden_name.upper()
 
-            #print_error('handle Ugly_Case "{}"'.format(overridden_name))
+            # print_error('handle Ugly_Case "{}"'.format(overridden_name))
         else:
             if overridden_name:
                 name = overridden_name
             else:
                 name = self.name
                 if name.startswith(interface_prefix):
-                    name = name[len(interface_prefix):]
+                    name = name[len(interface_prefix) :]
             self.name_without_prefix = name
             name = utils.strip_dots(name)
-            name_with_ns = utils.strip_dots(cns + '.' + name)
+            name_with_ns = utils.strip_dots(cns + "." + name)
             self.camel_name = name_with_ns
             self.ns_upper = cns_upper
             self.name_lower = cns_lower + utils.camel_case_to_uscore(name)
             self.name_upper = utils.camel_case_to_uscore(name).upper()
 
-        self.name_hyphen = self.name_upper.lower().replace('_', '-')
+        self.name_hyphen = self.name_upper.lower().replace("_", "-")
 
-        if utils.lookup_annotation(self.annotations, 'org.freedesktop.DBus.Deprecated') == 'true':
+        if (
+            utils.lookup_annotation(self.annotations, "org.freedesktop.DBus.Deprecated")
+            == "true"
+        ):
             self.deprecated = True
 
         for m in self.methods:
index 7dcc735..45226d5 100644 (file)
 #
 # Author: David Zeuthen <davidz@redhat.com>
 
-import sys
 import xml.parsers.expat
 
 from . import dbustypes
 from .utils import print_error
 
+
 class DBusXMLParser:
-    STATE_TOP = 'top'
-    STATE_NODE = 'node'
-    STATE_INTERFACE = 'interface'
-    STATE_METHOD = 'method'
-    STATE_SIGNAL = 'signal'
-    STATE_PROPERTY = 'property'
-    STATE_ARG = 'arg'
-    STATE_ANNOTATION = 'annotation'
-    STATE_IGNORED = 'ignored'
+    STATE_TOP = "top"
+    STATE_NODE = "node"
+    STATE_INTERFACE = "interface"
+    STATE_METHOD = "method"
+    STATE_SIGNAL = "signal"
+    STATE_PROPERTY = "property"
+    STATE_ARG = "arg"
+    STATE_ANNOTATION = "annotation"
+    STATE_IGNORED = "ignored"
 
     def __init__(self, xml_data, h_type_implies_unix_fd=True):
         self._parser = xml.parsers.expat.ParserCreate()
@@ -51,21 +51,22 @@ class DBusXMLParser:
         self._cur_object = None
         self._cur_object_stack = []
 
-        self.doc_comment_last_symbol = ''
+        self.doc_comment_last_symbol = ""
 
         self._h_type_implies_unix_fd = h_type_implies_unix_fd
 
         self._parser.Parse(xml_data)
 
-    COMMENT_STATE_BEGIN = 'begin'
-    COMMENT_STATE_PARAMS = 'params'
-    COMMENT_STATE_BODY = 'body'
-    COMMENT_STATE_SKIP = 'skip'
+    COMMENT_STATE_BEGIN = "begin"
+    COMMENT_STATE_PARAMS = "params"
+    COMMENT_STATE_BODY = "body"
+    COMMENT_STATE_SKIP = "skip"
+
     def handle_comment(self, data):
-        comment_state = DBusXMLParser.COMMENT_STATE_BEGIN;
-        lines = data.split('\n')
-        symbol = ''
-        body = ''
+        comment_state = DBusXMLParser.COMMENT_STATE_BEGIN
+        lines = data.split("\n")
+        symbol = ""
+        body = ""
         in_para = False
         params = {}
         for line in lines:
@@ -73,59 +74,59 @@ class DBusXMLParser:
             line = line.lstrip()
             if comment_state == DBusXMLParser.COMMENT_STATE_BEGIN:
                 if len(line) > 0:
-                    colon_index = line.find(': ')
+                    colon_index = line.find(": ")
                     if colon_index == -1:
-                        if line.endswith(':'):
-                            symbol = line[0:len(line)-1]
+                        if line.endswith(":"):
+                            symbol = line[0 : len(line) - 1]
                             comment_state = DBusXMLParser.COMMENT_STATE_PARAMS
                         else:
                             comment_state = DBusXMLParser.COMMENT_STATE_SKIP
                     else:
                         symbol = line[0:colon_index]
-                        rest_of_line = line[colon_index+2:].strip()
+                        rest_of_line = line[colon_index + 2 :].strip()
                         if len(rest_of_line) > 0:
-                            body += '<para>' + rest_of_line + '</para>'
+                            body += "<para>" + rest_of_line + "</para>"
                         comment_state = DBusXMLParser.COMMENT_STATE_PARAMS
             elif comment_state == DBusXMLParser.COMMENT_STATE_PARAMS:
-                if line.startswith('@'):
-                    colon_index = line.find(': ')
+                if line.startswith("@"):
+                    colon_index = line.find(": ")
                     if colon_index == -1:
                         comment_state = DBusXMLParser.COMMENT_STATE_BODY
                         if not in_para:
-                            body += '<para>'
+                            body += "<para>"
                             in_para = True
-                        body += orig_line + '\n'
+                        body += orig_line + "\n"
                     else:
                         param = line[1:colon_index]
-                        docs = line[colon_index + 2:]
+                        docs = line[colon_index + 2 :]
                         params[param] = docs
                 else:
                     comment_state = DBusXMLParser.COMMENT_STATE_BODY
                     if len(line) > 0:
                         if not in_para:
-                            body += '<para>'
+                            body += "<para>"
                             in_para = True
-                        body += orig_line + '\n'
+                        body += orig_line + "\n"
             elif comment_state == DBusXMLParser.COMMENT_STATE_BODY:
                 if len(line) > 0:
                     if not in_para:
-                        body += '<para>'
+                        body += "<para>"
                         in_para = True
-                    body += orig_line + '\n'
+                    body += orig_line + "\n"
                 else:
                     if in_para:
-                        body += '</para>'
+                        body += "</para>"
                         in_para = False
         if in_para:
-            body += '</para>'
+            body += "</para>"
 
-        if symbol != '':
+        if symbol != "":
             self.doc_comment_last_symbol = symbol
             self.doc_comment_params = params
             self.doc_comment_body = body
 
     def handle_char_data(self, data):
-        #print 'char_data=%s'%data
+        # print 'char_data=%s'%data
         pass
 
     def handle_start_element(self, name, attrs):
@@ -141,77 +142,76 @@ class DBusXMLParser:
         elif self.state == DBusXMLParser.STATE_NODE:
             if name == DBusXMLParser.STATE_INTERFACE:
                 self.state = DBusXMLParser.STATE_INTERFACE
-                iface = dbustypes.Interface(attrs['name'])
+                iface = dbustypes.Interface(attrs["name"])
                 self._cur_object = iface
                 self.parsed_interfaces.append(iface)
             elif name == DBusXMLParser.STATE_ANNOTATION:
                 self.state = DBusXMLParser.STATE_ANNOTATION
-                anno = dbustypes.Annotation(attrs['name'], attrs['value'])
+                anno = dbustypes.Annotation(attrs["name"], attrs["value"])
                 self._cur_object.annotations.append(anno)
                 self._cur_object = anno
             else:
                 self.state = DBusXMLParser.STATE_IGNORED
 
             # assign docs, if any
-            if 'name' in attrs and self.doc_comment_last_symbol == attrs['name']:
+            if "name" in attrs and self.doc_comment_last_symbol == attrs["name"]:
                 self._cur_object.doc_string = self.doc_comment_body
-                if 'short_description' in self.doc_comment_params:
-                    short_description = self.doc_comment_params['short_description']
+                if "short_description" in self.doc_comment_params:
+                    short_description = self.doc_comment_params["short_description"]
                     self._cur_object.doc_string_brief = short_description
-                if 'since' in self.doc_comment_params:
-                    self._cur_object.since = \
-                        self.doc_comment_params['since'].strip()
+                if "since" in self.doc_comment_params:
+                    self._cur_object.since = self.doc_comment_params["since"].strip()
 
         elif self.state == DBusXMLParser.STATE_INTERFACE:
             if name == DBusXMLParser.STATE_METHOD:
                 self.state = DBusXMLParser.STATE_METHOD
-                method = dbustypes.Method(attrs['name'],
-                                          h_type_implies_unix_fd=self._h_type_implies_unix_fd)
+                method = dbustypes.Method(
+                    attrs["name"], h_type_implies_unix_fd=self._h_type_implies_unix_fd
+                )
                 self._cur_object.methods.append(method)
                 self._cur_object = method
             elif name == DBusXMLParser.STATE_SIGNAL:
                 self.state = DBusXMLParser.STATE_SIGNAL
-                signal = dbustypes.Signal(attrs['name'])
+                signal = dbustypes.Signal(attrs["name"])
                 self._cur_object.signals.append(signal)
                 self._cur_object = signal
             elif name == DBusXMLParser.STATE_PROPERTY:
                 self.state = DBusXMLParser.STATE_PROPERTY
-                prop = dbustypes.Property(attrs['name'], attrs['type'], attrs['access'])
+                prop = dbustypes.Property(attrs["name"], attrs["type"], attrs["access"])
                 self._cur_object.properties.append(prop)
                 self._cur_object = prop
             elif name == DBusXMLParser.STATE_ANNOTATION:
                 self.state = DBusXMLParser.STATE_ANNOTATION
-                anno = dbustypes.Annotation(attrs['name'], attrs['value'])
+                anno = dbustypes.Annotation(attrs["name"], attrs["value"])
                 self._cur_object.annotations.append(anno)
                 self._cur_object = anno
             else:
                 self.state = DBusXMLParser.STATE_IGNORED
 
             # assign docs, if any
-            if 'name' in attrs and self.doc_comment_last_symbol == attrs['name']:
+            if "name" in attrs and self.doc_comment_last_symbol == attrs["name"]:
                 self._cur_object.doc_string = self.doc_comment_body
-                if 'since' in self.doc_comment_params:
-                    self._cur_object.since = \
-                        self.doc_comment_params['since'].strip()
+                if "since" in self.doc_comment_params:
+                    self._cur_object.since = self.doc_comment_params["since"].strip()
 
         elif self.state == DBusXMLParser.STATE_METHOD:
             if name == DBusXMLParser.STATE_ARG:
                 self.state = DBusXMLParser.STATE_ARG
                 arg_name = None
-                if 'name' in attrs:
-                    arg_name = attrs['name']
-                arg = dbustypes.Arg(arg_name, attrs['type'])
-                direction = attrs.get('direction', 'in')
-                if direction == 'in':
+                if "name" in attrs:
+                    arg_name = attrs["name"]
+                arg = dbustypes.Arg(arg_name, attrs["type"])
+                direction = attrs.get("direction", "in")
+                if direction == "in":
                     self._cur_object.in_args.append(arg)
-                elif direction == 'out':
+                elif direction == "out":
                     self._cur_object.out_args.append(arg)
                 else:
                     print_error('Invalid direction "{}"'.format(direction))
                 self._cur_object = arg
             elif name == DBusXMLParser.STATE_ANNOTATION:
                 self.state = DBusXMLParser.STATE_ANNOTATION
-                anno = dbustypes.Annotation(attrs['name'], attrs['value'])
+                anno = dbustypes.Annotation(attrs["name"], attrs["value"])
                 self._cur_object.annotations.append(anno)
                 self._cur_object = anno
             else:
@@ -219,26 +219,27 @@ class DBusXMLParser:
 
             # assign docs, if any
             if self.doc_comment_last_symbol == old_cur_object.name:
-                if 'name' in attrs and attrs['name'] in self.doc_comment_params:
-                    doc_string = self.doc_comment_params[attrs['name']]
-                    if doc_string != None:
+                if "name" in attrs and attrs["name"] in self.doc_comment_params:
+                    doc_string = self.doc_comment_params[attrs["name"]]
+                    if doc_string is not None:
                         self._cur_object.doc_string = doc_string
-                    if 'since' in self.doc_comment_params:
-                        self._cur_object.since = \
-                            self.doc_comment_params['since'].strip()
+                    if "since" in self.doc_comment_params:
+                        self._cur_object.since = self.doc_comment_params[
+                            "since"
+                        ].strip()
 
         elif self.state == DBusXMLParser.STATE_SIGNAL:
             if name == DBusXMLParser.STATE_ARG:
                 self.state = DBusXMLParser.STATE_ARG
                 arg_name = None
-                if 'name' in attrs:
-                    arg_name = attrs['name']
-                arg = dbustypes.Arg(arg_name, attrs['type'])
+                if "name" in attrs:
+                    arg_name = attrs["name"]
+                arg = dbustypes.Arg(arg_name, attrs["type"])
                 self._cur_object.args.append(arg)
                 self._cur_object = arg
             elif name == DBusXMLParser.STATE_ANNOTATION:
                 self.state = DBusXMLParser.STATE_ANNOTATION
-                anno = dbustypes.Annotation(attrs['name'], attrs['value'])
+                anno = dbustypes.Annotation(attrs["name"], attrs["value"])
                 self._cur_object.annotations.append(anno)
                 self._cur_object = anno
             else:
@@ -246,18 +247,19 @@ class DBusXMLParser:
 
             # assign docs, if any
             if self.doc_comment_last_symbol == old_cur_object.name:
-                if 'name' in attrs and attrs['name'] in self.doc_comment_params:
-                    doc_string = self.doc_comment_params[attrs['name']]
-                    if doc_string != None:
+                if "name" in attrs and attrs["name"] in self.doc_comment_params:
+                    doc_string = self.doc_comment_params[attrs["name"]]
+                    if doc_string is not None:
                         self._cur_object.doc_string = doc_string
-                    if 'since' in self.doc_comment_params:
-                        self._cur_object.since = \
-                            self.doc_comment_params['since'].strip()
+                    if "since" in self.doc_comment_params:
+                        self._cur_object.since = self.doc_comment_params[
+                            "since"
+                        ].strip()
 
         elif self.state == DBusXMLParser.STATE_PROPERTY:
             if name == DBusXMLParser.STATE_ANNOTATION:
                 self.state = DBusXMLParser.STATE_ANNOTATION
-                anno = dbustypes.Annotation(attrs['name'], attrs['value'])
+                anno = dbustypes.Annotation(attrs["name"], attrs["value"])
                 self._cur_object.annotations.append(anno)
                 self._cur_object = anno
             else:
@@ -266,7 +268,7 @@ class DBusXMLParser:
         elif self.state == DBusXMLParser.STATE_ARG:
             if name == DBusXMLParser.STATE_ANNOTATION:
                 self.state = DBusXMLParser.STATE_ANNOTATION
-                anno = dbustypes.Annotation(attrs['name'], attrs['value'])
+                anno = dbustypes.Annotation(attrs["name"], attrs["value"])
                 self._cur_object.annotations.append(anno)
                 self._cur_object = anno
             else:
@@ -275,14 +277,18 @@ class DBusXMLParser:
         elif self.state == DBusXMLParser.STATE_ANNOTATION:
             if name == DBusXMLParser.STATE_ANNOTATION:
                 self.state = DBusXMLParser.STATE_ANNOTATION
-                anno = dbustypes.Annotation(attrs['name'], attrs['value'])
+                anno = dbustypes.Annotation(attrs["name"], attrs["value"])
                 self._cur_object.annotations.append(anno)
                 self._cur_object = anno
             else:
                 self.state = DBusXMLParser.STATE_IGNORED
 
         else:
-            print_error('Unhandled state "{}" while entering element with name "{}"'.format(self.state, name))
+            print_error(
+                'Unhandled state "{}" while entering element with name "{}"'.format(
+                    self.state, name
+                )
+            )
 
         self.state_stack.append(old_state)
         self._cur_object_stack.append(old_cur_object)
@@ -291,6 +297,7 @@ class DBusXMLParser:
         self.state = self.state_stack.pop()
         self._cur_object = self._cur_object_stack.pop()
 
+
 def parse_dbus_xml(xml_data, h_type_implies_unix_fd):
     parser = DBusXMLParser(xml_data, h_type_implies_unix_fd)
     return parser.parsed_interfaces
index 95ba107..95559d3 100644 (file)
@@ -23,49 +23,58 @@ import distutils.version
 import os
 import sys
 
+
 # pylint: disable=too-few-public-methods
 class Color:
-    '''ANSI Terminal colors'''
-    GREEN = '\033[1;32m'
-    BLUE = '\033[1;34m'
-    YELLOW = '\033[1;33m'
-    RED = '\033[1;31m'
-    END = '\033[0m'
-
-def print_color(msg, color=Color.END, prefix='MESSAGE'):
-    '''Print a string with a color prefix'''
+    """ANSI Terminal colors"""
+
+    GREEN = "\033[1;32m"
+    BLUE = "\033[1;34m"
+    YELLOW = "\033[1;33m"
+    RED = "\033[1;31m"
+    END = "\033[0m"
+
+
+def print_color(msg, color=Color.END, prefix="MESSAGE"):
+    """Print a string with a color prefix"""
     if os.isatty(sys.stderr.fileno()):
-        real_prefix = '{start}{prefix}{end}'.format(start=color, prefix=prefix, end=Color.END)
+        real_prefix = "{start}{prefix}{end}".format(
+            start=color, prefix=prefix, end=Color.END
+        )
     else:
         real_prefix = prefix
-    sys.stderr.write('{prefix}: {msg}\n'.format(prefix=real_prefix, msg=msg))
+    sys.stderr.write("{prefix}: {msg}\n".format(prefix=real_prefix, msg=msg))
+
 
 def print_error(msg):
-    '''Print an error, and terminate'''
-    print_color(msg, color=Color.RED, prefix='ERROR')
+    """Print an error, and terminate"""
+    print_color(msg, color=Color.RED, prefix="ERROR")
     sys.exit(1)
 
+
 def print_warning(msg, fatal=False):
-    '''Print a warning, and optionally terminate'''
+    """Print a warning, and optionally terminate"""
     if fatal:
         color = Color.RED
-        prefix = 'ERROR'
+        prefix = "ERROR"
     else:
         color = Color.YELLOW
-        prefix = 'WARNING'
+        prefix = "WARNING"
     print_color(msg, color, prefix)
     if fatal:
         sys.exit(1)
 
+
 def print_info(msg):
-    '''Print a message'''
-    print_color(msg, color=Color.GREEN, prefix='INFO')
+    """Print a message"""
+    print_color(msg, color=Color.GREEN, prefix="INFO")
+
 
 def strip_dots(s):
-    ret = ''
+    ret = ""
     force_upper = False
     for c in s:
-        if c == '.':
+        if c == ".":
             force_upper = True
         else:
             if force_upper:
@@ -75,19 +84,21 @@ def strip_dots(s):
                 ret += c
     return ret
 
+
 def dots_to_hyphens(s):
-    return s.replace('.', '-')
+    return s.replace(".", "-")
+
 
 def camel_case_to_uscore(s):
-    ret = ''
+    ret = ""
     insert_uscore = False
     prev_was_lower = False
-    initial = True;
+    initial = True
     for c in s:
         # Keep initial underscores in camel case
-        if initial and c == '_':
-            ret += '_'
-            continue;
+        if initial and c == "_":
+            ret += "_"
+            continue
         initial = False
 
         if c.isupper():
@@ -97,16 +108,18 @@ def camel_case_to_uscore(s):
         else:
             prev_was_lower = True
         if insert_uscore:
-            ret += '_'
+            ret += "_"
         ret += c.lower()
         insert_uscore = False
     return ret
 
+
 def is_ugly_case(s):
-    if s and s.find('_') > 0:
+    if s and s.find("_") > 0:
         return True
     return False
 
+
 def lookup_annotation(annotations, key):
     if annotations:
         for a in annotations:
@@ -114,35 +127,39 @@ def lookup_annotation(annotations, key):
                 return a.value
     return None
 
+
 def lookup_docs(annotations):
-    s = lookup_annotation(annotations, 'org.gtk.GDBus.DocString')
+    s = lookup_annotation(annotations, "org.gtk.GDBus.DocString")
     if s is None:
-        return ''
+        return ""
     else:
         return s
 
+
 def lookup_since(annotations):
-    s = lookup_annotation(annotations, 'org.gtk.GDBus.Since')
+    s = lookup_annotation(annotations, "org.gtk.GDBus.Since")
     if s is None:
-        return ''
+        return ""
     else:
         return s
 
+
 def lookup_brief_docs(annotations):
-    s = lookup_annotation(annotations, 'org.gtk.GDBus.DocString.Short')
+    s = lookup_annotation(annotations, "org.gtk.GDBus.DocString.Short")
     if s is None:
-        return ''
+        return ""
     else:
         return s
 
+
 def version_cmp_key(key):
     # If the 'since' version is 'UNRELEASED', compare higher than anything else
     # If it is empty put a 0 in its place as this will
     # allow LooseVersion to work and will always compare lower.
-    if key[0] == 'UNRELEASED':
-        v = '9999'
+    if key[0] == "UNRELEASED":
+        v = "9999"
     elif key[0]:
         v = str(key[0])
     else:
-        v = '0'
+        v = "0"
     return (distutils.version.LooseVersion(v), key[1])
index 863a5e8..78198df 100644 (file)
 
 #include <gio/gio.h>
 
+#ifdef G_OS_UNIX
+#include <gio/gunixfdlist.h>
+#endif
+
 #include <gi18n.h>
 
 #ifdef G_OS_WIN32
@@ -905,6 +909,10 @@ handle_call (gint        *argc,
   gchar *method_name;
   GVariant *result;
   GPtrArray *in_signature_types;
+#ifdef G_OS_UNIX
+  GUnixFDList *fd_list;
+  guint fd_id;
+#endif
   gboolean complete_names;
   gboolean complete_paths;
   gboolean complete_methods;
@@ -920,6 +928,9 @@ handle_call (gint        *argc,
   method_name = NULL;
   result = NULL;
   in_signature_types = NULL;
+#ifdef G_OS_UNIX
+  fd_list = NULL;
+#endif
 
   modify_argv0_for_command (argc, argv, "call");
 
@@ -1164,6 +1175,23 @@ handle_call (gint        *argc,
             }
           g_free (context);
         }
+#ifdef G_OS_UNIX
+      if (g_variant_is_of_type (value, G_VARIANT_TYPE_HANDLE))
+        {
+          if (!fd_list)
+            fd_list = g_unix_fd_list_new ();
+          if ((fd_id = g_unix_fd_list_append (fd_list, g_variant_get_handle (value), &error)) == -1)
+            {
+              g_printerr (_("Error adding handle %d: %s\n"),
+                          g_variant_get_handle (value), error->message);
+              g_variant_builder_clear (&builder);
+              g_error_free (error);
+              goto out;
+            } 
+         g_variant_unref (value);
+          value = g_variant_new_handle (fd_id);
+       }
+#endif
       g_variant_builder_add_value (&builder, value);
       ++parm;
     }
@@ -1171,17 +1199,33 @@ handle_call (gint        *argc,
 
   if (parameters != NULL)
     parameters = g_variant_ref_sink (parameters);
+#ifdef G_OS_UNIX
+  result = g_dbus_connection_call_with_unix_fd_list_sync (c,
+                                                          opt_call_dest,
+                                                          opt_call_object_path,
+                                                          interface_name,
+                                                          method_name,
+                                                          parameters,
+                                                          NULL,
+                                                          G_DBUS_CALL_FLAGS_NONE,
+                                                          opt_call_timeout > 0 ? opt_call_timeout * 1000 : opt_call_timeout,
+                                                          fd_list,
+                                                          NULL,
+                                                          NULL,
+                                                          &error);
+#else
   result = g_dbus_connection_call_sync (c,
-                                        opt_call_dest,
-                                        opt_call_object_path,
-                                        interface_name,
-                                        method_name,
-                                        parameters,
-                                        NULL,
-                                        G_DBUS_CALL_FLAGS_NONE,
-                                        opt_call_timeout > 0 ? opt_call_timeout * 1000 : opt_call_timeout,
-                                        NULL,
-                                        &error);
+                                       opt_call_dest,
+                                       opt_call_object_path,
+                                       interface_name,
+                                       method_name,
+                                       parameters,
+                                       NULL,
+                                       G_DBUS_CALL_FLAGS_NONE,
+                                       opt_call_timeout > 0 ? opt_call_timeout * 1000 : opt_call_timeout,
+                                       NULL,
+                                       &error);
+#endif
   if (result == NULL)
     {
       g_printerr (_("Error: %s\n"), error->message);
@@ -1230,6 +1274,9 @@ handle_call (gint        *argc,
   g_free (interface_name);
   g_free (method_name);
   g_option_context_free (o);
+#ifdef G_OS_UNIX
+  g_clear_object (&fd_list);
+#endif
   return ret;
 }
 
index baa4e59..095a666 100644 (file)
@@ -40,6 +40,7 @@
 #include "gioenumtypes.h"
 #include "gioerror.h"
 #include "gdbusprivate.h"
+#include "glib-private.h"
 
 #include "glibintl.h"
 
@@ -265,6 +266,7 @@ ensure_keyring_directory (GError **error)
 {
   gchar *path;
   const gchar *e;
+  gboolean is_setuid;
 #ifdef G_OS_UNIX
   struct stat statbuf;
 #endif
@@ -332,7 +334,10 @@ ensure_keyring_directory (GError **error)
     }
 #endif  /* if !G_OS_UNIX */
 
-  if (g_mkdir_with_parents (path, 0700) != 0)
+  /* Only create the directory if not running as setuid */
+  is_setuid = GLIB_PRIVATE_CALL (g_check_setuid) ();
+  if (!is_setuid &&
+      g_mkdir_with_parents (path, 0700) != 0)
     {
       int errsv = errno;
       g_set_error (error,
@@ -344,6 +349,17 @@ ensure_keyring_directory (GError **error)
       g_clear_pointer (&path, g_free);
       return NULL;
     }
+  else if (is_setuid)
+    {
+      g_set_error (error,
+                   G_IO_ERROR,
+                   G_IO_ERROR_PERMISSION_DENIED,
+                   _("Error creating directory “%s”: %s"),
+                   path,
+                   _("Operation not supported"));
+      g_clear_pointer (&path, g_free);
+      return NULL;
+    }
 
   return g_steal_pointer (&path);
 }
index 54aaf43..65939a4 100644 (file)
@@ -393,7 +393,7 @@ struct _GDBusConnection
    * FLAG_CLOSED is the closed property. It may be read at any time, but
    * may only be written while holding @lock.
    */
-  volatile gint atomic_flags;
+  gint atomic_flags;  /* (atomic) */
 
   /* If the connection could not be established during initable_init(),
    * this GError will be set.
@@ -1596,7 +1596,7 @@ static gboolean
 g_dbus_connection_send_message_unlocked (GDBusConnection   *connection,
                                          GDBusMessage      *message,
                                          GDBusSendMessageFlags flags,
-                                         volatile guint32  *out_serial,
+                                         guint32           *out_serial,
                                          GError           **error)
 {
   guchar *blob;
@@ -1708,7 +1708,9 @@ g_dbus_connection_send_message_unlocked (GDBusConnection   *connection,
  * will be assigned by @connection and set on @message via
  * g_dbus_message_set_serial(). If @out_serial is not %NULL, then the
  * serial number used will be written to this location prior to
- * submitting the message to the underlying transport.
+ * submitting the message to the underlying transport. While it has a `volatile`
+ * qualifier, this is a historical artifact and the argument passed to it should
+ * not be `volatile`.
  *
  * If @connection is closed then the operation will fail with
  * %G_IO_ERROR_CLOSED. If @message is not well-formed,
@@ -1741,7 +1743,7 @@ g_dbus_connection_send_message (GDBusConnection        *connection,
   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
   CONNECTION_LOCK (connection);
-  ret = g_dbus_connection_send_message_unlocked (connection, message, flags, out_serial, error);
+  ret = g_dbus_connection_send_message_unlocked (connection, message, flags, (guint32 *) out_serial, error);
   CONNECTION_UNLOCK (connection);
   return ret;
 }
@@ -1901,7 +1903,7 @@ g_dbus_connection_send_message_with_reply_unlocked (GDBusConnection     *connect
                                                     GDBusMessage        *message,
                                                     GDBusSendMessageFlags flags,
                                                     gint                 timeout_msec,
-                                                    volatile guint32    *out_serial,
+                                                    guint32             *out_serial,
                                                     GCancellable        *cancellable,
                                                     GAsyncReadyCallback  callback,
                                                     gpointer             user_data)
@@ -1909,7 +1911,7 @@ g_dbus_connection_send_message_with_reply_unlocked (GDBusConnection     *connect
   GTask *task;
   SendMessageData *data;
   GError *error = NULL;
-  volatile guint32 serial;
+  guint32 serial;
 
   if (out_serial == NULL)
     out_serial = &serial;
@@ -1979,7 +1981,9 @@ g_dbus_connection_send_message_with_reply_unlocked (GDBusConnection     *connect
  * will be assigned by @connection and set on @message via
  * g_dbus_message_set_serial(). If @out_serial is not %NULL, then the
  * serial number used will be written to this location prior to
- * submitting the message to the underlying transport.
+ * submitting the message to the underlying transport. While it has a `volatile`
+ * qualifier, this is a historical artifact and the argument passed to it should
+ * not be `volatile`.
  *
  * If @connection is closed then the operation will fail with
  * %G_IO_ERROR_CLOSED. If @cancellable is canceled, the operation will
@@ -2022,7 +2026,7 @@ g_dbus_connection_send_message_with_reply (GDBusConnection       *connection,
                                                       message,
                                                       flags,
                                                       timeout_msec,
-                                                      out_serial,
+                                                      (guint32 *) out_serial,
                                                       cancellable,
                                                       callback,
                                                       user_data);
@@ -2105,7 +2109,9 @@ send_message_with_reply_sync_cb (GDBusConnection *connection,
  * will be assigned by @connection and set on @message via
  * g_dbus_message_set_serial(). If @out_serial is not %NULL, then the
  * serial number used will be written to this location prior to
- * submitting the message to the underlying transport.
+ * submitting the message to the underlying transport. While it has a `volatile`
+ * qualifier, this is a historical artifact and the argument passed to it should
+ * not be `volatile`.
  *
  * If @connection is closed then the operation will fail with
  * %G_IO_ERROR_CLOSED. If @cancellable is canceled, the operation will
@@ -3082,7 +3088,7 @@ g_dbus_connection_get_peer_credentials (GDBusConnection *connection)
 
 /* ---------------------------------------------------------------------------------------------------- */
 
-static volatile guint _global_filter_id = 1;
+static guint _global_filter_id = 1;  /* (atomic) */
 
 /**
  * g_dbus_connection_add_filter:
@@ -3327,9 +3333,9 @@ args_to_rule (const gchar      *sender,
   return g_string_free (rule, FALSE);
 }
 
-static volatile guint _global_subscriber_id = 1;
-static volatile guint _global_registration_id = 1;
-static volatile guint _global_subtree_registration_id = 1;
+static guint _global_subscriber_id = 1;  /* (atomic) */
+static guint _global_registration_id = 1;  /* (atomic) */
+static guint _global_subtree_registration_id = 1;  /* (atomic) */
 
 /* ---------------------------------------------------------------------------------------------------- */
 
@@ -5992,7 +5998,7 @@ g_dbus_connection_call_sync_internal (GDBusConnection         *connection,
                                                           message,
                                                           send_flags,
                                                           timeout_msec,
-                                                          NULL, /* volatile guint32 *out_serial */
+                                                          NULL, /* guint32 *out_serial */
                                                           cancellable,
                                                           &local_error);
 
@@ -6248,6 +6254,18 @@ g_dbus_connection_call_sync (GDBusConnection     *connection,
  *
  * Like g_dbus_connection_call() but also takes a #GUnixFDList object.
  *
+ * The file descriptors normally correspond to %G_VARIANT_TYPE_HANDLE
+ * values in the body of the message. For example, if a message contains
+ * two file descriptors, @fd_list would have length 2, and
+ * `g_variant_new_handle (0)` and `g_variant_new_handle (1)` would appear
+ * somewhere in the body of the message (not necessarily in that order!)
+ * to represent the file descriptors at indexes 0 and 1 respectively.
+ *
+ * When designing D-Bus APIs that are intended to be interoperable,
+ * please note that non-GDBus implementations of D-Bus can usually only
+ * access file descriptors if they are referenced in this way by a
+ * value of type %G_VARIANT_TYPE_HANDLE in the body of the message.
+ *
  * This method is only available on UNIX.
  *
  * Since: 2.30
@@ -6280,6 +6298,17 @@ g_dbus_connection_call_with_unix_fd_list (GDBusConnection     *connection,
  *
  * Finishes an operation started with g_dbus_connection_call_with_unix_fd_list().
  *
+ * The file descriptors normally correspond to %G_VARIANT_TYPE_HANDLE
+ * values in the body of the message. For example,
+ * if g_variant_get_handle() returns 5, that is intended to be a reference
+ * to the file descriptor that can be accessed by
+ * `g_unix_fd_list_get (*out_fd_list, 5, ...)`.
+ *
+ * When designing D-Bus APIs that are intended to be interoperable,
+ * please note that non-GDBus implementations of D-Bus can usually only
+ * access file descriptors if they are referenced in this way by a
+ * value of type %G_VARIANT_TYPE_HANDLE in the body of the message.
+ *
  * Returns: %NULL if @error is set. Otherwise a #GVariant tuple with
  *     return values. Free with g_variant_unref().
  *
@@ -6314,6 +6343,8 @@ g_dbus_connection_call_with_unix_fd_list_finish (GDBusConnection  *connection,
  * @error: return location for error or %NULL
  *
  * Like g_dbus_connection_call_sync() but also takes and returns #GUnixFDList objects.
+ * See g_dbus_connection_call_with_unix_fd_list() and
+ * g_dbus_connection_call_with_unix_fd_list_finish() for more details.
  *
  * This method is only available on UNIX.
  *
index 6826773..4ad97bb 100644 (file)
  * GQuark
  * foo_bar_error_quark (void)
  * {
- *   static volatile gsize quark_volatile = 0;
+ *   static gsize quark = 0;
  *   g_dbus_error_register_error_domain ("foo-bar-error-quark",
- *                                       &quark_volatile,
+ *                                       &quark,
  *                                       foo_bar_error_entries,
  *                                       G_N_ELEMENTS (foo_bar_error_entries));
- *   return (GQuark) quark_volatile;
+ *   return (GQuark) quark;
  * }
  * ]|
  * With this setup, a D-Bus peer can transparently pass e.g. %FOO_BAR_ERROR_ANOTHER_ERROR and
@@ -160,12 +160,12 @@ GQuark
 g_dbus_error_quark (void)
 {
   G_STATIC_ASSERT (G_N_ELEMENTS (g_dbus_error_entries) - 1 == G_DBUS_ERROR_PROPERTY_READ_ONLY);
-  static volatile gsize quark_volatile = 0;
+  static gsize quark = 0;
   g_dbus_error_register_error_domain ("g-dbus-error-quark",
-                                      &quark_volatile,
+                                      &quark,
                                       g_dbus_error_entries,
                                       G_N_ELEMENTS (g_dbus_error_entries));
-  return (GQuark) quark_volatile;
+  return (GQuark) quark;
 }
 
 /**
@@ -177,6 +177,9 @@ g_dbus_error_quark (void)
  *
  * Helper function for associating a #GError error domain with D-Bus error names.
  *
+ * While @quark_volatile has a `volatile` qualifier, this is a historical
+ * artifact and the argument passed to it should not be `volatile`.
+ *
  * Since: 2.26
  */
 void
@@ -185,25 +188,31 @@ g_dbus_error_register_error_domain (const gchar           *error_domain_quark_na
                                     const GDBusErrorEntry *entries,
                                     guint                  num_entries)
 {
+  gsize *quark;
+
   g_return_if_fail (error_domain_quark_name != NULL);
   g_return_if_fail (quark_volatile != NULL);
   g_return_if_fail (entries != NULL);
   g_return_if_fail (num_entries > 0);
 
-  if (g_once_init_enter (quark_volatile))
+  /* Drop the volatile qualifier, which should never have been on the argument
+   * in the first place. */
+  quark = (gsize *) quark_volatile;
+
+  if (g_once_init_enter (quark))
     {
       guint n;
-      GQuark quark;
+      GQuark new_quark;
 
-      quark = g_quark_from_static_string (error_domain_quark_name);
+      new_quark = g_quark_from_static_string (error_domain_quark_name);
 
       for (n = 0; n < num_entries; n++)
         {
-          g_warn_if_fail (g_dbus_error_register_error (quark,
+          g_warn_if_fail (g_dbus_error_register_error (new_quark,
                                                        entries[n].error_code,
                                                        entries[n].dbus_error_name));
         }
-      g_once_init_leave (quark_volatile, quark);
+      g_once_init_leave (quark, new_quark);
     }
 }
 
index fa03115..35fa8e4 100644 (file)
@@ -73,7 +73,7 @@ g_dbus_interface_get_info (GDBusInterface *interface_)
  * the returned object is being used from other threads. See
  * g_dbus_interface_dup_object() for a thread-safe alternative.
  *
- * Returns: (transfer none): A #GDBusObject or %NULL. The returned
+ * Returns: (nullable) (transfer none): A #GDBusObject or %NULL. The returned
  *     reference belongs to @interface_ and should not be freed.
  *
  * Since: 2.30
@@ -91,7 +91,7 @@ g_dbus_interface_get_object (GDBusInterface *interface_)
  *
  * Gets the #GDBusObject that @interface_ belongs to, if any.
  *
- * Returns: (transfer full): A #GDBusObject or %NULL. The returned
+ * Returns: (nullable) (transfer full): A #GDBusObject or %NULL. The returned
  * reference should be freed with g_object_unref().
  *
  * Since: 2.32
index a0125c5..76398df 100644 (file)
@@ -458,7 +458,7 @@ dbus_interface_interface_init (GDBusInterfaceIface *iface)
 
 typedef struct
 {
-  volatile gint ref_count;
+  gint ref_count;  /* (atomic) */
   GDBusInterfaceSkeleton       *interface;
   GDBusInterfaceMethodCallFunc  method_call_func;
   GDBusMethodInvocation        *invocation;
@@ -767,7 +767,7 @@ set_object_path_locked (GDBusInterfaceSkeleton *interface_,
  *
  * Gets the first connection that @interface_ is exported on, if any.
  *
- * Returns: (transfer none): A #GDBusConnection or %NULL if @interface_ is
+ * Returns: (nullable) (transfer none): A #GDBusConnection or %NULL if @interface_ is
  * not exported anywhere. Do not free, the object belongs to @interface_.
  *
  * Since: 2.30
@@ -876,7 +876,7 @@ g_dbus_interface_skeleton_has_connection (GDBusInterfaceSkeleton     *interface_
  *
  * Gets the object path that @interface_ is exported on, if any.
  *
- * Returns: A string owned by @interface_ or %NULL if @interface_ is not exported
+ * Returns: (nullable): A string owned by @interface_ or %NULL if @interface_ is not exported
  * anywhere. Do not free, the string belongs to @interface_.
  *
  * Since: 2.30
index dde0642..f35b2fb 100644 (file)
@@ -1847,7 +1847,7 @@ g_dbus_node_info_new_for_xml (const gchar  *xml_data,
  *
  * The cost of this function is O(n) in number of annotations.
  *
- * Returns: The value or %NULL if not found. Do not free, it is owned by @annotations.
+ * Returns: (nullable): The value or %NULL if not found. Do not free, it is owned by @annotations.
  *
  * Since: 2.26
  */
@@ -1915,7 +1915,7 @@ static GHashTable *info_cache = NULL;
  * The cost of this function is O(n) in number of methods unless
  * g_dbus_interface_info_cache_build() has been used on @info.
  *
- * Returns: (transfer none): A #GDBusMethodInfo or %NULL if not found. Do not free, it is owned by @info.
+ * Returns: (nullable) (transfer none): A #GDBusMethodInfo or %NULL if not found. Do not free, it is owned by @info.
  *
  * Since: 2.26
  */
@@ -1969,7 +1969,7 @@ g_dbus_interface_info_lookup_method (GDBusInterfaceInfo *info,
  * The cost of this function is O(n) in number of signals unless
  * g_dbus_interface_info_cache_build() has been used on @info.
  *
- * Returns: (transfer none): A #GDBusSignalInfo or %NULL if not found. Do not free, it is owned by @info.
+ * Returns: (nullable) (transfer none): A #GDBusSignalInfo or %NULL if not found. Do not free, it is owned by @info.
  *
  * Since: 2.26
  */
@@ -2023,7 +2023,7 @@ g_dbus_interface_info_lookup_signal (GDBusInterfaceInfo *info,
  * The cost of this function is O(n) in number of properties unless
  * g_dbus_interface_info_cache_build() has been used on @info.
  *
- * Returns: (transfer none): A #GDBusPropertyInfo or %NULL if not found. Do not free, it is owned by @info.
+ * Returns: (nullable) (transfer none): A #GDBusPropertyInfo or %NULL if not found. Do not free, it is owned by @info.
  *
  * Since: 2.26
  */
@@ -2165,7 +2165,7 @@ g_dbus_interface_info_cache_release (GDBusInterfaceInfo *info)
  *
  * The cost of this function is O(n) in number of interfaces.
  *
- * Returns: (transfer none): A #GDBusInterfaceInfo or %NULL if not found. Do not free, it is owned by @info.
+ * Returns: (nullable) (transfer none): A #GDBusInterfaceInfo or %NULL if not found. Do not free, it is owned by @info.
  *
  * Since: 2.26
  */
index 14b1710..f2e2917 100644 (file)
@@ -43,7 +43,7 @@ G_BEGIN_DECLS
 struct _GDBusAnnotationInfo
 {
   /*< public >*/
-  volatile gint         ref_count;
+  gint                  ref_count;  /* (atomic) */
   gchar                *key;
   gchar                *value;
   GDBusAnnotationInfo **annotations;
@@ -63,7 +63,7 @@ struct _GDBusAnnotationInfo
 struct _GDBusArgInfo
 {
   /*< public >*/
-  volatile gint         ref_count;
+  gint                  ref_count;  /* (atomic) */
   gchar                *name;
   gchar                *signature;
   GDBusAnnotationInfo **annotations;
@@ -84,7 +84,7 @@ struct _GDBusArgInfo
 struct _GDBusMethodInfo
 {
   /*< public >*/
-  volatile gint         ref_count;
+  gint                  ref_count;  /* (atomic) */
   gchar                *name;
   GDBusArgInfo        **in_args;
   GDBusArgInfo        **out_args;
@@ -105,7 +105,7 @@ struct _GDBusMethodInfo
 struct _GDBusSignalInfo
 {
   /*< public >*/
-  volatile gint         ref_count;
+  gint                  ref_count;  /* (atomic) */
   gchar                *name;
   GDBusArgInfo        **args;
   GDBusAnnotationInfo **annotations;
@@ -126,7 +126,7 @@ struct _GDBusSignalInfo
 struct _GDBusPropertyInfo
 {
   /*< public >*/
-  volatile gint             ref_count;
+  gint                      ref_count;  /* (atomic) */
   gchar                    *name;
   gchar                    *signature;
   GDBusPropertyInfoFlags    flags;
@@ -149,7 +149,7 @@ struct _GDBusPropertyInfo
 struct _GDBusInterfaceInfo
 {
   /*< public >*/
-  volatile gint         ref_count;
+  gint                  ref_count;  /* (atomic) */
   gchar                *name;
   GDBusMethodInfo     **methods;
   GDBusSignalInfo     **signals;
@@ -172,7 +172,7 @@ struct _GDBusInterfaceInfo
 struct _GDBusNodeInfo
 {
   /*< public >*/
-  volatile gint         ref_count;
+  gint                  ref_count;  /* (atomic) */
   gchar                *path;
   GDBusInterfaceInfo  **interfaces;
   GDBusNodeInfo       **nodes;
index 0e4878d..bc9386e 100644 (file)
@@ -1085,7 +1085,7 @@ g_dbus_message_get_header_fields (GDBusMessage  *message)
  *
  * Gets the body of a message.
  *
- * Returns: (transfer none): A #GVariant or %NULL if the body is
+ * Returns: (nullable) (transfer none): A #GVariant or %NULL if the body is
  * empty. Do not free, it is owned by @message.
  *
  * Since: 2.26
@@ -1158,7 +1158,13 @@ g_dbus_message_set_body (GDBusMessage  *message,
  *
  * This method is only available on UNIX.
  *
- * Returns: (transfer none):A #GUnixFDList or %NULL if no file descriptors are
+ * The file descriptors normally correspond to %G_VARIANT_TYPE_HANDLE
+ * values in the body of the message. For example,
+ * if g_variant_get_handle() returns 5, that is intended to be a reference
+ * to the file descriptor that can be accessed by
+ * `g_unix_fd_list_get (list, 5, ...)`.
+ *
+ * Returns: (nullable) (transfer none): A #GUnixFDList or %NULL if no file descriptors are
  * associated. Do not free, this object is owned by @message.
  *
  * Since: 2.26
@@ -1182,6 +1188,11 @@ g_dbus_message_get_unix_fd_list (GDBusMessage  *message)
  *
  * This method is only available on UNIX.
  *
+ * When designing D-Bus APIs that are intended to be interoperable,
+ * please note that non-GDBus implementations of D-Bus can usually only
+ * access file descriptors if they are referenced by a value of type
+ * %G_VARIANT_TYPE_HANDLE in the body of the message.
+ *
  * Since: 2.26
  */
 void
@@ -2983,7 +2994,7 @@ g_dbus_message_set_reply_serial (GDBusMessage  *message,
  *
  * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE header field.
  *
- * Returns: The value.
+ * Returns: (nullable): The value.
  *
  * Since: 2.26
  */
@@ -2997,7 +3008,7 @@ g_dbus_message_get_interface (GDBusMessage  *message)
 /**
  * g_dbus_message_set_interface:
  * @message: A #GDBusMessage.
- * @value: The value to set.
+ * @value: (nullable): The value to set.
  *
  * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE header field.
  *
@@ -3020,7 +3031,7 @@ g_dbus_message_set_interface (GDBusMessage  *message,
  *
  * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_MEMBER header field.
  *
- * Returns: The value.
+ * Returns: (nullable): The value.
  *
  * Since: 2.26
  */
@@ -3034,7 +3045,7 @@ g_dbus_message_get_member (GDBusMessage  *message)
 /**
  * g_dbus_message_set_member:
  * @message: A #GDBusMessage.
- * @value: The value to set.
+ * @value: (nullable): The value to set.
  *
  * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_MEMBER header field.
  *
@@ -3057,7 +3068,7 @@ g_dbus_message_set_member (GDBusMessage  *message,
  *
  * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_PATH header field.
  *
- * Returns: The value.
+ * Returns: (nullable): The value.
  *
  * Since: 2.26
  */
@@ -3071,7 +3082,7 @@ g_dbus_message_get_path (GDBusMessage  *message)
 /**
  * g_dbus_message_set_path:
  * @message: A #GDBusMessage.
- * @value: The value to set.
+ * @value: (nullable): The value to set.
  *
  * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_PATH header field.
  *
@@ -3094,7 +3105,7 @@ g_dbus_message_set_path (GDBusMessage  *message,
  *
  * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_SENDER header field.
  *
- * Returns: The value.
+ * Returns: (nullable): The value.
  *
  * Since: 2.26
  */
@@ -3108,7 +3119,7 @@ g_dbus_message_get_sender (GDBusMessage *message)
 /**
  * g_dbus_message_set_sender:
  * @message: A #GDBusMessage.
- * @value: The value to set.
+ * @value: (nullable): The value to set.
  *
  * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_SENDER header field.
  *
@@ -3131,7 +3142,7 @@ g_dbus_message_set_sender (GDBusMessage  *message,
  *
  * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION header field.
  *
- * Returns: The value.
+ * Returns: (nullable): The value.
  *
  * Since: 2.26
  */
@@ -3145,7 +3156,7 @@ g_dbus_message_get_destination (GDBusMessage  *message)
 /**
  * g_dbus_message_set_destination:
  * @message: A #GDBusMessage.
- * @value: The value to set.
+ * @value: (nullable): The value to set.
  *
  * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION header field.
  *
@@ -3168,7 +3179,7 @@ g_dbus_message_set_destination (GDBusMessage  *message,
  *
  * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME header field.
  *
- * Returns: The value.
+ * Returns: (nullable): The value.
  *
  * Since: 2.26
  */
@@ -3181,7 +3192,7 @@ g_dbus_message_get_error_name (GDBusMessage  *message)
 
 /**
  * g_dbus_message_set_error_name:
- * @message: A #GDBusMessage.
+ * @message: (nullable): A #GDBusMessage.
  * @value: The value to set.
  *
  * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME header field.
@@ -3223,7 +3234,7 @@ g_dbus_message_get_signature (GDBusMessage  *message)
 /**
  * g_dbus_message_set_signature:
  * @message: A #GDBusMessage.
- * @value: The value to set.
+ * @value: (nullable): The value to set.
  *
  * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE header field.
  *
@@ -3246,7 +3257,7 @@ g_dbus_message_set_signature (GDBusMessage  *message,
  *
  * Convenience to get the first item in the body of @message.
  *
- * Returns: The string item or %NULL if the first item in the body of
+ * Returns: (nullable): The string item or %NULL if the first item in the body of
  * @message is not a string.
  *
  * Since: 2.26
index 18ae9d1..c22e19e 100644 (file)
@@ -194,7 +194,7 @@ g_dbus_method_invocation_get_interface_name (GDBusMethodInvocation *invocation)
  * returned.  See g_dbus_method_invocation_get_property_info() and
  * #GDBusInterfaceVTable for more information.
  *
- * Returns: A #GDBusMethodInfo or %NULL. Do not free, it is owned by @invocation.
+ * Returns: (nullable): A #GDBusMethodInfo or %NULL. Do not free, it is owned by @invocation.
  *
  * Since: 2.26
  */
@@ -221,7 +221,7 @@ g_dbus_method_invocation_get_method_info (GDBusMethodInvocation *invocation)
  *
  * If the call was GetAll, %NULL will be returned.
  *
- * Returns: (transfer none): a #GDBusPropertyInfo or %NULL
+ * Returns: (nullable) (transfer none): a #GDBusPropertyInfo or %NULL
  *
  * Since: 2.38
  */
index d20e6ff..1130d67 100644 (file)
@@ -55,7 +55,7 @@ typedef enum
 
 typedef struct
 {
-  volatile gint             ref_count;
+  gint                      ref_count;  /* (atomic) */
   guint                     id;
   GBusNameOwnerFlags        flags;
   gchar                    *name;
@@ -73,7 +73,7 @@ typedef struct
   guint                     name_acquired_subscription_id;
   guint                     name_lost_subscription_id;
 
-  volatile gboolean         cancelled; /* must hold lock when reading or modifying */
+  gboolean                  cancelled; /* must hold lock when reading or modifying */
 
   gboolean                  needs_release;
 } Client;
index bc2a911..8d24700 100644 (file)
@@ -56,7 +56,7 @@ typedef enum
 
 typedef struct
 {
-  volatile gint             ref_count;
+  gint                      ref_count;  /* (atomic) */
   guint                     id;
   gchar                    *name;
   GBusNameWatcherFlags      flags;
@@ -78,7 +78,7 @@ typedef struct
 } Client;
 
 /* Must be accessed atomically. */
-static volatile guint next_global_id = 1;
+static guint next_global_id = 1;  /* (atomic) */
 
 /* Must be accessed with @lock held. */
 static GHashTable *map_id_to_client = NULL;
index 32393ed..c332720 100644 (file)
@@ -137,7 +137,7 @@ g_dbus_object_get_interfaces (GDBusObject *object)
  * Gets the D-Bus interface with name @interface_name associated with
  * @object, if any.
  *
- * Returns: (transfer full): %NULL if not found, otherwise a
+ * Returns: (nullable) (transfer full): %NULL if not found, otherwise a
  *   #GDBusInterface that must be freed with g_object_unref().
  *
  * Since: 2.30
index 5c980b4..4e42c1a 100644 (file)
@@ -265,7 +265,7 @@ ensure_required_types (void)
 
 typedef struct
 {
-  volatile gint refcount;
+  gint refcount;  /* (atomic) */
   GThread *thread;
   GMainContext *context;
   GMainLoop *loop;
@@ -341,12 +341,12 @@ typedef enum {
 
 struct GDBusWorker
 {
-  volatile gint                       ref_count;
+  gint                                ref_count;  /* (atomic) */
 
   SharedThreadData                   *shared_thread_data;
 
   /* really a boolean, but GLib 2.28 lacks atomic boolean ops */
-  volatile gint                       stopped;
+  gint                                stopped;  /* (atomic) */
 
   /* TODO: frozen (e.g. G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING) currently
    * only affects messages received from the other peer (since GDBusServer is the
@@ -1085,8 +1085,11 @@ write_message_continue_writing (MessageToWriteData *data)
   else
     {
 #ifdef G_OS_UNIX
-      if (fd_list != NULL)
+      if (data->total_written == 0 && fd_list != NULL)
         {
+          /* We were trying to write byte 0 of the message, which needs
+           * the fd list to be attached to it, but this connection doesn't
+           * support doing that. */
           g_task_return_new_error (task,
                                    G_IO_ERROR,
                                    G_IO_ERROR_FAILED,
@@ -1938,15 +1941,14 @@ _g_dbus_debug_print_unlock (void)
 void
 _g_dbus_initialize (void)
 {
-  static volatile gsize initialized = 0;
+  static gsize initialized = 0;
 
   if (g_once_init_enter (&initialized))
     {
-      volatile GQuark g_dbus_error_domain;
       const gchar *debug;
 
-      g_dbus_error_domain = G_DBUS_ERROR;
-      (g_dbus_error_domain); /* To avoid -Wunused-but-set-variable */
+      /* Ensure the domain is registered. */
+      g_dbus_error_quark ();
 
       debug = g_getenv ("G_DBUS_DEBUG");
       if (debug != NULL)
index 4a8dab0..9009734 100644 (file)
@@ -71,7 +71,7 @@
  * To just export an object on a well-known name on a message bus, such as the
  * session or system bus, you should instead use g_bus_own_name().
  *
- * An example of peer-to-peer communication with G-DBus can be found
+ * An example of peer-to-peer communication with GDBus can be found
  * in [gdbus-example-peer.c](https://git.gnome.org/browse/glib/tree/gio/tests/gdbus-example-peer.c).
  *
  * Note that a minimal #GDBusServer will accept connections from any
index ff9b441..eb7eee9 100644 (file)
@@ -533,9 +533,9 @@ g_dbus_gvariant_to_gvalue (GVariant  *value,
  * See the g_dbus_gvariant_to_gvalue() function for how to convert a
  * #GVariant to a #GValue.
  *
- * Returns: A #GVariant (never floating) of #GVariantType @type holding
- *     the data from @gvalue or %NULL in case of failure. Free with
- *     g_variant_unref().
+ * Returns: (transfer full): A #GVariant (never floating) of
+ *     #GVariantType @type holding the data from @gvalue or an empty #GVariant
+ *     in case of failure. Free with g_variant_unref().
  *
  * Since: 2.30
  */
index b779b30..6b91854 100644 (file)
@@ -2107,7 +2107,7 @@ g_desktop_app_info_get_is_hidden (GDesktopAppInfo *info)
  * situations such as the #GDesktopAppInfo returned from
  * g_desktop_app_info_new_from_keyfile(), this function will return %NULL.
  *
- * Returns: (type filename): The full path to the file for @info,
+ * Returns: (nullable) (type filename): The full path to the file for @info,
  *     or %NULL if not known.
  * Since: 2.24
  */
@@ -2155,7 +2155,7 @@ g_desktop_app_info_get_icon (GAppInfo *appinfo)
  *
  * Gets the categories from the desktop file.
  *
- * Returns: The unparsed Categories key from the desktop file;
+ * Returns: (nullable): The unparsed Categories key from the desktop file;
  *     i.e. no attempt is made to split it by ';' or validate it.
  */
 const char *
@@ -2184,9 +2184,9 @@ g_desktop_app_info_get_keywords (GDesktopAppInfo *info)
  * g_desktop_app_info_get_generic_name:
  * @info: a #GDesktopAppInfo
  *
- * Gets the generic name from the destkop file.
+ * Gets the generic name from the desktop file.
  *
- * Returns: The value of the GenericName key
+ * Returns: (nullable): The value of the GenericName key
  */
 const char *
 g_desktop_app_info_get_generic_name (GDesktopAppInfo *info)
@@ -4679,7 +4679,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
  * WM_CLASS property of the main window of the application, if launched
  * through @info.
  *
- * Returns: (transfer none): the startup WM class, or %NULL if none is set
+ * Returns: (nullable) (transfer none): the startup WM class, or %NULL if none is set
  * in the desktop file.
  *
  * Since: 2.34
@@ -4701,7 +4701,7 @@ g_desktop_app_info_get_startup_wm_class (GDesktopAppInfo *info)
  *
  * The @key is looked up in the "Desktop Entry" group.
  *
- * Returns: a newly allocated string, or %NULL if the key
+ * Returns: (nullable): a newly allocated string, or %NULL if the key
  *     is not found
  *
  * Since: 2.36
index 48d4c82..2f28d48 100644 (file)
@@ -112,6 +112,19 @@ g_file_icon_set_property (GObject      *object,
 }
 
 static void
+g_file_icon_constructed (GObject *object)
+{
+#ifndef G_DISABLE_ASSERT
+  GFileIcon *icon = G_FILE_ICON (object);
+#endif
+
+  G_OBJECT_CLASS (g_file_icon_parent_class)->constructed (object);
+
+  /* Must have be set during construction */
+  g_assert (icon->file != NULL);
+}
+
+static void
 g_file_icon_finalize (GObject *object)
 {
   GFileIcon *icon;
@@ -132,6 +145,7 @@ g_file_icon_class_init (GFileIconClass *klass)
   gobject_class->get_property = g_file_icon_get_property;
   gobject_class->set_property = g_file_icon_set_property;
   gobject_class->finalize = g_file_icon_finalize;
+  gobject_class->constructed = g_file_icon_constructed;
 
   /**
    * GFileIcon:file:
@@ -174,7 +188,7 @@ g_file_icon_new (GFile *file)
  * 
  * Gets the #GFile associated with the given @icon.
  * 
- * Returns: (transfer none): a #GFile, or %NULL.
+ * Returns: (transfer none): a #GFile.
  **/
 GFile *
 g_file_icon_get_file (GFileIcon *icon)
index be465c8..1b008f7 100644 (file)
@@ -1652,7 +1652,7 @@ g_file_info_get_edit_name (GFileInfo *info)
  *
  * Gets the icon for a file.
  *
- * Returns: (transfer none): #GIcon for the given @info.
+ * Returns: (nullable) (transfer none): #GIcon for the given @info.
  **/
 GIcon *
 g_file_info_get_icon (GFileInfo *info)
@@ -1679,7 +1679,7 @@ g_file_info_get_icon (GFileInfo *info)
  *
  * Gets the symbolic icon for a file.
  *
- * Returns: (transfer none): #GIcon for the given @info.
+ * Returns: (nullable) (transfer none): #GIcon for the given @info.
  *
  * Since: 2.34
  **/
@@ -1835,7 +1835,7 @@ g_file_info_get_modification_date_time (GFileInfo *info)
  *
  * Gets the symlink target for a given #GFileInfo.
  *
- * Returns: a string containing the symlink target.
+ * Returns: (nullable): a string containing the symlink target.
  **/
 const char *
 g_file_info_get_symlink_target (GFileInfo *info)
@@ -1859,7 +1859,7 @@ g_file_info_get_symlink_target (GFileInfo *info)
  * Gets the [entity tag][gfile-etag] for a given
  * #GFileInfo. See %G_FILE_ATTRIBUTE_ETAG_VALUE.
  *
- * Returns: a string containing the value of the "etag:value" attribute.
+ * Returns: (nullable): a string containing the value of the "etag:value" attribute.
  **/
 const char *
 g_file_info_get_etag (GFileInfo *info)
@@ -2464,8 +2464,8 @@ g_file_attribute_matcher_new (const char *attributes)
 
 /**
  * g_file_attribute_matcher_subtract:
- * @matcher: Matcher to subtract from 
- * @subtract: The matcher to subtract
+ * @matcher: (nullable): Matcher to subtract from 
+ * @subtract: (nullable): The matcher to subtract
  *
  * Subtracts all attributes of @subtract from @matcher and returns
  * a matcher that supports those attributes.
@@ -2476,7 +2476,7 @@ g_file_attribute_matcher_new (const char *attributes)
  * is a limitation of the current implementation, but may be fixed
  * in the future.
  *
- * Returns: A file attribute matcher matching all attributes of
+ * Returns: (nullable): A file attribute matcher matching all attributes of
  *     @matcher that are not matched by @subtract
  **/
 GFileAttributeMatcher *
index 5919c28..f599bcd 100644 (file)
@@ -277,7 +277,7 @@ g_file_io_stream_query_info_finish (GFileIOStream     *stream,
  * This must be called after the stream has been written
  * and closed, as the etag can change while writing.
  *
- * Returns: the entity tag for the stream.
+ * Returns: (nullable) (transfer full): the entity tag for the stream.
  *
  * Since: 2.22
  **/
index bad2c6e..a290c03 100644 (file)
@@ -404,9 +404,9 @@ init_completion (GFilenameCompleter *completer,
  *
  * Obtains a completion for @initial_text from @completer.
  *  
- * Returns: a completed string, or %NULL if no completion exists. 
- *     This string is not owned by GIO, so remember to g_free() it 
- *     when finished.
+ * Returns: (nullable) (transfer full): a completed string, or %NULL if no
+ *     completion exists. This string is not owned by GIO, so remember to g_free()
+ *     it when finished.
  **/
 char *
 g_filename_completer_get_completion_suffix (GFilenameCompleter *completer,
index d0839c2..1dc536f 100644 (file)
@@ -271,7 +271,7 @@ g_file_output_stream_query_info_finish (GFileOutputStream     *stream,
  * This must be called after the stream has been written
  * and closed, as the etag can change while writing.
  * 
- * Returns: the entity tag for the stream.
+ * Returns: (nullable) (transfer full): the entity tag for the stream.
  **/
 char *
 g_file_output_stream_get_etag (GFileOutputStream  *stream)
index 42c0a09..f1ba0e2 100644 (file)
@@ -562,7 +562,7 @@ g_icon_deserialize_emblemed (GVariant *value)
  *
  * Deserializes a #GIcon previously serialized using g_icon_serialize().
  *
- * Returns: (transfer full): a #GIcon, or %NULL when deserialization fails.
+ * Returns: (nullable) (transfer full): a #GIcon, or %NULL when deserialization fails.
  *
  * Since: 2.38
  */
@@ -653,7 +653,7 @@ g_icon_deserialize (GVariant *value)
  * makes sense to transfer the #GVariant between processes on the same machine,
  * (as opposed to over the network), and within the same file system namespace.
  *
- * Returns: (transfer full): a #GVariant, or %NULL when serialization fails. The #GVariant will not be floating.
+ * Returns: (nullable) (transfer full): a #GVariant, or %NULL when serialization fails. The #GVariant will not be floating.
  *
  * Since: 2.38
  */
index 8960540..351700d 100644 (file)
@@ -4,6 +4,6 @@ import os
 import subprocess
 import sys
 
-if not os.environ.get('DESTDIR'):
-  print('GIO module cache creation...')
-  subprocess.call([sys.argv[1], sys.argv[2]])
+if not os.environ.get("DESTDIR"):
+    print("GIO module cache creation...")
+    subprocess.call([sys.argv[1], sys.argv[2]])
index e9adc4a..948a012 100644 (file)
@@ -13,9 +13,9 @@
 GType
 @enum_name@_get_type (void)
 {
-  static volatile gsize g_define_type_id__volatile = 0;
+  static gsize static_g_define_type_id = 0;
 
-  if (g_once_init_enter (&g_define_type_id__volatile))
+  if (g_once_init_enter (&static_g_define_type_id))
     {
       static const G@Type@Value values[] = {
 /*** END value-header ***/
@@ -29,10 +29,10 @@ GType
       };
       GType g_define_type_id =
         g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
-      g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
+      g_once_init_leave (&static_g_define_type_id, g_define_type_id);
     }
 
-  return g_define_type_id__volatile;
+  return static_g_define_type_id;
 }
 
 /*** END value-tail ***/
index dc4d6d3..e27f1ab 100644 (file)
@@ -49,6 +49,7 @@
 #include "gmemorymonitordbus.h"
 #ifdef G_OS_WIN32
 #include "gregistrysettingsbackend.h"
+#include "giowin32-priv.h"
 #endif
 #include <glib/gstdio.h>
 
@@ -1068,7 +1069,10 @@ DllMain (HINSTANCE hinstDLL,
         LPVOID    lpvReserved)
 {
   if (fdwReason == DLL_PROCESS_ATTACH)
+    {
       gio_dll = hinstDLL;
+      gio_win32_appinfo_init (FALSE);
+    }
 
   return TRUE;
 }
index 8843845..6f20a95 100644 (file)
@@ -35,6 +35,8 @@ GOutputStream *
 g_win32_output_stream_new_from_fd (gint      fd,
                                   gboolean  close_fd);
 
+void
+gio_win32_appinfo_init (gboolean do_wait);
 G_END_DECLS
 
 #endif /* __G_IO_MODULE_PRIV_H__ */
index cd5765a..039ff06 100644 (file)
@@ -105,20 +105,24 @@ compute_checksum (guint8        *digest,
   g_assert (len == 32);
 }
 
-static void
-g_keyfile_settings_backend_keyfile_write (GKeyfileSettingsBackend *kfsb)
+static gboolean
+g_keyfile_settings_backend_keyfile_write (GKeyfileSettingsBackend  *kfsb,
+                                          GError                  **error)
 {
   gchar *contents;
   gsize length;
+  gboolean success;
 
   contents = g_key_file_to_data (kfsb->keyfile, &length, NULL);
-  g_file_replace_contents (kfsb->file, contents, length, NULL, FALSE,
-                           G_FILE_CREATE_REPLACE_DESTINATION |
-                           G_FILE_CREATE_PRIVATE,
-                           NULL, NULL, NULL);
+  success = g_file_replace_contents (kfsb->file, contents, length, NULL, FALSE,
+                                     G_FILE_CREATE_REPLACE_DESTINATION |
+                                     G_FILE_CREATE_PRIVATE,
+                                     NULL, NULL, error);
 
   compute_checksum (kfsb->digest, contents, length);
   g_free (contents);
+
+  return success;
 }
 
 static gboolean
@@ -359,6 +363,8 @@ g_keyfile_settings_backend_write_tree (GSettingsBackend *backend,
                                        gpointer          origin_tag)
 {
   WriteManyData data = { G_KEYFILE_SETTINGS_BACKEND (backend) };
+  gboolean success;
+  GError *error = NULL;
 
   if (!data.kfsb->writable)
     return FALSE;
@@ -369,11 +375,16 @@ g_keyfile_settings_backend_write_tree (GSettingsBackend *backend,
     return FALSE;
 
   g_tree_foreach (tree, g_keyfile_settings_backend_write_one, &data);
-  g_keyfile_settings_backend_keyfile_write (data.kfsb);
+  success = g_keyfile_settings_backend_keyfile_write (data.kfsb, &error);
+  if (error)
+    {
+      g_warning ("Failed to write keyfile to %s: %s", g_file_peek_path (data.kfsb->file), error->message);
+      g_error_free (error);
+    }
 
   g_settings_backend_changed_tree (backend, tree, origin_tag);
 
-  return TRUE;
+  return success;
 }
 
 static gboolean
@@ -384,6 +395,7 @@ g_keyfile_settings_backend_write (GSettingsBackend *backend,
 {
   GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (backend);
   gboolean success;
+  GError *error = NULL;
 
   if (!kfsb->writable)
     return FALSE;
@@ -393,7 +405,12 @@ g_keyfile_settings_backend_write (GSettingsBackend *backend,
   if (success)
     {
       g_settings_backend_changed (backend, key, origin_tag);
-      g_keyfile_settings_backend_keyfile_write (kfsb);
+      success = g_keyfile_settings_backend_keyfile_write (kfsb, &error);
+      if (error)
+        {
+          g_warning ("Failed to write keyfile to %s: %s", g_file_peek_path (kfsb->file), error->message);
+          g_error_free (error);
+        }
     }
 
   return success;
@@ -405,9 +422,17 @@ g_keyfile_settings_backend_reset (GSettingsBackend *backend,
                                   gpointer          origin_tag)
 {
   GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (backend);
+  GError *error = NULL;
 
   if (set_to_keyfile (kfsb, key, NULL))
-    g_keyfile_settings_backend_keyfile_write (kfsb);
+    {
+      g_keyfile_settings_backend_keyfile_write (kfsb, &error);
+      if (error)
+        {
+          g_warning ("Failed to write keyfile to %s: %s", g_file_peek_path (kfsb->file), error->message);
+          g_error_free (error);
+        }
+    }
 
   g_settings_backend_changed (backend, key, origin_tag);
 }
@@ -689,6 +714,7 @@ static void
 g_keyfile_settings_backend_constructed (GObject *object)
 {
   GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object);
+  const char *path;
 
   if (kfsb->file == NULL)
     {
@@ -709,7 +735,9 @@ g_keyfile_settings_backend_constructed (GObject *object)
   kfsb->permission = g_simple_permission_new (TRUE);
 
   kfsb->dir = g_file_get_parent (kfsb->file);
-  g_mkdir_with_parents (g_file_peek_path (kfsb->dir), 0700);
+  path = g_file_peek_path (kfsb->dir);
+  if (g_mkdir_with_parents (path, 0700) == -1)
+    g_warning ("Failed to create %s: %s", path, g_strerror (errno));
 
   kfsb->file_monitor = g_file_monitor (kfsb->file, G_FILE_MONITOR_NONE, NULL, NULL);
   kfsb->dir_monitor = g_file_monitor (kfsb->dir, G_FILE_MONITOR_NONE, NULL, NULL);
index a87de9c..15738d8 100644 (file)
@@ -1824,6 +1824,7 @@ _g_local_file_has_trash_dir (const char *dirname, dev_t dir_dev)
 {
   static gsize home_dev_set = 0;
   static dev_t home_dev;
+  static gboolean home_dev_valid = FALSE;
   char *topdir, *globaldir, *trashdir, *tmpname;
   uid_t uid;
   char uid_str[32];
@@ -1834,13 +1835,23 @@ _g_local_file_has_trash_dir (const char *dirname, dev_t dir_dev)
     {
       GStatBuf home_stat;
 
-      g_stat (g_get_home_dir (), &home_stat);
-      home_dev = home_stat.st_dev;
+      if (g_stat (g_get_home_dir (), &home_stat) == 0)
+        {
+          home_dev = home_stat.st_dev;
+          home_dev_valid = TRUE;
+        }
+      else
+        {
+          home_dev_valid = FALSE;
+        }
+
       g_once_init_leave (&home_dev_set, 1);
     }
 
   /* Assume we can trash to the home */
-  if (dir_dev == home_dev)
+  if (!home_dev_valid)
+    return FALSE;
+  else if (dir_dev == home_dev)
     return TRUE;
 
   topdir = find_mountpoint_for (dirname, dir_dev, TRUE);
@@ -1972,7 +1983,15 @@ g_local_file_trash (GFile         *file,
     }
     
   homedir = g_get_home_dir ();
-  g_stat (homedir, &home_stat);
+  if (g_stat (homedir, &home_stat) != 0)
+    {
+      errsv = errno;
+
+      g_set_io_error (error,
+                      _("Error trashing file %s: %s"),
+                      file, errsv);
+      return FALSE;
+    }
 
   is_homedir_trash = FALSE;
   trashdir = NULL;
index 90fcb33..4228d34 100644 (file)
@@ -1547,15 +1547,45 @@ win32_get_file_user_info (const gchar  *filename,
 /* support for '.hidden' files */
 G_LOCK_DEFINE_STATIC (hidden_cache);
 static GHashTable *hidden_cache;
+static GSource *hidden_cache_source = NULL; /* Under the hidden_cache lock */
+static guint hidden_cache_ttl_secs = 5;
+static guint hidden_cache_ttl_jitter_secs = 2;
+
+typedef struct
+{
+  GHashTable *hidden_files;
+  gint64 timestamp_secs;
+} HiddenCacheData;
 
 static gboolean
 remove_from_hidden_cache (gpointer user_data)
 {
+  HiddenCacheData *data;
+  GHashTableIter iter;
+  gboolean retval;
+  gint64 timestamp_secs;
+
   G_LOCK (hidden_cache);
-  g_hash_table_remove (hidden_cache, user_data);
+  timestamp_secs = g_source_get_time (hidden_cache_source) / G_USEC_PER_SEC;
+
+  g_hash_table_iter_init (&iter, hidden_cache);
+  while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &data))
+    {
+      if (timestamp_secs > data->timestamp_secs + hidden_cache_ttl_secs)
+        g_hash_table_iter_remove (&iter);
+    }
+
+  if (g_hash_table_size (hidden_cache) == 0)
+    {
+      g_clear_pointer (&hidden_cache_source, g_source_unref);
+      retval = G_SOURCE_REMOVE;
+    }
+  else
+    retval = G_SOURCE_CONTINUE;
+
   G_UNLOCK (hidden_cache);
 
-  return FALSE;
+  return retval;
 }
 
 static GHashTable *
@@ -1593,16 +1623,19 @@ read_hidden_file (const gchar *dirname)
 }
 
 static void
-maybe_unref_hash_table (gpointer data)
+free_hidden_file_data (gpointer user_data)
 {
-  if (data != NULL)
-    g_hash_table_unref (data);
+  HiddenCacheData *data = user_data;
+
+  g_clear_pointer (&data->hidden_files, g_hash_table_unref);
+  g_free (data);
 }
 
 static gboolean
 file_is_hidden (const gchar *path,
                 const gchar *basename)
 {
+  HiddenCacheData *data;
   gboolean result;
   gchar *dirname;
   gpointer table;
@@ -1613,28 +1646,38 @@ file_is_hidden (const gchar *path,
 
   if G_UNLIKELY (hidden_cache == NULL)
     hidden_cache = g_hash_table_new_full (g_str_hash, g_str_equal,
-                                          g_free, maybe_unref_hash_table);
+                                          g_free, free_hidden_file_data);
 
   if (!g_hash_table_lookup_extended (hidden_cache, dirname,
-                                     NULL, &table))
+                                     NULL, (gpointer *) &data))
     {
       gchar *mydirname;
-      GSource *remove_from_cache_source;
+
+      data = g_new0 (HiddenCacheData, 1);
+      data->hidden_files = table = read_hidden_file (dirname);
+      data->timestamp_secs = g_get_monotonic_time () / G_USEC_PER_SEC;
 
       g_hash_table_insert (hidden_cache,
                            mydirname = g_strdup (dirname),
-                           table = read_hidden_file (dirname));
+                           data);
 
-      remove_from_cache_source = g_timeout_source_new_seconds (5);
-      g_source_set_priority (remove_from_cache_source, G_PRIORITY_DEFAULT);
-      g_source_set_callback (remove_from_cache_source, 
-                             remove_from_hidden_cache, 
-                             mydirname, 
-                             NULL);
-      g_source_attach (remove_from_cache_source, 
-                       GLIB_PRIVATE_CALL (g_get_worker_context) ());
-      g_source_unref (remove_from_cache_source);
+      if (!hidden_cache_source)
+        {
+          hidden_cache_source =
+            g_timeout_source_new_seconds (hidden_cache_ttl_secs +
+                                          hidden_cache_ttl_jitter_secs);
+          g_source_set_priority (hidden_cache_source, G_PRIORITY_DEFAULT);
+          g_source_set_name (hidden_cache_source,
+                             "[gio] remove_from_hidden_cache");
+          g_source_set_callback (hidden_cache_source,
+                                 remove_from_hidden_cache,
+                                 NULL, NULL);
+          g_source_attach (hidden_cache_source,
+                           GLIB_PRIVATE_CALL (g_get_worker_context) ());
+        }
     }
+  else
+    table = data->hidden_files;
 
   result = table != NULL && g_hash_table_contains (table, basename);
 
@@ -2656,8 +2699,8 @@ set_mtime_atime (char                       *filename,
 #ifdef HAVE_SELINUX
 static gboolean
 set_selinux_context (char                       *filename,
-                const GFileAttributeValue  *value,
-                GError                    **error)
+                     const GFileAttributeValue  *value,
+                     GError                    **error)
 {
   const char *val;
 
@@ -2665,34 +2708,30 @@ set_selinux_context (char                       *filename,
     return FALSE;
 
   if (val == NULL)
-  {
-    g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
-                         _("SELinux context must be non-NULL"));
-    return FALSE;
-  }
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+                           _("SELinux context must be non-NULL"));
+      return FALSE;
+    }
 
-  if (is_selinux_enabled ()) {
-       security_context_t val_s;
-       
-       val_s = g_strdup (val);
-       
-       if (setfilecon_raw (filename, val_s) < 0)
-       {
-            int errsv = errno;
+  if (!is_selinux_enabled ())
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+                           _("SELinux is not enabled on this system"));
+      return FALSE;
+    }
+
+  if (setfilecon_raw (filename, val) < 0)
+    {
+      int errsv = errno;
             
-            g_set_error (error, G_IO_ERROR,
-                         g_io_error_from_errno (errsv),
-                       _("Error setting SELinux context: %s"),
-                         g_strerror (errsv));
-            return FALSE;
-        }
-        g_free (val_s);
-  } else {
-    g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
-                         _("SELinux is not enabled on this system"));
-    return FALSE;
-  }
-                                                     
+      g_set_error (error, G_IO_ERROR,
+                   g_io_error_from_errno (errsv),
+                   _("Error setting SELinux context: %s"),
+                   g_strerror (errsv));
+      return FALSE;
+    }
+
   return TRUE;
 }
 #endif 
index ae0d3f7..37ddf48 100644 (file)
@@ -118,7 +118,7 @@ static guint signals[LAST_SIGNAL] = { 0 };
  *
  * Gets a reference to the default #GMemoryMonitor for the system.
  *
- * Returns: (transfer full): a new reference to the default #GMemoryMonitor
+ * Returns: (not nullable) (transfer full): a new reference to the default #GMemoryMonitor
  *
  * Since: 2.64
  */
index 9560252..bb5202c 100644 (file)
@@ -781,7 +781,7 @@ g_menu_item_set_link (GMenuItem   *menu_item,
  * type, %NULL is returned.  %NULL is also returned if the attribute
  * simply does not exist.
  *
- * Returns: (transfer full): the attribute value, or %NULL
+ * Returns: (nullable) (transfer full): the attribute value, or %NULL
  *
  * Since: 2.34
  */
@@ -865,7 +865,7 @@ g_menu_item_get_attribute (GMenuItem   *menu_item,
  *
  * Queries the named @link on @menu_item.
  *
- * Returns: (transfer full): the link, or %NULL
+ * Returns: (nullable) (transfer full): the link, or %NULL
  *
  * Since: 2.34
  */
index 9d7b766..bd60dc5 100644 (file)
@@ -541,7 +541,7 @@ g_menu_model_iterate_item_attributes (GMenuModel *model,
  * If the attribute does not exist, or does not match the expected type
  * then %NULL is returned.
  *
- * Returns: (transfer full): the value of the attribute
+ * Returns: (nullable) (transfer full): the value of the attribute
  *
  * Since: 2.32
  */
@@ -648,7 +648,7 @@ g_menu_model_iterate_item_links (GMenuModel *model,
  * If the link exists, the linked #GMenuModel is returned.  If the link
  * does not exist, %NULL is returned.
  *
- * Returns: (transfer full): the linked #GMenuModel, or %NULL
+ * Returns: (nullable) (transfer full): the linked #GMenuModel, or %NULL
  *
  * Since: 2.32
  */
index 05fc506..4bc19a8 100644 (file)
@@ -638,7 +638,7 @@ g_mount_operation_new (void)
  * 
  * Get the user name from the mount operation.
  *
- * Returns: a string containing the user name.
+ * Returns: (nullable): a string containing the user name.
  **/
 const char *
 g_mount_operation_get_username (GMountOperation *op)
@@ -650,7 +650,7 @@ g_mount_operation_get_username (GMountOperation *op)
 /**
  * g_mount_operation_set_username:
  * @op: a #GMountOperation.
- * @username: input username.
+ * @username: (nullable): input username.
  *
  * Sets the user name within @op to @username.
  **/
@@ -670,7 +670,7 @@ g_mount_operation_set_username (GMountOperation *op,
  *
  * Gets a password from the mount operation. 
  *
- * Returns: a string containing the password within @op.
+ * Returns: (nullable): a string containing the password within @op.
  **/
 const char *
 g_mount_operation_get_password (GMountOperation *op)
@@ -682,7 +682,7 @@ g_mount_operation_get_password (GMountOperation *op)
 /**
  * g_mount_operation_set_password:
  * @op: a #GMountOperation.
- * @password: password to set.
+ * @password: (nullable): password to set.
  * 
  * Sets the mount operation's password to @password.  
  *
@@ -741,7 +741,7 @@ g_mount_operation_set_anonymous (GMountOperation *op,
  * 
  * Gets the domain of the mount operation.
  * 
- * Returns: a string set to the domain. 
+ * Returns: (nullable): a string set to the domain.
  **/
 const char *
 g_mount_operation_get_domain (GMountOperation *op)
@@ -753,7 +753,7 @@ g_mount_operation_get_domain (GMountOperation *op)
 /**
  * g_mount_operation_set_domain:
  * @op: a #GMountOperation.
- * @domain: the domain to set.
+ * @domain: (nullable): the domain to set.
  * 
  * Sets the mount operation's domain. 
  **/  
index b51d9c5..ef1940a 100644 (file)
@@ -611,7 +611,7 @@ g_network_address_get_port (GNetworkAddress *addr)
  *
  * Gets @addr's scheme
  *
- * Returns: @addr's scheme (%NULL if not built from URI)
+ * Returns: (nullable): @addr's scheme (%NULL if not built from URI)
  *
  * Since: 2.26
  */
index 05507fe..7bc6d73 100644 (file)
@@ -61,7 +61,7 @@ void
 g_networking_init (void)
 {
 #ifdef G_OS_WIN32
-  static volatile gsize inited = 0;
+  static gsize inited = 0;
 
   if (g_once_init_enter (&inited))
     {
index f9853fc..8027e46 100644 (file)
@@ -83,7 +83,8 @@ static guint signals[LAST_SIGNAL] = { 0 };
  *
  * Gets the default #GNetworkMonitor for the system.
  *
- * Returns: (transfer none): a #GNetworkMonitor
+ * Returns: (not nullable) (transfer none): a #GNetworkMonitor, which will be
+ *     a dummy object if no network monitor is available
  *
  * Since: 2.32
  */
index 60bb5b8..4c80a47 100644 (file)
@@ -55,7 +55,7 @@ g_proxy_default_init (GProxyInterface *iface)
  * Find the `gio-proxy` extension point for a proxy implementation that supports
  * the specified protocol.
  *
- * Returns: (transfer full): return a #GProxy or NULL if protocol
+ * Returns: (nullable) (transfer full): return a #GProxy or NULL if protocol
  *               is not supported.
  *
  * Since: 2.26
index a02b31f..a9405eb 100644 (file)
@@ -409,7 +409,7 @@ g_proxy_address_get_destination_port (GProxyAddress *proxy)
  *
  * Gets @proxy's username.
  *
- * Returns: the @proxy's username
+ * Returns: (nullable): the @proxy's username
  *
  * Since: 2.26
  */
@@ -425,7 +425,7 @@ g_proxy_address_get_username (GProxyAddress *proxy)
  *
  * Gets @proxy's password.
  *
- * Returns: the @proxy's password
+ * Returns: (nullable): the @proxy's password
  *
  * Since: 2.26
  */
@@ -442,7 +442,7 @@ g_proxy_address_get_password (GProxyAddress *proxy)
  *
  * Gets the proxy URI that @proxy was constructed from.
  *
- * Returns: the @proxy's URI, or %NULL if unknown
+ * Returns: (nullable): the @proxy's URI, or %NULL if unknown
  *
  * Since: 2.34
  */
index ca34663..c83347b 100644 (file)
@@ -72,7 +72,8 @@ g_proxy_resolver_default_init (GProxyResolverInterface *iface)
  *
  * Gets the default #GProxyResolver for the system.
  *
- * Returns: (transfer none): the default #GProxyResolver.
+ * Returns: (not nullable) (transfer none): the default #GProxyResolver, which
+ *     will be a dummy object if no proxy resolver is available
  *
  * Since: 2.26
  */
index b7222b8..b495d12 100644 (file)
@@ -800,7 +800,9 @@ g_resource_lookup_data (GResource             *resource,
   if (!do_lookup (resource, path, lookup_flags, &size, &flags, &data, &data_size, error))
     return NULL;
 
-  if (flags & G_RESOURCE_FLAGS_COMPRESSED)
+  if (size == 0)
+    return g_bytes_new_with_free_func ("", 0, (GDestroyNotify) g_resource_unref, g_resource_ref (resource));
+  else if (flags & G_RESOURCE_FLAGS_COMPRESSED)
     {
       char *uncompressed, *d;
       const char *s;
@@ -1396,7 +1398,7 @@ register_lazy_static_resources (void)
 void
 g_static_resource_init (GStaticResource *static_resource)
 {
-  gpointer next;
+  GStaticResource *next;
 
   do
     {
index f53a023..dcc7c37 100644 (file)
@@ -1001,7 +1001,9 @@ g_settings_backend_verify (gpointer impl)
  *
  * The user gets a reference to the backend.
  *
- * Returns: (transfer full): the default #GSettingsBackend
+ * Returns: (not nullable) (transfer full): the default #GSettingsBackend,
+ *     which will be a dummy (memory) settings backend if no other settings
+ *     backend is available.
  *
  * Since: 2.28
  */
index 0b94f76..cbc3fad 100644 (file)
@@ -1001,7 +1001,7 @@ g_settings_schema_get_value (GSettingsSchema *schema,
  * therefore describe multiple sets of keys at different locations.  For
  * relocatable schemas, this function will return %NULL.
  *
- * Returns: (transfer none): the path of the schema, or %NULL
+ * Returns: (nullable) (transfer none): the path of the schema, or %NULL
  *
  * Since: 2.32
  **/
@@ -1660,7 +1660,7 @@ g_settings_schema_key_get_name (GSettingsSchemaKey *key)
  * function has to parse all of the source XML files in the schema
  * directory.
  *
- * Returns: the summary for @key, or %NULL
+ * Returns: (nullable): the summary for @key, or %NULL
  *
  * Since: 2.34
  **/
@@ -1695,7 +1695,7 @@ g_settings_schema_key_get_summary (GSettingsSchemaKey *key)
  * function has to parse all of the source XML files in the schema
  * directory.
  *
- * Returns: the description for @key, or %NULL
+ * Returns: (nullable): the description for @key, or %NULL
  *
  * Since: 2.34
  **/
index ce3c186..62b1afb 100644 (file)
@@ -491,7 +491,7 @@ g_socket_client_set_protocol (GSocketClient   *client,
  *
  * See g_socket_client_set_local_address() for details.
  *
- * Returns: (transfer none): a #GSocketAddress or %NULL. Do not free.
+ * Returns: (nullable) (transfer none): a #GSocketAddress or %NULL. Do not free.
  *
  * Since: 2.22
  */
@@ -1837,9 +1837,9 @@ g_socket_client_connected_callback (GObject      *source,
     {
       if (!g_cancellable_is_cancelled (attempt->cancellable))
         {
+          g_debug ("GSocketClient: Connection attempt failed: %s", data->error_info->tmp_error->message);
           clarify_connect_error (data->error_info->tmp_error, data->connectable, attempt->address);
           consider_tmp_error (data->error_info, G_SOCKET_CLIENT_CONNECTING);
-          g_debug ("GSocketClient: Connection attempt failed: %s", data->error_info->tmp_error->message);
           connection_attempt_remove (attempt);
           connection_attempt_unref (attempt);
           try_next_connection_or_finish (data, FALSE);
index 8cc9354..4bf1f6b 100644 (file)
@@ -773,10 +773,10 @@ g_subprocess_get_identifier (GSubprocess *subprocess)
  * Gets the #GOutputStream that you can write to in order to give data
  * to the stdin of @subprocess.
  *
- * The process must have been created with
- * %G_SUBPROCESS_FLAGS_STDIN_PIPE.
+ * The process must have been created with %G_SUBPROCESS_FLAGS_STDIN_PIPE and
+ * not %G_SUBPROCESS_FLAGS_STDIN_INHERIT, otherwise %NULL will be returned.
  *
- * Returns: (transfer none): the stdout pipe
+ * Returns: (nullable) (transfer none): the stdout pipe
  *
  * Since: 2.40
  **/
@@ -784,7 +784,6 @@ GOutputStream *
 g_subprocess_get_stdin_pipe (GSubprocess *subprocess)
 {
   g_return_val_if_fail (G_IS_SUBPROCESS (subprocess), NULL);
-  g_return_val_if_fail (subprocess->stdin_pipe, NULL);
 
   return subprocess->stdin_pipe;
 }
@@ -796,10 +795,10 @@ g_subprocess_get_stdin_pipe (GSubprocess *subprocess)
  * Gets the #GInputStream from which to read the stdout output of
  * @subprocess.
  *
- * The process must have been created with
- * %G_SUBPROCESS_FLAGS_STDOUT_PIPE.
+ * The process must have been created with %G_SUBPROCESS_FLAGS_STDOUT_PIPE,
+ * otherwise %NULL will be returned.
  *
- * Returns: (transfer none): the stdout pipe
+ * Returns: (nullable) (transfer none): the stdout pipe
  *
  * Since: 2.40
  **/
@@ -807,7 +806,6 @@ GInputStream *
 g_subprocess_get_stdout_pipe (GSubprocess *subprocess)
 {
   g_return_val_if_fail (G_IS_SUBPROCESS (subprocess), NULL);
-  g_return_val_if_fail (subprocess->stdout_pipe, NULL);
 
   return subprocess->stdout_pipe;
 }
@@ -819,10 +817,10 @@ g_subprocess_get_stdout_pipe (GSubprocess *subprocess)
  * Gets the #GInputStream from which to read the stderr output of
  * @subprocess.
  *
- * The process must have been created with
- * %G_SUBPROCESS_FLAGS_STDERR_PIPE.
+ * The process must have been created with %G_SUBPROCESS_FLAGS_STDERR_PIPE,
+ * otherwise %NULL will be returned.
  *
- * Returns: (transfer none): the stderr pipe
+ * Returns: (nullable) (transfer none): the stderr pipe
  *
  * Since: 2.40
  **/
@@ -830,7 +828,6 @@ GInputStream *
 g_subprocess_get_stderr_pipe (GSubprocess *subprocess)
 {
   g_return_val_if_fail (G_IS_SUBPROCESS (subprocess), NULL);
-  g_return_val_if_fail (subprocess->stderr_pipe, NULL);
 
   return subprocess->stderr_pipe;
 }
index c279609..9e077bd 100644 (file)
@@ -303,7 +303,7 @@ g_subprocess_launcher_unsetenv (GSubprocessLauncher *self,
  * On UNIX, the returned string can be an arbitrary byte string.
  * On Windows, it will be UTF-8.
  *
- * Returns: (type filename): the value of the environment variable,
+ * Returns: (nullable) (type filename): the value of the environment variable,
  *     %NULL if unset
  *
  * Since: 2.40
index 9a5c148..3540e65 100644 (file)
@@ -24,6 +24,7 @@
 #include "gasyncresult.h"
 #include "gcancellable.h"
 #include "glib-private.h"
+#include "gtrace-private.h"
 
 #include "glibintl.h"
 
@@ -618,6 +619,9 @@ static GSource *task_pool_manager;
 static guint64 task_wait_time;
 static gint tasks_running;
 
+static guint task_pool_max_counter;
+static guint tasks_running_counter;
+
 /* When the task pool fills up and blocks, and the program keeps
  * queueing more tasks, we will slowly add more threads to the pool
  * (in case the existing tasks are trying to queue subtasks of their
@@ -1361,6 +1365,7 @@ task_pool_manager_timeout (gpointer user_data)
 {
   g_mutex_lock (&task_pool_mutex);
   g_thread_pool_set_max_threads (task_pool, tasks_running + 1, NULL);
+  g_trace_set_int64_counter (task_pool_max_counter, tasks_running + 1);
   g_source_set_ready_time (task_pool_manager, -1);
   g_mutex_unlock (&task_pool_mutex);
 
@@ -1374,6 +1379,8 @@ g_task_thread_setup (void)
   g_mutex_lock (&task_pool_mutex);
   tasks_running++;
 
+  g_trace_set_int64_counter (tasks_running_counter, tasks_running);
+
   if (tasks_running == G_TASK_POOL_SIZE)
     task_wait_time = G_TASK_WAIT_TIME_BASE;
   else if (tasks_running > G_TASK_POOL_SIZE && tasks_running < G_TASK_WAIT_TIME_MAX_POOL_SIZE)
@@ -1394,7 +1401,10 @@ g_task_thread_cleanup (void)
   tasks_pending = g_thread_pool_unprocessed (task_pool);
 
   if (tasks_running > G_TASK_POOL_SIZE)
-    g_thread_pool_set_max_threads (task_pool, tasks_running - 1, NULL);
+    {
+      g_thread_pool_set_max_threads (task_pool, tasks_running - 1, NULL);
+      g_trace_set_int64_counter (task_pool_max_counter, tasks_running - 1);
+    }
   else if (tasks_running + tasks_pending < G_TASK_POOL_SIZE)
     g_source_set_ready_time (task_pool_manager, -1);
 
@@ -1402,6 +1412,9 @@ g_task_thread_cleanup (void)
     task_wait_time /= G_TASK_WAIT_TIME_MULTIPLIER;
 
   tasks_running--;
+
+  g_trace_set_int64_counter (tasks_running_counter, tasks_running);
+
   g_mutex_unlock (&task_pool_mutex);
   g_private_set (&task_private, GUINT_TO_POINTER (FALSE));
 }
@@ -2214,6 +2227,16 @@ g_task_class_init (GTaskClass *klass)
                           P_("Task completed"),
                           P_("Whether the task has completed yet"),
                           FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+  if (G_UNLIKELY (task_pool_max_counter == 0))
+    {
+      /* We use two counters to track characteristics of the GTask thread pool.
+       * task pool max size - the value of g_thread_pool_set_max_threads()
+       * tasks running - the number of running threads
+       */
+      task_pool_max_counter = g_trace_define_int64_counter ("GIO", "task pool max size", "Maximum number of threads allowed in the GTask thread pool; see g_thread_pool_set_max_threads()");
+      tasks_running_counter = g_trace_define_int64_counter ("GIO", "tasks running", "Number of currently running tasks in the GTask thread pool");
+    }
 }
 
 static gpointer
index 96da52c..9cfaadb 100644 (file)
@@ -282,10 +282,13 @@ watcher_send_command (const gchar *command)
 {
   GIOChannel *channel;
   GError *error = NULL;
+  GIOStatus status;
 
   channel = watcher_init ();
 
-  g_io_channel_write_chars (channel, command, -1, NULL, &error);
+  do
+   status = g_io_channel_write_chars (channel, command, -1, NULL, &error);
+  while (status == G_IO_STATUS_AGAIN);
   g_assert_no_error (error);
 
   g_io_channel_flush (channel, &error);
index d67e490..6d948ad 100644 (file)
@@ -98,7 +98,8 @@ g_tls_backend_default_init (GTlsBackendInterface *iface)
  *
  * Gets the default #GTlsBackend for the system.
  *
- * Returns: (transfer none): a #GTlsBackend
+ * Returns: (not nullable) (transfer none): a #GTlsBackend, which will be a
+ *     dummy object if no TLS backend is available
  *
  * Since: 2.28
  */
index 0668d49..9d00272 100644 (file)
@@ -784,7 +784,7 @@ g_tls_certificate_list_new_from_file (const gchar  *file,
  *
  * Gets the #GTlsCertificate representing @cert's issuer, if known
  *
- * Returns: (transfer none): The certificate of @cert's issuer,
+ * Returns: (nullable) (transfer none): The certificate of @cert's issuer,
  * or %NULL if @cert is self-signed or signed with an unknown
  * certificate.
  *
index f2a61c4..d0a740f 100644 (file)
@@ -224,7 +224,7 @@ g_tls_client_connection_set_validation_flags (GTlsClientConnection  *conn,
  *
  * Gets @conn's expected server identity
  *
- * Returns: (transfer none): a #GSocketConnectable describing the
+ * Returns: (nullable) (transfer none): a #GSocketConnectable describing the
  * expected server identity, or %NULL if the expected identity is not
  * known.
  *
index b0fdfa8..2aac641 100644 (file)
@@ -2491,7 +2491,7 @@ g_unix_mount_point_get_fs_type (GUnixMountPoint *mount_point)
  * 
  * Gets the options for the mount point.
  * 
- * Returns: a string containing the options.
+ * Returns: (nullable): a string containing the options.
  *
  * Since: 2.32
  */
index 3475624..f178d7a 100644 (file)
@@ -342,7 +342,8 @@ g_vfs_parse_name (GVfs       *vfs,
  *
  * Gets the default #GVfs for the system.
  *
- * Returns: (transfer none): a #GVfs.
+ * Returns: (not nullable) (transfer none): a #GVfs, which will be the local
+ *     file system #GVfs if no other implementation is available.
  */
 GVfs *
 g_vfs_get_default (void)
index 65ec955..056999f 100644 (file)
@@ -353,7 +353,7 @@ g_volume_monitor_get_mounts (GVolumeMonitor *volume_monitor)
  * 
  * Finds a #GVolume object by its UUID (see g_volume_get_uuid())
  * 
- * Returns: (transfer full): a #GVolume or %NULL if no such volume is available.
+ * Returns: (nullable) (transfer full): a #GVolume or %NULL if no such volume is available.
  *     Free the returned object with g_object_unref().
  **/
 GVolume *
@@ -377,7 +377,7 @@ g_volume_monitor_get_volume_for_uuid (GVolumeMonitor *volume_monitor,
  * 
  * Finds a #GMount object by its UUID (see g_mount_get_uuid())
  * 
- * Returns: (transfer full): a #GMount or %NULL if no such mount is available.
+ * Returns: (nullable) (transfer full): a #GMount or %NULL if no such mount is available.
  *     Free the returned object with g_object_unref().
  **/
 GMount *
index 612373a..8871acc 100644 (file)
@@ -36,6 +36,7 @@
 #include <windows.h>
 
 #include <glib/gstdioprivate.h>
+#include "giowin32-priv.h"
 #include "glib-private.h"
 
 /* We need to watch 8 places:
@@ -519,7 +520,26 @@ g_win32_appinfo_application_init (GWin32AppInfoApplication *self)
   self->verbs = g_ptr_array_new_with_free_func (g_object_unref);
 }
 
-G_LOCK_DEFINE_STATIC (gio_win32_appinfo);
+/* The AppInfo threadpool that does asynchronous AppInfo tree rebuilds */
+static GThreadPool *gio_win32_appinfo_threadpool;
+
+/* This mutex is held by a thread that reads or writes the AppInfo tree.
+ * (tree object references can be obtained and later read without
+ *  holding this mutex, since objects are practically immutable).
+ */
+static GMutex gio_win32_appinfo_mutex;
+
+/* Any thread wanting to access AppInfo can wait on this condition */
+static GCond gio_win32_appinfo_cond;
+
+/* Increased to indicate that AppInfo tree does needs to be rebuilt.
+ * AppInfo thread checks this to see if it needs to
+ * do a tree re-build. If the value changes during a rebuild,
+ * another rebuild is triggered after that.
+ * Other threads check this to see if they need
+ * to wait for a tree re-build to finish.
+ */
+static gint gio_win32_appinfo_update_counter = 0;
 
 /* Map of owned ".ext" (with '.', UTF-8, folded)
  * to GWin32AppInfoFileExtension ptr
@@ -3046,6 +3066,19 @@ update_registry_data (void)
   return;
 }
 
+/* This function is called when any of our registry watchers detect
+ * changes in the registry.
+ */
+static void
+keys_updated (GWin32RegistryKey  *key,
+              gpointer            user_data)
+{
+  /* Indicate the tree as not up-to-date, push a new job for the AppInfo thread */
+  g_atomic_int_inc (&gio_win32_appinfo_update_counter);
+  /* We don't use the data pointer, but it must be non-NULL */
+  g_thread_pool_push (gio_win32_appinfo_threadpool, (gpointer) keys_updated, NULL);
+}
+
 static void
 watch_keys (void)
 {
@@ -3055,7 +3088,7 @@ watch_keys (void)
                                 G_WIN32_REGISTRY_WATCH_NAME |
                                 G_WIN32_REGISTRY_WATCH_ATTRIBUTES |
                                 G_WIN32_REGISTRY_WATCH_VALUES,
-                                NULL,
+                                keys_updated,
                                 NULL,
                                 NULL);
 
@@ -3065,7 +3098,7 @@ watch_keys (void)
                                 G_WIN32_REGISTRY_WATCH_NAME |
                                 G_WIN32_REGISTRY_WATCH_ATTRIBUTES |
                                 G_WIN32_REGISTRY_WATCH_VALUES,
-                                NULL,
+                                keys_updated,
                                 NULL,
                                 NULL);
 
@@ -3075,7 +3108,7 @@ watch_keys (void)
                                 G_WIN32_REGISTRY_WATCH_NAME |
                                 G_WIN32_REGISTRY_WATCH_ATTRIBUTES |
                                 G_WIN32_REGISTRY_WATCH_VALUES,
-                                NULL,
+                                keys_updated,
                                 NULL,
                                 NULL);
 
@@ -3085,7 +3118,7 @@ watch_keys (void)
                                 G_WIN32_REGISTRY_WATCH_NAME |
                                 G_WIN32_REGISTRY_WATCH_ATTRIBUTES |
                                 G_WIN32_REGISTRY_WATCH_VALUES,
-                                NULL,
+                                keys_updated,
                                 NULL,
                                 NULL);
 
@@ -3095,7 +3128,7 @@ watch_keys (void)
                                 G_WIN32_REGISTRY_WATCH_NAME |
                                 G_WIN32_REGISTRY_WATCH_ATTRIBUTES |
                                 G_WIN32_REGISTRY_WATCH_VALUES,
-                                NULL,
+                                keys_updated,
                                 NULL,
                                 NULL);
 
@@ -3105,7 +3138,7 @@ watch_keys (void)
                                 G_WIN32_REGISTRY_WATCH_NAME |
                                 G_WIN32_REGISTRY_WATCH_ATTRIBUTES |
                                 G_WIN32_REGISTRY_WATCH_VALUES,
-                                NULL,
+                                keys_updated,
                                 NULL,
                                 NULL);
 
@@ -3115,7 +3148,7 @@ watch_keys (void)
                                 G_WIN32_REGISTRY_WATCH_NAME |
                                 G_WIN32_REGISTRY_WATCH_ATTRIBUTES |
                                 G_WIN32_REGISTRY_WATCH_VALUES,
-                                NULL,
+                                keys_updated,
                                 NULL,
                                 NULL);
 
@@ -3125,14 +3158,45 @@ watch_keys (void)
                                 G_WIN32_REGISTRY_WATCH_NAME |
                                 G_WIN32_REGISTRY_WATCH_ATTRIBUTES |
                                 G_WIN32_REGISTRY_WATCH_VALUES,
-                                NULL,
+                                keys_updated,
                                 NULL,
                                 NULL);
 }
 
-
+/* This is the main function of the AppInfo thread */
 static void
-g_win32_appinfo_init (void)
+gio_win32_appinfo_thread_func (gpointer data,
+                               gpointer user_data)
+{
+  gint saved_counter;
+  g_mutex_lock (&gio_win32_appinfo_mutex);
+  saved_counter = g_atomic_int_get (&gio_win32_appinfo_update_counter);
+
+  if (saved_counter > 0)
+    update_registry_data ();
+  /* If the counter didn't change while we were working, then set it to zero.
+   * Otherwise we need to rebuild the tree again, so keep it greater than zero.
+   * Numeric value doesn't matter - even if we're asked to rebuild N times,
+   * we just need to rebuild once, and as long as there were no new rebuild
+   * requests while we were working, we're done.
+   */
+  if (g_atomic_int_compare_and_exchange  (&gio_win32_appinfo_update_counter,
+                                          saved_counter,
+                                          0))
+    g_cond_broadcast (&gio_win32_appinfo_cond);
+
+  g_mutex_unlock (&gio_win32_appinfo_mutex);
+}
+
+/* Initializes Windows AppInfo. Creates the registry watchers,
+ * the AppInfo thread, and initiates an update of the AppInfo tree.
+ * Called with do_wait = `FALSE` at startup to prevent it from
+ * blocking until the tree is updated. All subsequent calls
+ * from everywhere else are made with do_wait = `TRUE`, blocking
+ * until the tree is re-built (if needed).
+ */
+void
+gio_win32_appinfo_init (gboolean do_wait)
 {
   static gsize initialized;
 
@@ -3165,11 +3229,31 @@ g_win32_appinfo_init (void)
 
       watch_keys ();
 
-      update_registry_data ();
+      /* We don't really require an exclusive pool, but the implementation
+       * details might cause the g_thread_pool_push() call below to block
+       * if the pool is not exclusive (specifically - for POSIX threads backend
+       * lacking thread scheduler settings).
+       */
+      gio_win32_appinfo_threadpool = g_thread_pool_new (gio_win32_appinfo_thread_func,
+                                                        NULL,
+                                                        1,
+                                                        TRUE,
+                                                        NULL);
+      g_mutex_init (&gio_win32_appinfo_mutex);
+      g_cond_init (&gio_win32_appinfo_cond);
+      g_atomic_int_set (&gio_win32_appinfo_update_counter, 1);
+      /* Trigger initial tree build. Fake data pointer. */
+      g_thread_pool_push (gio_win32_appinfo_threadpool, (gpointer) keys_updated, NULL);
 
       g_once_init_leave (&initialized, TRUE);
     }
 
+  if (!do_wait)
+    return;
+
+  /* If any of the keys had a change, then we've already initiated
+   * a tree re-build in keys_updated(). Just wait for it to finish.
+   */
   if ((url_associations_key       && g_win32_registry_key_has_changed (url_associations_key))       ||
       (file_exts_key              && g_win32_registry_key_has_changed (file_exts_key))              ||
       (user_clients_key           && g_win32_registry_key_has_changed (user_clients_key))           ||
@@ -3179,10 +3263,11 @@ g_win32_appinfo_init (void)
       (system_registered_apps_key && g_win32_registry_key_has_changed (system_registered_apps_key)) ||
       (classes_root_key           && g_win32_registry_key_has_changed (classes_root_key)))
     {
-      G_LOCK (gio_win32_appinfo);
-      update_registry_data ();
+      g_mutex_lock (&gio_win32_appinfo_mutex);
+      while (g_atomic_int_get (&gio_win32_appinfo_update_counter) > 0)
+        g_cond_wait (&gio_win32_appinfo_cond, &gio_win32_appinfo_mutex);
       watch_keys ();
-      G_UNLOCK (gio_win32_appinfo);
+      g_mutex_unlock (&gio_win32_appinfo_mutex);
     }
 }
 
@@ -3248,8 +3333,8 @@ g_win32_app_info_new_from_app (GWin32AppInfoApplication *app,
 
   new_info->app = g_object_ref (app);
 
-  g_win32_appinfo_init ();
-  G_LOCK (gio_win32_appinfo);
+  gio_win32_appinfo_init (TRUE);
+  g_mutex_lock (&gio_win32_appinfo_mutex);
 
   i = 0;
   g_hash_table_iter_init (&iter, new_info->app->supported_exts);
@@ -3274,7 +3359,7 @@ g_win32_app_info_new_from_app (GWin32AppInfoApplication *app,
       i += 1;
     }
 
-  G_UNLOCK (gio_win32_appinfo);
+  g_mutex_unlock (&gio_win32_appinfo_mutex);
 
   new_info->supported_types[i] = NULL;
 
@@ -4216,13 +4301,13 @@ g_app_info_get_default_for_uri_scheme (const char *uri_scheme)
       return NULL;
     }
 
-  g_win32_appinfo_init ();
-  G_LOCK (gio_win32_appinfo);
+  gio_win32_appinfo_init (TRUE);
+  g_mutex_lock (&gio_win32_appinfo_mutex);
 
   g_set_object (&scheme, g_hash_table_lookup (urls, scheme_down));
   g_free (scheme_down);
 
-  G_UNLOCK (gio_win32_appinfo);
+  g_mutex_unlock (&gio_win32_appinfo_mutex);
 
   result = NULL;
 
@@ -4252,14 +4337,14 @@ g_app_info_get_default_for_type (const char *content_type,
   if (!ext_down)
     return NULL;
 
-  g_win32_appinfo_init ();
-  G_LOCK (gio_win32_appinfo);
+  gio_win32_appinfo_init (TRUE);
+  g_mutex_lock (&gio_win32_appinfo_mutex);
 
   /* Assuming that "content_type" is a file extension, not a MIME type */
   g_set_object (&ext, g_hash_table_lookup (extensions, ext_down));
   g_free (ext_down);
 
-  G_UNLOCK (gio_win32_appinfo);
+  g_mutex_unlock (&gio_win32_appinfo_mutex);
 
   if (ext == NULL)
     return NULL;
@@ -4309,15 +4394,15 @@ g_app_info_get_all (void)
   GList *apps;
   GList *apps_i;
 
-  g_win32_appinfo_init ();
-  G_LOCK (gio_win32_appinfo);
+  gio_win32_appinfo_init (TRUE);
+  g_mutex_lock (&gio_win32_appinfo_mutex);
 
   apps = NULL;
   g_hash_table_iter_init (&iter, apps_by_id);
   while (g_hash_table_iter_next (&iter, NULL, &value))
     apps = g_list_prepend (apps, g_object_ref (G_OBJECT (value)));
 
-  G_UNLOCK (gio_win32_appinfo);
+  g_mutex_unlock (&gio_win32_appinfo_mutex);
 
   infos = NULL;
   for (apps_i = apps; apps_i; apps_i = apps_i->next)
@@ -4345,14 +4430,14 @@ g_app_info_get_all_for_type (const char *content_type)
   if (!ext_down)
     return NULL;
 
-  g_win32_appinfo_init ();
-  G_LOCK (gio_win32_appinfo);
+  gio_win32_appinfo_init (TRUE);
+  g_mutex_lock (&gio_win32_appinfo_mutex);
 
   /* Assuming that "content_type" is a file extension, not a MIME type */
   g_set_object (&ext, g_hash_table_lookup (extensions, ext_down));
   g_free (ext_down);
 
-  G_UNLOCK (gio_win32_appinfo);
+  g_mutex_unlock (&gio_win32_appinfo_mutex);
 
   if (ext == NULL)
     return NULL;
index 53f3e47..b68f882 100644 (file)
@@ -296,7 +296,7 @@ g_zlib_compressor_new (GZlibCompressorFormat format,
  *
  * Returns the #GZlibCompressor:file-info property.
  *
- * Returns: (transfer none): a #GFileInfo, or %NULL
+ * Returns: (nullable) (transfer none): a #GFileInfo, or %NULL
  *
  * Since: 2.26
  */
index cf2542e..e3f2251 100644 (file)
@@ -282,7 +282,7 @@ g_zlib_decompressor_new (GZlibCompressorFormat format)
  * or the header data was not fully processed yet, or it not present in the
  * data stream at all.
  *
- * Returns: (transfer none): a #GFileInfo, or %NULL
+ * Returns: (nullable) (transfer none): a #GFileInfo, or %NULL
  *
  * Since: 2.26
  */
index 37af82e..d1ffdf4 100644 (file)
@@ -34,7 +34,7 @@ static gboolean km_debug_enabled = FALSE;
 static GSList *missing_subs_list = NULL;
 G_LOCK_DEFINE_STATIC (missing_lock);
 
-static volatile gboolean scan_missing_running = FALSE;
+static gboolean scan_missing_running = FALSE;  /* must be accessed under @missing_lock */
 
 
 static gboolean
@@ -62,7 +62,6 @@ _km_add_missing (kqueue_sub *sub)
 
   KM_W ("adding %s to missing list\n", sub->filename);
   missing_subs_list = g_slist_prepend (missing_subs_list, sub);
-  G_UNLOCK (missing_lock);
 
   if (!scan_missing_running)
     {
@@ -73,6 +72,8 @@ _km_add_missing (kqueue_sub *sub)
       g_source_attach (source, GLIB_PRIVATE_CALL (g_get_worker_context) ());
       g_source_unref (source);
     }
+
+  G_UNLOCK (missing_lock);
 }
 
 /**
index 37af9e4..f79d220 100644 (file)
@@ -577,6 +577,7 @@ gio_sources = files(
   'gzlibdecompressor.c',
   'glistmodel.c',
   'gliststore.c',
+  '../glib/gtrace.c',
 )
 
 gio_sources += appinfo_sources
@@ -791,7 +792,7 @@ libgio = library('gio-2.0',
   #  '$(gio_win32_res_ldflag)',
   dependencies : [libz_dep, libdl_dep, libmount_dep, libglib_dep,
                   libgobject_dep, libgmodule_dep, selinux_dep, xattr_dep,
-                  platform_deps, network_libs],
+                  platform_deps, network_libs, libsysprof_capture_dep],
   c_args : gio_c_args,
   objc_args : gio_c_args,
   # intl.lib is not compatible with SAFESEH
index c4e0721..725d91e 100644 (file)
@@ -11,7 +11,7 @@ setup (Fixture       *fixture,
        gconstpointer  user_data)
 {
   fixture->applications_dir = g_build_filename (g_get_user_data_dir (), "applications", NULL);
-  g_assert_cmpint (g_mkdir_with_parents (fixture->applications_dir, 0755), ==, 0);
+  g_assert_no_errno (g_mkdir_with_parents (fixture->applications_dir, 0755));
 
   g_test_message ("Using data directory: %s", g_get_user_data_dir ());
 }
@@ -20,7 +20,7 @@ static void
 teardown (Fixture       *fixture,
           gconstpointer  user_data)
 {
-  g_assert_cmpint (g_rmdir (fixture->applications_dir), ==, 0);
+  g_assert_no_errno (g_rmdir (fixture->applications_dir));
   g_clear_pointer (&fixture->applications_dir, g_free);
 }
 
index 51de0ed..d3a09ba 100644 (file)
@@ -26,13 +26,16 @@ import shutil
 import subprocess
 import sys
 import tempfile
-import textwrap
 import unittest
 
 import taptestrunner
 
 
-Result = collections.namedtuple('Result', ('info', 'out', 'err', 'subs'))
+# Disable line length warnings as wrapping the C code templates would be hard
+# flake8: noqa: E501
+
+
+Result = collections.namedtuple("Result", ("info", "out", "err", "subs"))
 
 
 class TestCodegen(unittest.TestCase):
@@ -47,22 +50,27 @@ class TestCodegen(unittest.TestCase):
     parsing and generation code of gdbus-codegen into separate unit tests, and
     just test command line behaviour in this integration test.
     """
+
     # Track the cwd, we want to back out to that to clean up our tempdir
-    cwd = ''
+    cwd = ""
 
     def setUp(self):
         self.timeout_seconds = 10  # seconds per test
         self.tmpdir = tempfile.TemporaryDirectory()
         self.cwd = os.getcwd()
         os.chdir(self.tmpdir.name)
-        print('tmpdir:', self.tmpdir.name)
-        if 'G_TEST_BUILDDIR' in os.environ:
-            self.__codegen = \
-                os.path.join(os.environ['G_TEST_BUILDDIR'], '..',
-                             'gdbus-2.0', 'codegen', 'gdbus-codegen')
+        print("tmpdir:", self.tmpdir.name)
+        if "G_TEST_BUILDDIR" in os.environ:
+            self.__codegen = os.path.join(
+                os.environ["G_TEST_BUILDDIR"],
+                "..",
+                "gdbus-2.0",
+                "codegen",
+                "gdbus-codegen",
+            )
         else:
-            self.__codegen = shutil.which('gdbus-codegen')
-        print('codegen:', self.__codegen)
+            self.__codegen = shutil.which("gdbus-codegen")
+        print("codegen:", self.__codegen)
 
     def tearDown(self):
         os.chdir(self.cwd)
@@ -73,201 +81,200 @@ class TestCodegen(unittest.TestCase):
 
         # shebang lines are not supported on native
         # Windows consoles
-        if os.name == 'nt':
+        if os.name == "nt":
             argv.insert(0, sys.executable)
 
         argv.extend(args)
-        print('Running:', argv)
+        print("Running:", argv)
 
         env = os.environ.copy()
-        env['LC_ALL'] = 'C.UTF-8'
-        print('Environment:', env)
+        env["LC_ALL"] = "C.UTF-8"
+        print("Environment:", env)
 
         # We want to ensure consistent line endings...
-        info = subprocess.run(argv, timeout=self.timeout_seconds,
-                              stdout=subprocess.PIPE,
-                              stderr=subprocess.PIPE,
-                              env=env,
-                              universal_newlines=True)
+        info = subprocess.run(
+            argv,
+            timeout=self.timeout_seconds,
+            stdout=subprocess.PIPE,
+            stderr=subprocess.PIPE,
+            env=env,
+            universal_newlines=True,
+        )
         info.check_returncode()
         out = info.stdout.strip()
         err = info.stderr.strip()
 
         # Known substitutions for standard boilerplate
         subs = {
-            'standard_top_comment':
-                '/*\n'
-                ' * This file is generated by gdbus-codegen, do not modify it.\n'
-                ' *\n'
-                ' * The license of this code is the same as for the D-Bus interface description\n'
-                ' * it was derived from. Note that it links to GLib, so must comply with the\n'
-                ' * LGPL linking clauses.\n'
-                ' */',
-            'standard_config_h_include':
-                '#ifdef HAVE_CONFIG_H\n'
-                '#  include "config.h"\n'
-                '#endif',
-            'standard_header_includes':
-                '#include <string.h>\n'
-                '#ifdef G_OS_UNIX\n'
-                '#  include <gio/gunixfdlist.h>\n'
-                '#endif',
-            'standard_typedefs_and_helpers':
-                'typedef struct\n'
-                '{\n'
-                '  GDBusArgInfo parent_struct;\n'
-                '  gboolean use_gvariant;\n'
-                '} _ExtendedGDBusArgInfo;\n'
-                '\n'
-                'typedef struct\n'
-                '{\n'
-                '  GDBusMethodInfo parent_struct;\n'
-                '  const gchar *signal_name;\n'
-                '  gboolean pass_fdlist;\n'
-                '} _ExtendedGDBusMethodInfo;\n'
-                '\n'
-                'typedef struct\n'
-                '{\n'
-                '  GDBusSignalInfo parent_struct;\n'
-                '  const gchar *signal_name;\n'
-                '} _ExtendedGDBusSignalInfo;\n'
-                '\n'
-                'typedef struct\n'
-                '{\n'
-                '  GDBusPropertyInfo parent_struct;\n'
-                '  const gchar *hyphen_name;\n'
-                '  guint use_gvariant : 1;\n'
-                '  guint emits_changed_signal : 1;\n'
-                '} _ExtendedGDBusPropertyInfo;\n'
-                '\n'
-                'typedef struct\n'
-                '{\n'
-                '  GDBusInterfaceInfo parent_struct;\n'
-                '  const gchar *hyphen_name;\n'
-                '} _ExtendedGDBusInterfaceInfo;\n'
-                '\n'
-                'typedef struct\n'
-                '{\n'
-                '  const _ExtendedGDBusPropertyInfo *info;\n'
-                '  guint prop_id;\n'
-                '  GValue orig_value; /* the value before the change */\n'
-                '} ChangedProperty;\n'
-                '\n'
-                'static void\n'
-                '_changed_property_free (ChangedProperty *data)\n'
-                '{\n'
-                '  g_value_unset (&data->orig_value);\n'
-                '  g_free (data);\n'
-                '}\n'
-                '\n'
-                'static gboolean\n'
-                '_g_strv_equal0 (gchar **a, gchar **b)\n'
-                '{\n'
-                '  gboolean ret = FALSE;\n'
-                '  guint n;\n'
-                '  if (a == NULL && b == NULL)\n'
-                '    {\n'
-                '      ret = TRUE;\n'
-                '      goto out;\n'
-                '    }\n'
-                '  if (a == NULL || b == NULL)\n'
-                '    goto out;\n'
-                '  if (g_strv_length (a) != g_strv_length (b))\n'
-                '    goto out;\n'
-                '  for (n = 0; a[n] != NULL; n++)\n'
-                '    if (g_strcmp0 (a[n], b[n]) != 0)\n'
-                '      goto out;\n'
-                '  ret = TRUE;\n'
-                'out:\n'
-                '  return ret;\n'
-                '}\n'
-                '\n'
-                'static gboolean\n'
-                '_g_variant_equal0 (GVariant *a, GVariant *b)\n'
-                '{\n'
-                '  gboolean ret = FALSE;\n'
-                '  if (a == NULL && b == NULL)\n'
-                '    {\n'
-                '      ret = TRUE;\n'
-                '      goto out;\n'
-                '    }\n'
-                '  if (a == NULL || b == NULL)\n'
-                '    goto out;\n'
-                '  ret = g_variant_equal (a, b);\n'
-                'out:\n'
-                '  return ret;\n'
-                '}\n'
-                '\n'
-                'G_GNUC_UNUSED static gboolean\n'
-                '_g_value_equal (const GValue *a, const GValue *b)\n'
-                '{\n'
-                '  gboolean ret = FALSE;\n'
-                '  g_assert (G_VALUE_TYPE (a) == G_VALUE_TYPE (b));\n'
-                '  switch (G_VALUE_TYPE (a))\n'
-                '    {\n'
-                '      case G_TYPE_BOOLEAN:\n'
-                '        ret = (g_value_get_boolean (a) == g_value_get_boolean (b));\n'
-                '        break;\n'
-                '      case G_TYPE_UCHAR:\n'
-                '        ret = (g_value_get_uchar (a) == g_value_get_uchar (b));\n'
-                '        break;\n'
-                '      case G_TYPE_INT:\n'
-                '        ret = (g_value_get_int (a) == g_value_get_int (b));\n'
-                '        break;\n'
-                '      case G_TYPE_UINT:\n'
-                '        ret = (g_value_get_uint (a) == g_value_get_uint (b));\n'
-                '        break;\n'
-                '      case G_TYPE_INT64:\n'
-                '        ret = (g_value_get_int64 (a) == g_value_get_int64 (b));\n'
-                '        break;\n'
-                '      case G_TYPE_UINT64:\n'
-                '        ret = (g_value_get_uint64 (a) == g_value_get_uint64 (b));\n'
-                '        break;\n'
-                '      case G_TYPE_DOUBLE:\n'
-                '        {\n'
-                '          /* Avoid -Wfloat-equal warnings by doing a direct bit compare */\n'
-                '          gdouble da = g_value_get_double (a);\n'
-                '          gdouble db = g_value_get_double (b);\n'
-                '          ret = memcmp (&da, &db, sizeof (gdouble)) == 0;\n'
-                '        }\n'
-                '        break;\n'
-                '      case G_TYPE_STRING:\n'
-                '        ret = (g_strcmp0 (g_value_get_string (a), g_value_get_string (b)) == 0);\n'
-                '        break;\n'
-                '      case G_TYPE_VARIANT:\n'
-                '        ret = _g_variant_equal0 (g_value_get_variant (a), g_value_get_variant (b));\n'
-                '        break;\n'
-                '      default:\n'
-                '        if (G_VALUE_TYPE (a) == G_TYPE_STRV)\n'
-                '          ret = _g_strv_equal0 (g_value_get_boxed (a), g_value_get_boxed (b));\n'
-                '        else\n'
-                '          g_critical ("_g_value_equal() does not handle type %s", g_type_name (G_VALUE_TYPE (a)));\n'
-                '        break;\n'
-                '    }\n'
-                '  return ret;\n'
-                '}',
+            "standard_top_comment": "/*\n"
+            " * This file is generated by gdbus-codegen, do not modify it.\n"
+            " *\n"
+            " * The license of this code is the same as for the D-Bus interface description\n"
+            " * it was derived from. Note that it links to GLib, so must comply with the\n"
+            " * LGPL linking clauses.\n"
+            " */",
+            "standard_config_h_include": "#ifdef HAVE_CONFIG_H\n"
+            '#  include "config.h"\n'
+            "#endif",
+            "standard_header_includes": "#include <string.h>\n"
+            "#ifdef G_OS_UNIX\n"
+            "#  include <gio/gunixfdlist.h>\n"
+            "#endif",
+            "standard_typedefs_and_helpers": "typedef struct\n"
+            "{\n"
+            "  GDBusArgInfo parent_struct;\n"
+            "  gboolean use_gvariant;\n"
+            "} _ExtendedGDBusArgInfo;\n"
+            "\n"
+            "typedef struct\n"
+            "{\n"
+            "  GDBusMethodInfo parent_struct;\n"
+            "  const gchar *signal_name;\n"
+            "  gboolean pass_fdlist;\n"
+            "} _ExtendedGDBusMethodInfo;\n"
+            "\n"
+            "typedef struct\n"
+            "{\n"
+            "  GDBusSignalInfo parent_struct;\n"
+            "  const gchar *signal_name;\n"
+            "} _ExtendedGDBusSignalInfo;\n"
+            "\n"
+            "typedef struct\n"
+            "{\n"
+            "  GDBusPropertyInfo parent_struct;\n"
+            "  const gchar *hyphen_name;\n"
+            "  guint use_gvariant : 1;\n"
+            "  guint emits_changed_signal : 1;\n"
+            "} _ExtendedGDBusPropertyInfo;\n"
+            "\n"
+            "typedef struct\n"
+            "{\n"
+            "  GDBusInterfaceInfo parent_struct;\n"
+            "  const gchar *hyphen_name;\n"
+            "} _ExtendedGDBusInterfaceInfo;\n"
+            "\n"
+            "typedef struct\n"
+            "{\n"
+            "  const _ExtendedGDBusPropertyInfo *info;\n"
+            "  guint prop_id;\n"
+            "  GValue orig_value; /* the value before the change */\n"
+            "} ChangedProperty;\n"
+            "\n"
+            "static void\n"
+            "_changed_property_free (ChangedProperty *data)\n"
+            "{\n"
+            "  g_value_unset (&data->orig_value);\n"
+            "  g_free (data);\n"
+            "}\n"
+            "\n"
+            "static gboolean\n"
+            "_g_strv_equal0 (gchar **a, gchar **b)\n"
+            "{\n"
+            "  gboolean ret = FALSE;\n"
+            "  guint n;\n"
+            "  if (a == NULL && b == NULL)\n"
+            "    {\n"
+            "      ret = TRUE;\n"
+            "      goto out;\n"
+            "    }\n"
+            "  if (a == NULL || b == NULL)\n"
+            "    goto out;\n"
+            "  if (g_strv_length (a) != g_strv_length (b))\n"
+            "    goto out;\n"
+            "  for (n = 0; a[n] != NULL; n++)\n"
+            "    if (g_strcmp0 (a[n], b[n]) != 0)\n"
+            "      goto out;\n"
+            "  ret = TRUE;\n"
+            "out:\n"
+            "  return ret;\n"
+            "}\n"
+            "\n"
+            "static gboolean\n"
+            "_g_variant_equal0 (GVariant *a, GVariant *b)\n"
+            "{\n"
+            "  gboolean ret = FALSE;\n"
+            "  if (a == NULL && b == NULL)\n"
+            "    {\n"
+            "      ret = TRUE;\n"
+            "      goto out;\n"
+            "    }\n"
+            "  if (a == NULL || b == NULL)\n"
+            "    goto out;\n"
+            "  ret = g_variant_equal (a, b);\n"
+            "out:\n"
+            "  return ret;\n"
+            "}\n"
+            "\n"
+            "G_GNUC_UNUSED static gboolean\n"
+            "_g_value_equal (const GValue *a, const GValue *b)\n"
+            "{\n"
+            "  gboolean ret = FALSE;\n"
+            "  g_assert (G_VALUE_TYPE (a) == G_VALUE_TYPE (b));\n"
+            "  switch (G_VALUE_TYPE (a))\n"
+            "    {\n"
+            "      case G_TYPE_BOOLEAN:\n"
+            "        ret = (g_value_get_boolean (a) == g_value_get_boolean (b));\n"
+            "        break;\n"
+            "      case G_TYPE_UCHAR:\n"
+            "        ret = (g_value_get_uchar (a) == g_value_get_uchar (b));\n"
+            "        break;\n"
+            "      case G_TYPE_INT:\n"
+            "        ret = (g_value_get_int (a) == g_value_get_int (b));\n"
+            "        break;\n"
+            "      case G_TYPE_UINT:\n"
+            "        ret = (g_value_get_uint (a) == g_value_get_uint (b));\n"
+            "        break;\n"
+            "      case G_TYPE_INT64:\n"
+            "        ret = (g_value_get_int64 (a) == g_value_get_int64 (b));\n"
+            "        break;\n"
+            "      case G_TYPE_UINT64:\n"
+            "        ret = (g_value_get_uint64 (a) == g_value_get_uint64 (b));\n"
+            "        break;\n"
+            "      case G_TYPE_DOUBLE:\n"
+            "        {\n"
+            "          /* Avoid -Wfloat-equal warnings by doing a direct bit compare */\n"
+            "          gdouble da = g_value_get_double (a);\n"
+            "          gdouble db = g_value_get_double (b);\n"
+            "          ret = memcmp (&da, &db, sizeof (gdouble)) == 0;\n"
+            "        }\n"
+            "        break;\n"
+            "      case G_TYPE_STRING:\n"
+            "        ret = (g_strcmp0 (g_value_get_string (a), g_value_get_string (b)) == 0);\n"
+            "        break;\n"
+            "      case G_TYPE_VARIANT:\n"
+            "        ret = _g_variant_equal0 (g_value_get_variant (a), g_value_get_variant (b));\n"
+            "        break;\n"
+            "      default:\n"
+            "        if (G_VALUE_TYPE (a) == G_TYPE_STRV)\n"
+            "          ret = _g_strv_equal0 (g_value_get_boxed (a), g_value_get_boxed (b));\n"
+            "        else\n"
+            '          g_critical ("_g_value_equal() does not handle type %s", g_type_name (G_VALUE_TYPE (a)));\n'
+            "        break;\n"
+            "    }\n"
+            "  return ret;\n"
+            "}",
         }
 
         result = Result(info, out, err, subs)
 
-        print('Output:', result.out)
+        print("Output:", result.out)
         return result
 
     def runCodegenWithInterface(self, interface_contents, *args):
-        with tempfile.NamedTemporaryFile(dir=self.tmpdir.name,
-                                         suffix='.xml',
-                                         delete=False) as interface_file:
+        with tempfile.NamedTemporaryFile(
+            dir=self.tmpdir.name, suffix=".xml", delete=False
+        ) as interface_file:
             # Write out the interface.
-            interface_file.write(interface_contents.encode('utf-8'))
-            print(interface_file.name + ':', interface_contents)
+            interface_file.write(interface_contents.encode("utf-8"))
+            print(interface_file.name + ":", interface_contents)
             interface_file.flush()
 
             return self.runCodegen(interface_file.name, *args)
 
     def test_help(self):
         """Test the --help argument."""
-        result = self.runCodegen('--help')
-        self.assertIn('usage: gdbus-codegen', result.out)
+        result = self.runCodegen("--help")
+        self.assertIn("usage: gdbus-codegen", result.out)
 
     def test_no_args(self):
         """Test running with no arguments at all."""
@@ -276,11 +283,10 @@ class TestCodegen(unittest.TestCase):
 
     def test_empty_interface_header(self):
         """Test generating a header with an empty interface file."""
-        result = self.runCodegenWithInterface('',
-                                              '--output', '/dev/stdout',
-                                              '--header')
-        self.assertEqual('', result.err)
-        self.assertEqual('''{standard_top_comment}
+        result = self.runCodegenWithInterface("", "--output", "/dev/stdout", "--header")
+        self.assertEqual("", result.err)
+        self.assertEqual(
+            """{standard_top_comment}
 
 #ifndef __STDOUT__
 #define __STDOUT__
@@ -292,16 +298,18 @@ G_BEGIN_DECLS
 
 G_END_DECLS
 
-#endif /* __STDOUT__ */'''.format(**result.subs),
-                         result.out.strip())
+#endif /* __STDOUT__ */""".format(
+                **result.subs
+            ),
+            result.out.strip(),
+        )
 
     def test_empty_interface_body(self):
         """Test generating a body with an empty interface file."""
-        result = self.runCodegenWithInterface('',
-                                              '--output', '/dev/stdout',
-                                              '--body')
-        self.assertEqual('', result.err)
-        self.assertEqual('''{standard_top_comment}
+        result = self.runCodegenWithInterface("", "--output", "/dev/stdout", "--body")
+        self.assertEqual("", result.err)
+        self.assertEqual(
+            """{standard_top_comment}
 
 {standard_config_h_include}
 
@@ -309,12 +317,15 @@ G_END_DECLS
 
 {standard_header_includes}
 
-{standard_typedefs_and_helpers}'''.format(**result.subs),
-                         result.out.strip())
+{standard_typedefs_and_helpers}""".format(
+                **result.subs
+            ),
+            result.out.strip(),
+        )
 
     def test_reproducible(self):
         """Test builds are reproducible regardless of file ordering."""
-        xml_contents1 = '''
+        xml_contents1 = """
         <node>
           <interface name="com.acme.Coyote">
             <method name="Run"/>
@@ -324,40 +335,49 @@ G_END_DECLS
             <property name="Mood" type="s" access="read"/>
           </interface>
         </node>
-        '''
+        """
 
-        xml_contents2 = '''
+        xml_contents2 = """
         <node>
           <interface name="org.project.Bar.Frobnicator">
             <method name="RandomMethod"/>
           </interface>
         </node>
-        '''
+        """
 
-        with tempfile.NamedTemporaryFile(dir=self.tmpdir.name,
-                                         suffix='1.xml', delete=False) as xml_file1, \
-             tempfile.NamedTemporaryFile(dir=self.tmpdir.name,
-                                         suffix='2.xml', delete=False) as xml_file2:
+        with tempfile.NamedTemporaryFile(
+            dir=self.tmpdir.name, suffix="1.xml", delete=False
+        ) as xml_file1, tempfile.NamedTemporaryFile(
+            dir=self.tmpdir.name, suffix="2.xml", delete=False
+        ) as xml_file2:
             # Write out the interfaces.
-            xml_file1.write(xml_contents1.encode('utf-8'))
-            xml_file2.write(xml_contents2.encode('utf-8'))
+            xml_file1.write(xml_contents1.encode("utf-8"))
+            xml_file2.write(xml_contents2.encode("utf-8"))
 
             xml_file1.flush()
             xml_file2.flush()
 
             # Repeat this for headers and bodies.
-            for header_or_body in ['--header', '--body']:
+            for header_or_body in ["--header", "--body"]:
                 # Run gdbus-codegen with the interfaces in one order, and then
                 # again in another order.
-                result1 = self.runCodegen(xml_file1.name, xml_file2.name,
-                                          '--output', '/dev/stdout',
-                                          header_or_body)
-                self.assertEqual('', result1.err)
-
-                result2 = self.runCodegen(xml_file2.name, xml_file1.name,
-                                          '--output', '/dev/stdout',
-                                          header_or_body)
-                self.assertEqual('', result2.err)
+                result1 = self.runCodegen(
+                    xml_file1.name,
+                    xml_file2.name,
+                    "--output",
+                    "/dev/stdout",
+                    header_or_body,
+                )
+                self.assertEqual("", result1.err)
+
+                result2 = self.runCodegen(
+                    xml_file2.name,
+                    xml_file1.name,
+                    "--output",
+                    "/dev/stdout",
+                    header_or_body,
+                )
+                self.assertEqual("", result2.err)
 
                 # The output should be the same.
                 self.assertEqual(result1.out, result2.out)
@@ -365,94 +385,108 @@ G_END_DECLS
     def test_glib_min_required_invalid(self):
         """Test running with an invalid --glib-min-required."""
         with self.assertRaises(subprocess.CalledProcessError):
-            self.runCodegenWithInterface('',
-                                         '--output', '/dev/stdout',
-                                         '--body',
-                                         '--glib-min-required', 'hello mum')
+            self.runCodegenWithInterface(
+                "",
+                "--output",
+                "/dev/stdout",
+                "--body",
+                "--glib-min-required",
+                "hello mum",
+            )
 
     def test_glib_min_required_too_low(self):
         """Test running with a --glib-min-required which is too low (and hence
         probably a typo)."""
         with self.assertRaises(subprocess.CalledProcessError):
-            self.runCodegenWithInterface('',
-                                         '--output', '/dev/stdout',
-                                         '--body',
-                                         '--glib-min-required', '2.6')
+            self.runCodegenWithInterface(
+                "", "--output", "/dev/stdout", "--body", "--glib-min-required", "2.6"
+            )
 
     def test_glib_min_required_major_only(self):
         """Test running with a --glib-min-required which contains only a major version."""
-        result = self.runCodegenWithInterface('',
-                                              '--output', '/dev/stdout',
-                                              '--header',
-                                              '--glib-min-required', '3',
-                                              '--glib-max-allowed', '3.2')
-        self.assertEqual('', result.err)
-        self.assertNotEqual('', result.out.strip())
+        result = self.runCodegenWithInterface(
+            "",
+            "--output",
+            "/dev/stdout",
+            "--header",
+            "--glib-min-required",
+            "3",
+            "--glib-max-allowed",
+            "3.2",
+        )
+        self.assertEqual("", result.err)
+        self.assertNotEqual("", result.out.strip())
 
     def test_glib_min_required_with_micro(self):
         """Test running with a --glib-min-required which contains a micro version."""
-        result = self.runCodegenWithInterface('',
-                                              '--output', '/dev/stdout',
-                                              '--header',
-                                              '--glib-min-required', '2.46.2')
-        self.assertEqual('', result.err)
-        self.assertNotEqual('', result.out.strip())
+        result = self.runCodegenWithInterface(
+            "", "--output", "/dev/stdout", "--header", "--glib-min-required", "2.46.2"
+        )
+        self.assertEqual("", result.err)
+        self.assertNotEqual("", result.out.strip())
 
     def test_glib_max_allowed_too_low(self):
         """Test running with a --glib-max-allowed which is too low (and hence
         probably a typo)."""
         with self.assertRaises(subprocess.CalledProcessError):
-            self.runCodegenWithInterface('',
-                                         '--output', '/dev/stdout',
-                                         '--body',
-                                         '--glib-max-allowed', '2.6')
+            self.runCodegenWithInterface(
+                "", "--output", "/dev/stdout", "--body", "--glib-max-allowed", "2.6"
+            )
 
     def test_glib_max_allowed_major_only(self):
         """Test running with a --glib-max-allowed which contains only a major version."""
-        result = self.runCodegenWithInterface('',
-                                              '--output', '/dev/stdout',
-                                              '--header',
-                                              '--glib-max-allowed', '3')
-        self.assertEqual('', result.err)
-        self.assertNotEqual('', result.out.strip())
+        result = self.runCodegenWithInterface(
+            "", "--output", "/dev/stdout", "--header", "--glib-max-allowed", "3"
+        )
+        self.assertEqual("", result.err)
+        self.assertNotEqual("", result.out.strip())
 
     def test_glib_max_allowed_with_micro(self):
         """Test running with a --glib-max-allowed which contains a micro version."""
-        result = self.runCodegenWithInterface('',
-                                              '--output', '/dev/stdout',
-                                              '--header',
-                                              '--glib-max-allowed', '2.46.2')
-        self.assertEqual('', result.err)
-        self.assertNotEqual('', result.out.strip())
+        result = self.runCodegenWithInterface(
+            "", "--output", "/dev/stdout", "--header", "--glib-max-allowed", "2.46.2"
+        )
+        self.assertEqual("", result.err)
+        self.assertNotEqual("", result.out.strip())
 
     def test_glib_max_allowed_unstable(self):
         """Test running with a --glib-max-allowed which is unstable. It should
         be rounded up to the next stable version number, and hence should not
         end up less than --glib-min-required."""
-        result = self.runCodegenWithInterface('',
-                                              '--output', '/dev/stdout',
-                                              '--header',
-                                              '--glib-max-allowed', '2.63',
-                                              '--glib-min-required', '2.64')
-        self.assertEqual('', result.err)
-        self.assertNotEqual('', result.out.strip())
+        result = self.runCodegenWithInterface(
+            "",
+            "--output",
+            "/dev/stdout",
+            "--header",
+            "--glib-max-allowed",
+            "2.63",
+            "--glib-min-required",
+            "2.64",
+        )
+        self.assertEqual("", result.err)
+        self.assertNotEqual("", result.out.strip())
 
     def test_glib_max_allowed_less_than_min_required(self):
         """Test running with a --glib-max-allowed which is less than
         --glib-min-required."""
         with self.assertRaises(subprocess.CalledProcessError):
-            self.runCodegenWithInterface('',
-                                         '--output', '/dev/stdout',
-                                         '--body',
-                                         '--glib-max-allowed', '2.62',
-                                         '--glib-min-required', '2.64')
+            self.runCodegenWithInterface(
+                "",
+                "--output",
+                "/dev/stdout",
+                "--body",
+                "--glib-max-allowed",
+                "2.62",
+                "--glib-min-required",
+                "2.64",
+            )
 
     def test_unix_fd_types_and_annotations(self):
         """Test an interface with `h` arguments, no annotation, and GLib < 2.64.
 
         See issue #1726.
         """
-        interface_xml = '''
+        interface_xml = """
             <node>
               <interface name="FDPassing">
                 <method name="HelloFD">
@@ -470,71 +504,87 @@ G_END_DECLS
                   <arg name="files" type="a{sh}" direction="in"/>
                 </method>
               </interface>
-            </node>'''
+            </node>"""
 
         # Try without specifying --glib-min-required.
-        result = self.runCodegenWithInterface(interface_xml,
-                                              '--output', '/dev/stdout',
-                                              '--header')
-        self.assertEqual('', result.err)
-        self.assertEqual(result.out.strip().count('GUnixFDList'), 6)
+        result = self.runCodegenWithInterface(
+            interface_xml, "--output", "/dev/stdout", "--header"
+        )
+        self.assertEqual("", result.err)
+        self.assertEqual(result.out.strip().count("GUnixFDList"), 6)
 
         # Specify an old --glib-min-required.
-        result = self.runCodegenWithInterface(interface_xml,
-                                              '--output', '/dev/stdout',
-                                              '--header',
-                                              '--glib-min-required', '2.32')
-        self.assertEqual('', result.err)
-        self.assertEqual(result.out.strip().count('GUnixFDList'), 6)
+        result = self.runCodegenWithInterface(
+            interface_xml,
+            "--output",
+            "/dev/stdout",
+            "--header",
+            "--glib-min-required",
+            "2.32",
+        )
+        self.assertEqual("", result.err)
+        self.assertEqual(result.out.strip().count("GUnixFDList"), 6)
 
         # Specify a --glib-min-required ≥ 2.64. There should be more
         # mentions of `GUnixFDList` now, since the annotation is not needed to
         # trigger its use.
-        result = self.runCodegenWithInterface(interface_xml,
-                                              '--output', '/dev/stdout',
-                                              '--header',
-                                              '--glib-min-required', '2.64')
-        self.assertEqual('', result.err)
-        self.assertEqual(result.out.strip().count('GUnixFDList'), 18)
+        result = self.runCodegenWithInterface(
+            interface_xml,
+            "--output",
+            "/dev/stdout",
+            "--header",
+            "--glib-min-required",
+            "2.64",
+        )
+        self.assertEqual("", result.err)
+        self.assertEqual(result.out.strip().count("GUnixFDList"), 18)
 
     def test_call_flags_and_timeout_method_args(self):
         """Test that generated method call functions have @call_flags and
         @timeout_msec args if and only if GLib >= 2.64.
         """
-        interface_xml = '''
+        interface_xml = """
             <node>
               <interface name="org.project.UsefulInterface">
                 <method name="UsefulMethod"/>
               </interface>
-            </node>'''
+            </node>"""
 
         # Try without specifying --glib-min-required.
-        result = self.runCodegenWithInterface(interface_xml,
-                                              '--output', '/dev/stdout',
-                                              '--header')
-        self.assertEqual('', result.err)
-        self.assertEqual(result.out.strip().count('GDBusCallFlags call_flags,'), 0)
-        self.assertEqual(result.out.strip().count('gint timeout_msec,'), 0)
+        result = self.runCodegenWithInterface(
+            interface_xml, "--output", "/dev/stdout", "--header"
+        )
+        self.assertEqual("", result.err)
+        self.assertEqual(result.out.strip().count("GDBusCallFlags call_flags,"), 0)
+        self.assertEqual(result.out.strip().count("gint timeout_msec,"), 0)
 
         # Specify an old --glib-min-required.
-        result = self.runCodegenWithInterface(interface_xml,
-                                              '--output', '/dev/stdout',
-                                              '--header',
-                                              '--glib-min-required', '2.32')
-        self.assertEqual('', result.err)
-        self.assertEqual(result.out.strip().count('GDBusCallFlags call_flags,'), 0)
-        self.assertEqual(result.out.strip().count('gint timeout_msec,'), 0)
+        result = self.runCodegenWithInterface(
+            interface_xml,
+            "--output",
+            "/dev/stdout",
+            "--header",
+            "--glib-min-required",
+            "2.32",
+        )
+        self.assertEqual("", result.err)
+        self.assertEqual(result.out.strip().count("GDBusCallFlags call_flags,"), 0)
+        self.assertEqual(result.out.strip().count("gint timeout_msec,"), 0)
 
         # Specify a --glib-min-required ≥ 2.64. The two arguments should be
         # present for both the async and sync method call functions.
-        result = self.runCodegenWithInterface(interface_xml,
-                                              '--output', '/dev/stdout',
-                                              '--header',
-                                              '--glib-min-required', '2.64')
-        self.assertEqual('', result.err)
-        self.assertEqual(result.out.strip().count('GDBusCallFlags call_flags,'), 2)
-        self.assertEqual(result.out.strip().count('gint timeout_msec,'), 2)
-
-
-if __name__ == '__main__':
+        result = self.runCodegenWithInterface(
+            interface_xml,
+            "--output",
+            "/dev/stdout",
+            "--header",
+            "--glib-min-required",
+            "2.64",
+        )
+        self.assertEqual("", result.err)
+        self.assertEqual(result.out.strip().count("GDBusCallFlags call_flags,"), 2)
+        self.assertEqual(result.out.strip().count("gint timeout_msec,"), 2)
+
+
+if __name__ == "__main__":
     unittest.main(testRunner=taptestrunner.TAPTestRunner())
index f4e509a..27af993 100644 (file)
@@ -350,6 +350,7 @@ wait_for_file (const gchar *want_this,
 static void
 test_actions (void)
 {
+  const char *expected[] = { "frob", "tweak", "twiddle", "broken", NULL };
   const gchar * const *actions;
   GDesktopAppInfo *appinfo;
   gchar *name;
@@ -358,11 +359,7 @@ test_actions (void)
   g_assert_nonnull (appinfo);
 
   actions = g_desktop_app_info_list_actions (appinfo);
-  g_assert_cmpstr (actions[0], ==, "frob");
-  g_assert_cmpstr (actions[1], ==, "tweak");
-  g_assert_cmpstr (actions[2], ==, "twiddle");
-  g_assert_cmpstr (actions[3], ==, "broken");
-  g_assert_cmpstr (actions[4], ==, NULL);
+  g_assert_cmpstrv (actions, expected);
 
   name = g_desktop_app_info_get_action_name (appinfo, "frob");
   g_assert_cmpstr (name, ==, "Frobnicate");
diff --git a/gio/tests/empty.txt b/gio/tests/empty.txt
new file mode 100644 (file)
index 0000000..e69de29
index 809b0ec..1a02b5e 100644 (file)
@@ -221,7 +221,7 @@ test_internal_enhanced_stdio (void)
   guint64 size_p0, alsize_p0, size_ps, alsize_ps;
   const gchar *id_p0;
   const gchar *id_p1;
-  volatile guint64 time_p0;
+  guint64 time_p0;
   gchar *tmp_dir;
   wchar_t *programdata_dir_w;
   wchar_t *users_dir_w;
index 73a034b..8c92582 100644 (file)
@@ -43,9 +43,9 @@ G_LOCK_DEFINE_STATIC (write);
 typedef struct {
     GFilterOutputStream parent;
 
-    volatile gint started;
-    volatile gint finished;
-    volatile gint flushed;
+    gint started;  /* (atomic) */
+    gint finished;  /* (atomic) */
+    gint flushed;  /* (atomic) */
 
     GOutputStream *real_output;
 } MyOutputStream;
index 2785706..51dd27f 100644 (file)
@@ -61,9 +61,9 @@ _log (const gchar *format, ...)
 static gboolean
 test_connection_quit_mainloop (gpointer user_data)
 {
-  volatile gboolean *quit_mainloop_fired = user_data;
+  gboolean *quit_mainloop_fired = user_data;  /* (atomic) */
   _log ("quit_mainloop_fired");
-  *quit_mainloop_fired = TRUE;
+  g_atomic_int_set (quit_mainloop_fired, TRUE);
   g_main_loop_quit (loop);
   return G_SOURCE_CONTINUE;
 }
@@ -113,8 +113,8 @@ on_name_owner_changed (GDBusConnection *connection,
 static void
 a_gdestroynotify_that_sets_a_gboolean_to_true_and_quits_loop (gpointer user_data)
 {
-  volatile gboolean *val = user_data;
-  *val = TRUE;
+  gboolean *val = user_data;  /* (atomic) */
+  g_atomic_int_set (val, TRUE);
   _log ("destroynotify fired for %p", val);
   g_main_loop_quit (loop);
 }
@@ -143,10 +143,10 @@ test_connection_life_cycle (void)
   GDBusConnection *c;
   GDBusConnection *c2;
   GError *error;
-  volatile gboolean on_signal_registration_freed_called;
-  volatile gboolean on_filter_freed_called;
-  volatile gboolean on_register_object_freed_called;
-  volatile gboolean quit_mainloop_fired;
+  gboolean on_signal_registration_freed_called;  /* (atomic) */
+  gboolean on_filter_freed_called;  /* (atomic) */
+  gboolean on_register_object_freed_called;  /* (atomic) */
+  gboolean quit_mainloop_fired;  /* (atomic) */
   guint quit_mainloop_id;
   guint registration_id;
 
@@ -208,7 +208,7 @@ test_connection_life_cycle (void)
   g_assert_no_error (error);
   g_assert_nonnull (c2);
   /* signal registration */
-  on_signal_registration_freed_called = FALSE;
+  g_atomic_int_set (&on_signal_registration_freed_called, FALSE);
   g_dbus_connection_signal_subscribe (c2,
                                       "org.freedesktop.DBus", /* bus name */
                                       "org.freedesktop.DBus", /* interface */
@@ -220,13 +220,13 @@ test_connection_life_cycle (void)
                                       (gpointer) &on_signal_registration_freed_called,
                                       a_gdestroynotify_that_sets_a_gboolean_to_true_and_quits_loop);
   /* filter func */
-  on_filter_freed_called = FALSE;
+  g_atomic_int_set (&on_filter_freed_called, FALSE);
   g_dbus_connection_add_filter (c2,
                                 some_filter_func,
                                 (gpointer) &on_filter_freed_called,
                                 a_gdestroynotify_that_sets_a_gboolean_to_true_and_quits_loop);
   /* object registration */
-  on_register_object_freed_called = FALSE;
+  g_atomic_int_set (&on_register_object_freed_called, FALSE);
   error = NULL;
   registration_id = g_dbus_connection_register_object (c2,
                                                        "/foo",
@@ -239,7 +239,7 @@ test_connection_life_cycle (void)
   g_assert_cmpuint (registration_id, >, 0);
   /* ok, finalize the connection and check that all the GDestroyNotify functions are invoked as expected */
   g_object_unref (c2);
-  quit_mainloop_fired = FALSE;
+  g_atomic_int_set (&quit_mainloop_fired, FALSE);
   quit_mainloop_id = g_timeout_add (30000, test_connection_quit_mainloop, (gpointer) &quit_mainloop_fired);
   _log ("destroynotifies for\n"
         " register_object %p\n"
@@ -250,21 +250,21 @@ test_connection_life_cycle (void)
         &on_signal_registration_freed_called);
   while (TRUE)
     {
-      if (on_signal_registration_freed_called &&
-          on_filter_freed_called &&
-          on_register_object_freed_called)
+      if (g_atomic_int_get (&on_signal_registration_freed_called) &&
+          g_atomic_int_get (&on_filter_freed_called) &&
+          g_atomic_int_get (&on_register_object_freed_called))
         break;
-      if (quit_mainloop_fired)
+      if (g_atomic_int_get (&quit_mainloop_fired))
         break;
       _log ("entering loop");
       g_main_loop_run (loop);
       _log ("exiting loop");
     }
   g_source_remove (quit_mainloop_id);
-  g_assert_true (on_signal_registration_freed_called);
-  g_assert_true (on_filter_freed_called);
-  g_assert_true (on_register_object_freed_called);
-  g_assert_false (quit_mainloop_fired);
+  g_assert_true (g_atomic_int_get (&on_signal_registration_freed_called));
+  g_assert_true (g_atomic_int_get (&on_filter_freed_called));
+  g_assert_true (g_atomic_int_get (&on_register_object_freed_called));
+  g_assert_false (g_atomic_int_get (&quit_mainloop_fired));
 
   /*
    *  Check for correct behavior when the bus goes away
index ca3d5d0..d3e1eb2 100644 (file)
@@ -86,8 +86,8 @@ overflow_filter_func (GDBusConnection *connection,
                       gboolean         incoming,
                       gpointer         user_data)
 {
-  volatile gint *counter = user_data;
-  *counter += 1;
+  gint *counter = user_data;  /* (atomic) */
+  g_atomic_int_inc (counter);
   return message;
 }
 
@@ -108,8 +108,8 @@ test_overflow (void)
   GDBusConnection *producer, *consumer;
   GError *error;
   GTimer *timer;
-  volatile gint n_messages_received;
-  volatile gint n_messages_sent;
+  gint n_messages_received;  /* (atomic) */
+  gint n_messages_sent;  /* (atomic) */
 
   g_assert_cmpint (socketpair (AF_UNIX, SOCK_STREAM, 0, sv), ==, 0);
 
@@ -129,7 +129,7 @@ test_overflow (void)
   g_dbus_connection_set_exit_on_close (producer, TRUE);
   g_assert_no_error (error);
   g_object_unref (socket_connection);
-  n_messages_sent = 0;
+  g_atomic_int_set (&n_messages_sent, 0);
   g_dbus_connection_add_filter (producer, overflow_filter_func, (gpointer) &n_messages_sent, NULL);
 
   /* send enough data that we get an EAGAIN */
@@ -155,7 +155,7 @@ test_overflow (void)
    */
   g_timeout_add (500, overflow_on_500ms_later_func, NULL);
   g_main_loop_run (loop);
-  g_assert_cmpint (n_messages_sent, <, OVERFLOW_NUM_SIGNALS);
+  g_assert_cmpint (g_atomic_int_get (&n_messages_sent), <, OVERFLOW_NUM_SIGNALS);
 
   /* now suck it all out as a client, and add it up */
   socket = g_socket_new_from_fd (sv[1], &error);
@@ -171,18 +171,18 @@ test_overflow (void)
                                         &error);
   g_assert_no_error (error);
   g_object_unref (socket_connection);
-  n_messages_received = 0;
+  g_atomic_int_set (&n_messages_received, 0);
   g_dbus_connection_add_filter (consumer, overflow_filter_func, (gpointer) &n_messages_received, NULL);
   g_dbus_connection_start_message_processing (consumer);
 
   timer = g_timer_new ();
   g_timer_start (timer);
 
-  while (n_messages_received < OVERFLOW_NUM_SIGNALS && g_timer_elapsed (timer, NULL) < OVERFLOW_TIMEOUT_SEC)
+  while (g_atomic_int_get (&n_messages_received) < OVERFLOW_NUM_SIGNALS && g_timer_elapsed (timer, NULL) < OVERFLOW_TIMEOUT_SEC)
       g_main_context_iteration (NULL, FALSE);
 
-  g_assert_cmpint (n_messages_sent, ==, OVERFLOW_NUM_SIGNALS);
-  g_assert_cmpint (n_messages_received, ==, OVERFLOW_NUM_SIGNALS);
+  g_assert_cmpint (g_atomic_int_get (&n_messages_sent), ==, OVERFLOW_NUM_SIGNALS);
+  g_assert_cmpint (g_atomic_int_get (&n_messages_received), ==, OVERFLOW_NUM_SIGNALS);
 
   g_timer_destroy (timer);
   g_object_unref (consumer);
index ca53528..23a2298 100644 (file)
@@ -76,6 +76,12 @@ typedef struct
   gboolean signal_received;
 } PeerData;
 
+/* This needs to be enough to usually take more than one write(),
+ * to reproduce
+ * <https://gitlab.gnome.org/GNOME/glib/-/issues/2074>.
+ * 1 MiB ought to be enough. */
+#define BIG_MESSAGE_ARRAY_SIZE (1024 * 1024)
+
 static const gchar *test_interface_introspection_xml =
   "<node>"
   "  <interface name='org.gtk.GDBus.PeerTestInterface'>"
@@ -88,6 +94,11 @@ static const gchar *test_interface_introspection_xml =
   "    <method name='OpenFile'>"
   "      <arg type='s' name='path' direction='in'/>"
   "    </method>"
+  "    <method name='OpenFileWithBigMessage'>"
+  "      <arg type='s' name='path' direction='in'/>"
+  "      <arg type='h' name='handle' direction='out'/>"
+  "      <arg type='ay' name='junk' direction='out'/>"
+  "    </method>"
   "    <signal name='PeerSignal'>"
   "      <arg type='s' name='a_string'/>"
   "    </signal>"
@@ -164,7 +175,8 @@ test_interface_method_call (GDBusConnection       *connection,
 
       g_dbus_method_invocation_return_value (invocation, NULL);
     }
-  else if (g_strcmp0 (method_name, "OpenFile") == 0)
+  else if (g_strcmp0 (method_name, "OpenFile") == 0 ||
+           g_strcmp0 (method_name, "OpenFileWithBigMessage") == 0)
     {
 #ifdef G_OS_UNIX
       const gchar *path;
@@ -190,6 +202,21 @@ test_interface_method_call (GDBusConnection       *connection,
       g_object_unref (fd_list);
       g_object_unref (invocation);
 
+      if (g_strcmp0 (method_name, "OpenFileWithBigMessage") == 0)
+        {
+          char *junk;
+
+          junk = g_new0 (char, BIG_MESSAGE_ARRAY_SIZE);
+          g_dbus_message_set_body (reply,
+                                   g_variant_new ("(h@ay)",
+                                                  0,
+                                                  g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
+                                                                             junk,
+                                                                             BIG_MESSAGE_ARRAY_SIZE,
+                                                                             1)));
+          g_free (junk);
+        }
+
       error = NULL;
       g_dbus_connection_send_message (connection,
                                       reply,
@@ -723,6 +750,7 @@ do_test_peer (void)
   const gchar *s;
   GThread *service_thread;
   gulong signal_handler_id;
+  gsize i;
 
   memset (&data, '\0', sizeof (PeerData));
   data.current_connections = g_ptr_array_new_with_free_func (g_object_unref);
@@ -843,73 +871,116 @@ do_test_peer (void)
   g_assert_cmpint (data.num_method_calls, ==, 3);
   g_signal_handler_disconnect (proxy, signal_handler_id);
 
-  /* check for UNIX fd passing */
+  /*
+   * Check for UNIX fd passing.
+   *
+   * The first time through, we use a very simple method call. Note that
+   * because this does not have a G_VARIANT_TYPE_HANDLE in the message body
+   * to refer to the fd, it is a GDBus-specific idiom that would not
+   * interoperate with libdbus or sd-bus
+   * (see <https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1726>).
+   *
+   * The second time, we call a method that returns a fd attached to a
+   * large message, to reproduce
+   * <https://gitlab.gnome.org/GNOME/glib/-/issues/2074>. It also happens
+   * to follow the more usual pattern for D-Bus messages containing a
+   * G_VARIANT_TYPE_HANDLE to refer to attached fds.
+   */
+  for (i = 0; i < 2; i++)
+    {
 #ifdef G_OS_UNIX
-  {
-    GDBusMessage *method_call_message;
-    GDBusMessage *method_reply_message;
-    GUnixFDList *fd_list;
-    gint fd;
-    gchar *buf;
-    gsize len;
-    gchar *buf2;
-    gsize len2;
-    const char *testfile = g_test_get_filename (G_TEST_DIST, "file.c", NULL);
-
-    method_call_message = g_dbus_message_new_method_call (NULL, /* name */
-                                                          "/org/gtk/GDBus/PeerTestObject",
-                                                          "org.gtk.GDBus.PeerTestInterface",
-                                                          "OpenFile");
-    g_dbus_message_set_body (method_call_message, g_variant_new ("(s)", testfile));
-    error = NULL;
-    method_reply_message = g_dbus_connection_send_message_with_reply_sync (c,
-                                                                           method_call_message,
-                                                                           G_DBUS_SEND_MESSAGE_FLAGS_NONE,
-                                                                           -1,
-                                                                           NULL, /* out_serial */
-                                                                           NULL, /* cancellable */
-                                                                           &error);
-    g_assert_no_error (error);
-    g_assert (g_dbus_message_get_message_type (method_reply_message) == G_DBUS_MESSAGE_TYPE_METHOD_RETURN);
-    fd_list = g_dbus_message_get_unix_fd_list (method_reply_message);
-    g_assert (fd_list != NULL);
-    g_assert_cmpint (g_unix_fd_list_get_length (fd_list), ==, 1);
-    error = NULL;
-    fd = g_unix_fd_list_get (fd_list, 0, &error);
-    g_assert_no_error (error);
-    g_object_unref (method_call_message);
-    g_object_unref (method_reply_message);
+      GDBusMessage *method_call_message;
+      GDBusMessage *method_reply_message;
+      GUnixFDList *fd_list;
+      gint fd;
+      gchar *buf;
+      gsize len;
+      gchar *buf2;
+      gsize len2;
+      const char *testfile = g_test_get_filename (G_TEST_DIST, "file.c", NULL);
+      const char *method = "OpenFile";
+      GVariant *body;
+
+      if (i == 1)
+        method = "OpenFileWithBigMessage";
+
+      method_call_message = g_dbus_message_new_method_call (NULL, /* name */
+                                                            "/org/gtk/GDBus/PeerTestObject",
+                                                            "org.gtk.GDBus.PeerTestInterface",
+                                                            method);
+      g_dbus_message_set_body (method_call_message, g_variant_new ("(s)", testfile));
+      error = NULL;
+      method_reply_message = g_dbus_connection_send_message_with_reply_sync (c,
+                                                                             method_call_message,
+                                                                             G_DBUS_SEND_MESSAGE_FLAGS_NONE,
+                                                                             -1,
+                                                                             NULL, /* out_serial */
+                                                                             NULL, /* cancellable */
+                                                                             &error);
+      g_assert_no_error (error);
+      g_assert (g_dbus_message_get_message_type (method_reply_message) == G_DBUS_MESSAGE_TYPE_METHOD_RETURN);
 
-    error = NULL;
-    len = 0;
-    buf = read_all_from_fd (fd, &len, &error);
-    g_assert_no_error (error);
-    g_assert (buf != NULL);
-    close (fd);
+      body = g_dbus_message_get_body (method_reply_message);
 
-    error = NULL;
-    g_file_get_contents (testfile,
-                         &buf2,
-                         &len2,
-                         &error);
-    g_assert_no_error (error);
-    g_assert_cmpmem (buf, len, buf2, len2);
-    g_free (buf2);
-    g_free (buf);
-  }
+      if (i == 1)
+        {
+          gint32 handle = -1;
+          GVariant *junk = NULL;
+
+          g_assert_cmpstr (g_variant_get_type_string (body), ==, "(hay)");
+          g_variant_get (body, "(h@ay)", &handle, &junk);
+          g_assert_cmpint (handle, ==, 0);
+          g_assert_cmpuint (g_variant_n_children (junk), ==, BIG_MESSAGE_ARRAY_SIZE);
+          g_variant_unref (junk);
+        }
+      else
+        {
+          g_assert_null (body);
+        }
+
+      fd_list = g_dbus_message_get_unix_fd_list (method_reply_message);
+      g_assert (fd_list != NULL);
+      g_assert_cmpint (g_unix_fd_list_get_length (fd_list), ==, 1);
+      error = NULL;
+      fd = g_unix_fd_list_get (fd_list, 0, &error);
+      g_assert_no_error (error);
+      g_object_unref (method_call_message);
+      g_object_unref (method_reply_message);
+
+      error = NULL;
+      len = 0;
+      buf = read_all_from_fd (fd, &len, &error);
+      g_assert_no_error (error);
+      g_assert (buf != NULL);
+      close (fd);
+
+      error = NULL;
+      g_file_get_contents (testfile,
+                           &buf2,
+                           &len2,
+                           &error);
+      g_assert_no_error (error);
+      g_assert_cmpmem (buf, len, buf2, len2);
+      g_free (buf2);
+      g_free (buf);
 #else
-  error = NULL;
-  result = g_dbus_proxy_call_sync (proxy,
-                                   "OpenFile",
-                                   g_variant_new ("(s)", "boo"),
-                                   G_DBUS_CALL_FLAGS_NONE,
-                                   -1,
-                                   NULL,  /* GCancellable */
-                                   &error);
-  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_DBUS_ERROR);
-  g_assert (result == NULL);
-  g_error_free (error);
+      /* We do the same number of iterations on non-Unix, so that
+       * the method call count will match. In this case we use
+       * OpenFile both times, because the difference between this
+       * and OpenFileWithBigMessage is only relevant on Unix. */
+      error = NULL;
+      result = g_dbus_proxy_call_sync (proxy,
+                                       "OpenFile",
+                                       g_variant_new ("(s)", "boo"),
+                                       G_DBUS_CALL_FLAGS_NONE,
+                                       -1,
+                                       NULL,  /* GCancellable */
+                                       &error);
+      g_assert_error (error, G_IO_ERROR, G_IO_ERROR_DBUS_ERROR);
+      g_assert (result == NULL);
+      g_error_free (error);
 #endif /* G_OS_UNIX */
+    }
 
   /* Check that g_socket_get_credentials() work - (though this really
    * should be in socket.c)
@@ -1017,7 +1088,7 @@ do_test_peer (void)
   g_variant_get (result, "(&s)", &s);
   g_assert_cmpstr (s, ==, "You greeted me with 'Hey Again Peer!'.");
   g_variant_unref (result);
-  g_assert_cmpint (data.num_method_calls, ==, 5);
+  g_assert_cmpint (data.num_method_calls, ==, 6);
 
 #if 0
   /* TODO: THIS TEST DOESN'T WORK YET */
index 7bc53c6..2ef70b1 100644 (file)
@@ -1118,28 +1118,37 @@ test_message_serialize_double_array (void)
 
 /* Test that an invalid header in a D-Bus message (specifically, with a type
  * which doesn’t match what’s expected for the given header) is gracefully
- * handled with an error rather than a crash.
- * The set of bytes here come directly from fuzzer output. */
+ * handled with an error rather than a crash. */
 static void
 test_message_parse_non_signature_header (void)
 {
   const guint8 data[] = {
     'l',  /* little-endian byte order */
-    0x04,  /* message type */
-    0x0f,  /* message flags */
+    0x02,  /* message type (method return) */
+    0x00,  /* message flags (none) */
     0x01,  /* major protocol version */
-    0x00, 0x00, 0x00, 0x00,  /* body length */
+    0x00, 0x00, 0x00, 0x00,  /* body length (in bytes) */
     0x00, 0x00, 0x00, 0xbc,  /* message serial */
     /* a{yv} of header fields:
      * (things start to be invalid below here) */
-    0x02, 0x00, 0x00, 0x00,  /* array length (in bytes) */
-      G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE, /* array key */
+    0x10, 0x00, 0x00, 0x00,  /* array length (in bytes), must be a multiple of 8 */
+      0x08, /* array key (SIGNATURE) */
       /* Variant array value: */
       0x04, /* signature length */
       'd', 0x00, 0x00, 'F',  /* signature (invalid) */
       0x00,  /* nul terminator */
       /* (Variant array value payload missing) */
-    /* (message body length missing) */
+      /* alignment padding before the next header array element, as structs must
+       * be 8-aligned: */
+      0x00,
+      0x05,  /* array key (REPLY_SERIAL, required for method return messages) */
+      /* Variant array value: */
+      0x01,  /* signature length */
+      'u',  /* one complete type */
+      0x00,  /* nul terminator */
+      /* (Variant array value payload) */
+      0x00, 0x01, 0x02, 0x03,
+    /* (message body is zero-length) */
   };
   gsize size = sizeof (data);
   GDBusMessage *message = NULL;
@@ -1158,27 +1167,36 @@ test_message_parse_non_signature_header (void)
 
 /* Test that an invalid header in a D-Bus message (specifically, containing a
  * variant with an empty type signature) is gracefully handled with an error
- * rather than a crash. The set of bytes here come directly from fuzzer
- * output. */
+ * rather than a crash. */
 static void
 test_message_parse_empty_signature_header (void)
 {
   const guint8 data[] = {
     'l',  /* little-endian byte order */
-    0x20,  /* message type */
-    0x20,  /* message flags */
+    0x02,  /* message type (method return) */
+    0x00,  /* message flags (none) */
     0x01,  /* major protocol version */
-    0x20, 0x20, 0x20, 0x00,  /* body length (invalid) */
+    0x00, 0x00, 0x00, 0x00,  /* body length (in bytes) */
     0x20, 0x20, 0x20, 0x20,  /* message serial */
     /* a{yv} of header fields:
-     * (things start to be even more invalid below here) */
-    0x20, 0x20, 0x20, 0x00,  /* array length (in bytes) */
-      0x20, /* array key */
+     * (things start to be invalid below here) */
+    0x10, 0x00, 0x00, 0x00,  /* array length (in bytes), must be a multiple of 8 */
+      0x20, /* array key (this is not currently a valid header field) */
       /* Variant array value: */
       0x00, /* signature length */
       0x00,  /* nul terminator */
       /* (Variant array value payload missing) */
-    /* (message body length missing) */
+      /* alignment padding before the next header array element, as structs must
+       * be 8-aligned: */
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x05,  /* array key (REPLY_SERIAL, required for method return messages) */
+      /* Variant array value: */
+      0x01,  /* signature length */
+      'u',  /* one complete type */
+      0x00,  /* nul terminator */
+      /* (Variant array value payload) */
+      0x00, 0x01, 0x02, 0x03,
+    /* (message body is zero-length) */
   };
   gsize size = sizeof (data);
   GDBusMessage *message = NULL;
@@ -1197,28 +1215,37 @@ test_message_parse_empty_signature_header (void)
 
 /* Test that an invalid header in a D-Bus message (specifically, containing a
  * variant with a type signature containing multiple complete types) is
- * gracefully handled with an error rather than a crash. The set of bytes here
- * come directly from fuzzer output. */
+ * gracefully handled with an error rather than a crash. */
 static void
 test_message_parse_multiple_signature_header (void)
 {
   const guint8 data[] = {
     'l',  /* little-endian byte order */
-    0x20,  /* message type */
-    0x20,  /* message flags */
+    0x02,  /* message type (method return) */
+    0x00,  /* message flags (none) */
     0x01,  /* major protocol version */
-    0x20, 0x20, 0x20, 0x00,  /* body length (invalid) */
+    0x00, 0x00, 0x00, 0x00,  /* body length (in bytes) */
     0x20, 0x20, 0x20, 0x20,  /* message serial */
     /* a{yv} of header fields:
-     * (things start to be even more invalid below here) */
-    0x20, 0x20, 0x20, 0x00,  /* array length (in bytes) */
-      0x20, /* array key */
+     * (things start to be invalid below here) */
+    0x10, 0x00, 0x00, 0x00,  /* array length (in bytes), must be a multiple of 8 */
+      0x20, /* array key (this is not currently a valid header field) */
       /* Variant array value: */
       0x02, /* signature length */
       'b', 'b',  /* two complete types */
       0x00,  /* nul terminator */
       /* (Variant array value payload missing) */
-    /* (message body length missing) */
+      /* alignment padding before the next header array element, as structs must
+       * be 8-aligned: */
+      0x00, 0x00, 0x00,
+      0x05,  /* array key (REPLY_SERIAL, required for method return messages) */
+      /* Variant array value: */
+      0x01,  /* signature length */
+      'u',  /* one complete type */
+      0x00,  /* nul terminator */
+      /* (Variant array value payload) */
+      0x00, 0x01, 0x02, 0x03,
+    /* (message body is zero-length) */
   };
   gsize size = sizeof (data);
   GDBusMessage *message = NULL;
@@ -1238,22 +1265,21 @@ test_message_parse_multiple_signature_header (void)
 /* Test that an invalid header in a D-Bus message (specifically, containing a
  * variant with a valid type signature that is too long to be a valid
  * #GVariantType due to exceeding the array nesting limits) is gracefully
- * handled with an error rather than a crash. The set of bytes here come
- * directly from fuzzer output. */
+ * handled with an error rather than a crash. */
 static void
 test_message_parse_over_long_signature_header (void)
 {
   const guint8 data[] = {
     'l',  /* little-endian byte order */
-    0x20,  /* message type */
-    0x20,  /* message flags */
+    0x02,  /* message type (method return) */
+    0x00,  /* message flags (none) */
     0x01,  /* major protocol version */
-    0x20, 0x20, 0x20, 0x01,  /* body length (invalid) */
+    0x00, 0x00, 0x00, 0x00,  /* body length (in bytes) */
     0x20, 0x20, 0x20, 0x20,  /* message serial */
     /* a{yv} of header fields:
-     * (things start to be even more invalid below here) */
-    0x20, 0x00, 0x00, 0x00,  /* array length (in bytes) */
-      0x08,  /* array key */
+     * (things start to be invalid below here) */
+    0xa0, 0x00, 0x00, 0x00,  /* array length (in bytes), must be a multiple of 8 */
+      0x08,  /* array key (SIGNATURE) */
       /* Variant array value: */
       0x04,  /* signature length */
       'g', 0x00, 0x20, 0x20,  /* one complete type plus some rubbish */
@@ -1275,8 +1301,16 @@ test_message_parse_over_long_signature_header (void)
       'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
       'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
       'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
-      'v'
-    /* (message body length missing) */
+      'v',
+      /* first header length is a multiple of 8 so no padding is needed */
+      0x05,  /* array key (REPLY_SERIAL, required for method return messages) */
+      /* Variant array value: */
+      0x01,  /* signature length */
+      'u',  /* one complete type */
+      0x00,  /* nul terminator */
+      /* (Variant array value payload) */
+      0x00, 0x01, 0x02, 0x03,
+    /* (message body is zero-length) */
   };
   gsize size = sizeof (data);
   GDBusMessage *message = NULL;
@@ -1295,20 +1329,20 @@ test_message_parse_over_long_signature_header (void)
 
 /* Test that an invalid header in a D-Bus message (specifically, containing too
  * many levels of nested variant) is gracefully handled with an error rather
- * than a crash. The set of bytes here come almost directly from fuzzer output. */
+ * than a crash. */
 static void
 test_message_parse_deep_header_nesting (void)
 {
   const guint8 data[] = {
     'l',  /* little-endian byte order */
-    0x20,  /* message type */
-    0x20,  /* message flags */
+    0x02,  /* message type (method return) */
+    0x00,  /* message flags (none) */
     0x01,  /* major protocol version */
-    0x20, 0x20, 0x20, 0x00,  /* body length (invalid) */
+    0x00, 0x00, 0x00, 0x00,  /* body length (in bytes) */
     0x20, 0x20, 0x20, 0x20,  /* message serial */
     /* a{yv} of header fields:
-     * (things start to be even more invalid below here) */
-    0x20, 0x20, 0x20, 0x00,  /* array length (in bytes) */
+     * (things start to be invalid below here) */
+    0xd0, 0x00, 0x00, 0x00,  /* array length (in bytes), must be a multiple of 8 */
       0x20,  /* array key (this is not currently a valid header field) */
       /* Variant array value: */
       0x01,  /* signature length */
@@ -1333,10 +1367,18 @@ test_message_parse_deep_header_nesting (void)
       0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
       0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
       0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
-      0x01, 'v', 0x00, 0x01, 'v', 0x00,
+      0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
       /* Some arbitrary valid content inside the innermost variant: */
       0x01, 'y', 0x00, 0xcc,
-    /* (message body length missing) */
+      /* no padding needed as this header element length is a multiple of 8 */
+      0x05,  /* array key (REPLY_SERIAL, required for method return messages) */
+      /* Variant array value: */
+      0x01,  /* signature length */
+      'u',  /* one complete type */
+      0x00,  /* nul terminator */
+      /* (Variant array value payload) */
+      0x00, 0x01, 0x02, 0x03,
+    /* (message body is zero-length) */
   };
   gsize size = sizeof (data);
   GDBusMessage *message = NULL;
@@ -1362,22 +1404,30 @@ test_message_parse_deep_body_nesting (void)
 {
   const guint8 data[] = {
     'l',  /* little-endian byte order */
-    0x20,  /* message type */
-    0x20,  /* message flags */
+    0x02,  /* message type (method return) */
+    0x00,  /* message flags (none) */
     0x01,  /* major protocol version */
-    0x20, 0x20, 0x20, 0x00,  /* body length (invalid) */
+    0xc4, 0x00, 0x00, 0x00,  /* body length (in bytes) */
     0x20, 0x20, 0x20, 0x20,  /* message serial */
     /* a{yv} of header fields: */
-    0x07, 0x00, 0x00, 0x00,  /* array length (in bytes) */
-      0x08,  /* array key (signature field) */
+    0x10, 0x00, 0x00, 0x00,  /* array length (in bytes), must be a multiple of 8 */
+      0x08,  /* array key (SIGNATURE) */
       /* Variant array value: */
       0x01,  /* signature length */
       'g',  /* one complete type */
       0x00,  /* nul terminator */
       /* (Variant array value payload) */
       0x01, 'v', 0x00,
-    /* End-of-header padding to reach an 8-byte boundary: */
-    0x00,
+      /* alignment padding before the next header array element, as structs must
+       * be 8-aligned: */
+      0x00,
+      0x05,  /* array key (REPLY_SERIAL, required for method return messages) */
+      /* Variant array value: */
+      0x01,  /* signature length */
+      'u',  /* one complete type */
+      0x00,  /* nul terminator */
+      /* (Variant array value payload) */
+      0x00, 0x01, 0x02, 0x03,
     /* Message body: over 64 levels of nested variant, which is not valid: */
     0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
     0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
index e031a0a..b2e478d 100644 (file)
@@ -8,14 +8,13 @@
 #
 # See issue #1580
 
-import io
 import string
 import sys
 
 if len(sys.argv) != 2:
-    raise SystemExit('Usage: %s <output-file>' % sys.argv[0])
+    raise SystemExit("Usage: %s <output-file>" % sys.argv[0])
 
-with open(sys.argv[1], 'w', newline='\n') as f:
+with open(sys.argv[1], "w", newline="\n") as f:
     for count in range(12):
         for c in string.ascii_lowercase:
             f.write("%s\n" % (c * 100))
index 47219f3..dbd8195 100644 (file)
@@ -5,7 +5,7 @@ import sys
 import re
 import os
 
-debug = os.getenv('GIO_GENTYPEFUNCS_DEBUG') is not None
+debug = os.getenv("GIO_GENTYPEFUNCS_DEBUG") is not None
 
 out_file = sys.argv[1]
 in_files = sys.argv[2:]
@@ -13,32 +13,37 @@ in_files = sys.argv[2:]
 funcs = []
 
 
-if debug: print ('Output file: ', out_file)
+if debug:
+    print("Output file: ", out_file)
 
-if debug: print (len(in_files), 'input files')
+if debug:
+    print(len(in_files), "input files")
 
 for filename in in_files:
-  if debug: print ('Input file: ', filename)
-  with open(filename, 'rb') as f:
-    for line in f:
-      line = line.rstrip(b'\n').rstrip(b'\r')
-      # print line
-      match = re.search(b'\bg_[a-zA-Z0-9_]*_get_type\b', line)
-      if match:
-        func = match.group(0)
-        if not func in funcs:
-          funcs.append(func)
-          if debug: print ('Found ', func)
-
-file_output = 'G_GNUC_BEGIN_IGNORE_DEPRECATIONS\n'
+    if debug:
+        print("Input file: ", filename)
+    with open(filename, "rb") as f:
+        for line in f:
+            line = line.rstrip(b"\n").rstrip(b"\r")
+            # print line
+            match = re.search(b"\bg_[a-zA-Z0-9_]*_get_type\b", line)
+            if match:
+                func = match.group(0)
+                if func not in funcs:
+                    funcs.append(func)
+                    if debug:
+                        print("Found ", func)
+
+file_output = "G_GNUC_BEGIN_IGNORE_DEPRECATIONS\n"
 
 funcs = sorted(funcs)
 
 for f in funcs:
-  if f not in ['g_io_extension_get_type', 'g_settings_backend_get_type']:
-    file_output += '*tp++ = {0} ();\n'.format(f)
+    if f not in ["g_io_extension_get_type", "g_settings_backend_get_type"]:
+        file_output += "*tp++ = {0} ();\n".format(f)
 
-if debug: print (len(funcs), 'functions')
+if debug:
+    print(len(funcs), "functions")
 
 ofile = open(out_file, "w")
 ofile.write(file_output)
index baadca8..179d0fd 100644 (file)
@@ -39,7 +39,7 @@ static void
 teardown (Fixture       *fixture,
           gconstpointer  user_data)
 {
-  g_assert_cmpint (g_rmdir (fixture->tmp_dir), ==, 0);
+  g_assert_no_errno (g_rmdir (fixture->tmp_dir));
   g_clear_pointer (&fixture->tmp_dir, g_free);
 }
 
@@ -1060,7 +1060,7 @@ test_object_set_property (GObject      *object,
 static GType
 test_enum_get_type (void)
 {
-  static volatile gsize define_type_id = 0;
+  static gsize define_type_id = 0;
 
   if (g_once_init_enter (&define_type_id))
     {
@@ -1082,7 +1082,7 @@ test_enum_get_type (void)
 static GType
 test_flags_get_type (void)
 {
-  static volatile gsize define_type_id = 0;
+  static gsize define_type_id = 0;
 
   if (g_once_init_enter (&define_type_id))
     {
@@ -1844,7 +1844,7 @@ test_keyfile (Fixture       *fixture,
       g_signal_connect (settings, "writable-changed::greeting",
                         G_CALLBACK (key_changed_cb), &called);
 
-      g_chmod (keyfile_path, 0500);
+      g_assert_no_errno (g_chmod (keyfile_path, 0500));
       while (!called)
         g_main_context_iteration (NULL, FALSE);
       g_signal_handlers_disconnect_by_func (settings, key_changed_cb, &called);
@@ -1859,9 +1859,9 @@ test_keyfile (Fixture       *fixture,
   g_object_unref (settings);
 
   /* Clean up the temporary directory. */
-  g_chmod (keyfile_path, 0777);
-  g_assert_cmpint (g_remove (store_path), ==, 0);
-  g_rmdir (keyfile_path);
+  g_assert_no_errno (g_chmod (keyfile_path, 0777));
+  g_assert_no_errno (g_remove (store_path));
+  g_assert_no_errno (g_rmdir (keyfile_path));
   g_free (store_path);
   g_free (keyfile_path);
 }
index 34410f4..803ed90 100644 (file)
@@ -79,23 +79,26 @@ on_connected_cancelled (GObject      *source_object,
   g_main_loop_quit (user_data);
 }
 
-static int
-on_timer (GCancellable *cancel)
+typedef struct
 {
-  g_cancellable_cancel (cancel);
-  return G_SOURCE_REMOVE;
-}
+  GCancellable *cancellable;
+  gboolean completed;
+} EventCallbackData;
 
 static void
 on_event (GSocketClient      *client,
           GSocketClientEvent  event,
           GSocketConnectable *connectable,
           GIOStream          *connection,
-          gboolean           *got_completed_event)
+          EventCallbackData  *data)
 {
-  if (event == G_SOCKET_CLIENT_COMPLETE)
+  if (data->cancellable && event == G_SOCKET_CLIENT_CONNECTED)
+    {
+      g_cancellable_cancel (data->cancellable);
+    }
+  else if (event == G_SOCKET_CLIENT_COMPLETE)
     {
-      *got_completed_event = TRUE;
+      data->completed = TRUE;
       g_assert_null (connection);
     }
 }
@@ -108,8 +111,7 @@ test_happy_eyeballs_cancel_delayed (void)
   GError *error = NULL;
   guint16 port;
   GMainLoop *loop;
-  GCancellable *cancel;
-  gboolean got_completed_event = FALSE;
+  EventCallbackData data = { NULL, FALSE };
 
   /* This just tests that cancellation works as expected, still emits the completed signal,
    * and never returns a connection */
@@ -122,17 +124,16 @@ test_happy_eyeballs_cancel_delayed (void)
   g_socket_service_start (service);
 
   client = g_socket_client_new ();
-  cancel = g_cancellable_new ();
-  g_socket_client_connect_to_host_async (client, "localhost", port, cancel, on_connected_cancelled, loop);
-  g_timeout_add (1, (GSourceFunc) on_timer, cancel);
-  g_signal_connect (client, "event", G_CALLBACK (on_event), &got_completed_event);
+  data.cancellable = g_cancellable_new ();
+  g_socket_client_connect_to_host_async (client, "localhost", port, data.cancellable, on_connected_cancelled, loop);
+  g_signal_connect (client, "event", G_CALLBACK (on_event), &data);
   g_main_loop_run (loop);
 
-  g_assert_true (got_completed_event);
+  g_assert_true (data.completed);
   g_main_loop_unref (loop);
   g_object_unref (service);
   g_object_unref (client);
-  g_object_unref (cancel);
+  g_object_unref (data.cancellable);
 }
 
 static void
@@ -144,7 +145,7 @@ test_happy_eyeballs_cancel_instant (void)
   guint16 port;
   GMainLoop *loop;
   GCancellable *cancel;
-  gboolean got_completed_event = FALSE;
+  EventCallbackData data = { NULL, FALSE };
 
   /* This tests the same things as above, test_happy_eyeballs_cancel_delayed(), but
    * with different timing since it sends an already cancelled cancellable */
@@ -160,10 +161,10 @@ test_happy_eyeballs_cancel_instant (void)
   cancel = g_cancellable_new ();
   g_cancellable_cancel (cancel);
   g_socket_client_connect_to_host_async (client, "localhost", port, cancel, on_connected_cancelled, loop);
-  g_signal_connect (client, "event", G_CALLBACK (on_event), &got_completed_event);
+  g_signal_connect (client, "event", G_CALLBACK (on_event), &data);
   g_main_loop_run (loop);
 
-  g_assert_true (got_completed_event);
+  g_assert_true (data.completed);
   g_main_loop_unref (loop);
   g_object_unref (service);
   g_object_unref (client);
index 2ede210..316e23c 100644 (file)
@@ -149,13 +149,13 @@ check_cap_dac_override (const char *tmpdir)
   dac_denies_write = g_build_filename (tmpdir, "dac-denies-write", NULL);
   inside = g_build_filename (dac_denies_write, "inside", NULL);
 
-  g_assert_cmpint (mkdir (dac_denies_write, S_IRWXU) == 0 ? 0 : errno, ==, 0);
-  g_assert_cmpint (chmod (dac_denies_write, 0) == 0 ? 0 : errno, ==, 0);
+  g_assert_no_errno (mkdir (dac_denies_write, S_IRWXU));
+  g_assert_no_errno (chmod (dac_denies_write, 0));
 
   if (mkdir (inside, S_IRWXU) == 0)
     {
       g_test_message ("Looks like we have CAP_DAC_OVERRIDE or equivalent");
-      g_assert_cmpint (rmdir (inside) == 0 ? 0 : errno, ==, 0);
+      g_assert_no_errno (rmdir (inside));
       have_cap = TRUE;
     }
   else
@@ -167,8 +167,8 @@ check_cap_dac_override (const char *tmpdir)
       have_cap = FALSE;
     }
 
-  g_assert_cmpint (chmod (dac_denies_write, S_IRWXU) == 0 ? 0 : errno, ==, 0);
-  g_assert_cmpint (rmdir (dac_denies_write) == 0 ? 0 : errno, ==, 0);
+  g_assert_no_errno (chmod (dac_denies_write, S_IRWXU));
+  g_assert_no_errno (rmdir (dac_denies_write));
   g_free (dac_denies_write);
   g_free (inside);
   return have_cap;
index 50a2062..e64355a 100644 (file)
@@ -37,7 +37,7 @@ static const gchar *info = NULL;
 static GCancellable *cancellable = NULL;
 static gint return_value = 0;
 
-static void G_GNUC_NORETURN
+static G_NORETURN void
 usage (void)
 {
   fprintf (stderr, "Usage: proxy [-s] (uri|host:port|ip:port|path|srv/protocol/domain)\n");
index c57b818..3e6d896 100644 (file)
@@ -40,7 +40,7 @@ static gboolean synchronous = FALSE;
 static guint connectable_count = 0;
 static GResolverRecordType record_type = 0;
 
-static void G_GNUC_NORETURN
+static G_NORETURN void
 usage (void)
 {
        fprintf (stderr, "Usage: resolver [-s] [hostname | IP | service/protocol/domain ] ...\n");
index 0749b7d..325775f 100644 (file)
@@ -69,6 +69,15 @@ test_resource (GResource *resource)
   g_assert_cmpuint (flags, ==, G_RESOURCE_FLAGS_COMPRESSED);
 
   found = g_resource_get_info (resource,
+                               "/empty.txt",
+                               G_RESOURCE_LOOKUP_FLAGS_NONE,
+                               &size, &flags, &error);
+  g_assert_true (found);
+  g_assert_no_error (error);
+  g_assert_cmpint (size, ==, 0);
+  g_assert_cmpuint (flags, ==, G_RESOURCE_FLAGS_COMPRESSED);
+
+  found = g_resource_get_info (resource,
                               "/a_prefix/test2.txt",
                               G_RESOURCE_LOOKUP_FLAGS_NONE,
                               &size, &flags, &error);
@@ -105,6 +114,14 @@ test_resource (GResource *resource)
   g_assert_no_error (error);
   g_bytes_unref (data);
 
+  data = g_resource_lookup_data (resource,
+                                 "/empty.txt",
+                                 G_RESOURCE_LOOKUP_FLAGS_NONE,
+                                 &error);
+  g_assert_cmpuint (g_bytes_get_size (data), ==, 0);
+  g_assert_no_error (error);
+  g_bytes_unref (data);
+
   for (i = 0; i < G_N_ELEMENTS (not_found_paths); i++)
     {
       in = g_resource_open_stream (resource,
@@ -136,6 +153,24 @@ test_resource (GResource *resource)
   g_assert_no_error (error);
   g_clear_object (&in);
 
+  in = g_resource_open_stream (resource,
+                               "/empty.txt",
+                               G_RESOURCE_LOOKUP_FLAGS_NONE,
+                               &error);
+  g_assert_no_error (error);
+  g_assert_nonnull (in);
+
+  success = g_input_stream_read_all (in, buffer, sizeof (buffer) - 1,
+                                     &size,
+                                     NULL, &error);
+  g_assert_no_error (error);
+  g_assert_true (success);
+  g_assert_cmpint (size, ==, 0);
+
+  g_input_stream_close (in, NULL, &error);
+  g_assert_no_error (error);
+  g_clear_object (&in);
+
   data = g_resource_lookup_data (resource,
                                 "/a_prefix/test2.txt",
                                 G_RESOURCE_LOOKUP_FLAGS_NONE,
@@ -398,6 +433,14 @@ test_resource_registered (void)
   g_assert_cmpint (size, ==, 6);
   g_assert (flags == (G_RESOURCE_FLAGS_COMPRESSED));
 
+  found = g_resources_get_info ("/empty.txt",
+                                G_RESOURCE_LOOKUP_FLAGS_NONE,
+                                &size, &flags, &error);
+  g_assert_no_error (error);
+  g_assert_true (found);
+  g_assert_cmpint (size, ==, 0);
+  g_assert (flags == (G_RESOURCE_FLAGS_COMPRESSED));
+
   found = g_resources_get_info ("/a_prefix/test2.txt",
                                G_RESOURCE_LOOKUP_FLAGS_NONE,
                                &size, &flags, &error);
@@ -440,6 +483,30 @@ test_resource_registered (void)
   g_assert_no_error (error);
   g_clear_object (&in);
 
+  data = g_resources_lookup_data ("/empty.txt",
+                                  G_RESOURCE_LOOKUP_FLAGS_NONE,
+                                  &error);
+  g_assert_no_error (error);
+  g_assert_cmpuint (g_bytes_get_size (data), ==, 0);
+  g_bytes_unref (data);
+
+  in = g_resources_open_stream ("/empty.txt",
+                                G_RESOURCE_LOOKUP_FLAGS_NONE,
+                                &error);
+  g_assert_no_error (error);
+  g_assert_nonnull (in);
+
+  success = g_input_stream_read_all (in, buffer, sizeof (buffer) - 1,
+                                     &size,
+                                     NULL, &error);
+  g_assert_no_error (error);
+  g_assert_true (success);
+  g_assert_cmpint (size, ==, 0);
+
+  g_input_stream_close (in, NULL, &error);
+  g_assert_no_error (error);
+  g_clear_object (&in);
+
   data = g_resources_lookup_data ("/a_prefix/test2.txt",
                                  G_RESOURCE_LOOKUP_FLAGS_NONE,
                                  &error);
index f1dd783..8487a70 100644 (file)
@@ -99,7 +99,7 @@ test_start_stop (void)
 
 GMutex mutex_712570;
 GCond cond_712570;
-volatile gboolean finalized;
+gboolean finalized;  /* (atomic) */
 
 GType test_threaded_socket_service_get_type (void);
 typedef GThreadedSocketService TestThreadedSocketService;
@@ -120,7 +120,7 @@ test_threaded_socket_service_finalize (GObject *object)
   /* Signal the main thread that finalization completed successfully
    * rather than hanging.
    */
-  finalized = TRUE;
+  g_atomic_int_set (&finalized, TRUE);
   g_cond_signal (&cond_712570);
   g_mutex_unlock (&mutex_712570);
 }
@@ -235,7 +235,7 @@ test_threaded_712570 (void)
    */
   g_object_unref (service);
 
-  while (!finalized)
+  while (!g_atomic_int_get (&finalized))
     g_cond_wait (&cond_712570, &mutex_712570);
   g_mutex_unlock (&mutex_712570);
 }
index e0a064a..a8bda5b 100755 (executable)
@@ -23,29 +23,33 @@ import sys
 import tempfile
 import subprocess
 
-if not 'GLIB_TEST_COMPILATION' in os.environ:
-  print('''Test disabled because GLIB_TEST_COMPILATION is not set in the env.
+if "GLIB_TEST_COMPILATION" not in os.environ:
+    print(
+        """Test disabled because GLIB_TEST_COMPILATION is not set in the env.
 If you wish to run this test, set GLIB_TEST_COMPILATION=1 in the env,
 and make sure you have glib build dependencies installed, including
-meson.''')
-  sys.exit(77)
+meson."""
+    )
+    sys.exit(77)
 
 if len(sys.argv) != 2:
-  print('Usage: {} <gio-2.0.pc dir>'.format(os.path.basename(sys.argv[0])))
-  sys.exit(1)
+    print("Usage: {} <gio-2.0.pc dir>".format(os.path.basename(sys.argv[0])))
+    sys.exit(1)
 
 test_dir = os.path.dirname(sys.argv[0])
 
 with tempfile.TemporaryDirectory() as builddir:
-  env = os.environ.copy()
-  env['PKG_CONFIG_PATH'] = sys.argv[1]
-  sourcedir = os.path.join(test_dir, 'static-link')
+    env = os.environ.copy()
+    env["PKG_CONFIG_PATH"] = sys.argv[1]
+    sourcedir = os.path.join(test_dir, "static-link")
 
-  # Ensure we can static link and run a test app
-  subprocess.check_call(['meson', sourcedir, builddir], env=env)
-  subprocess.check_call(['ninja', '-C', builddir, 'test'], env=env)
-  # FIXME: This probably only works on Linux
-  out = subprocess.check_output(['ldd', os.path.join(builddir, 'test-static-link')], env=env).decode()
-  if 'libgio' in out:
-    print('test-static-link is dynamically linked on libgio')
-    exit(1)
+    # Ensure we can static link and run a test app
+    subprocess.check_call(["meson", sourcedir, builddir], env=env)
+    subprocess.check_call(["ninja", "-C", builddir, "test"], env=env)
+    # FIXME: This probably only works on Linux
+    out = subprocess.check_output(
+        ["ldd", os.path.join(builddir, "test-static-link")], env=env
+    ).decode()
+    if "libgio" in out:
+        print("test-static-link is dynamically linked on libgio")
+        exit(1)
index 2614961..9ce3b43 100644 (file)
@@ -30,147 +30,157 @@ import sys
 import base64
 from io import StringIO
 
+
 # Log modes
-class LogMode(object) :
-  LogToError, LogToDiagnostics, LogToYAML, LogToAttachment = range(4)
+class LogMode(object):
+    LogToError, LogToDiagnostics, LogToYAML, LogToAttachment = range(4)
 
 
 class TAPTestResult(unittest.TestResult):
-  def __init__(self, output_stream, error_stream, message_log, test_output_log):
-    super(TAPTestResult, self).__init__(self, output_stream)
-    self.output_stream = output_stream
-    self.error_stream = error_stream
-    self.orig_stdout = None
-    self.orig_stderr = None
-    self.message = None
-    self.test_output = None
-    self.message_log = message_log
-    self.test_output_log = test_output_log
-    self.output_stream.write("TAP version 13\n")
-    self._set_streams()
-
-  def printErrors(self):
-    self.print_raw("1..%d\n" % self.testsRun)
-    self._reset_streams()
-
-  def _set_streams(self):
-    self.orig_stdout = sys.stdout
-    self.orig_stderr = sys.stderr
-    if self.message_log == LogMode.LogToError:
-      self.message = self.error_stream
-    else:
-      self.message = StringIO()
-    if self.test_output_log == LogMode.LogToError:
-      self.test_output = self.error_stream
-    else:
-      self.test_output = StringIO()
-
-    if self.message_log == self.test_output_log:
-      self.test_output = self.message
-    sys.stdout = sys.stderr = self.test_output
-
-  def _reset_streams(self):
-    sys.stdout = self.orig_stdout
-    sys.stderr = self.orig_stderr
-
-
-  def print_raw(self, text):
-    self.output_stream.write(text)
-    self.output_stream.flush()
-
-  def print_result(self, result, test, directive = None):
-    self.output_stream.write("%s %d %s" % (result, self.testsRun, test.id()))
-    if directive:
-      self.output_stream.write(" # " + directive)
-    self.output_stream.write("\n")
-    self.output_stream.flush()
-
-  def ok(self, test, directive = None):
-    self.print_result("ok", test, directive)
-
-  def not_ok(self, test):
-    self.print_result("not ok", test)
-
-  def startTest(self, test):
-    super(TAPTestResult, self).startTest(test)
-
-  def stopTest(self, test):
-    super(TAPTestResult, self).stopTest(test)
-    if self.message_log == self.test_output_log:
-      logs = [(self.message_log, self.message, "output")]
-    else:
-      logs = [
-          (self.test_output_log, self.test_output, "test_output"),
-          (self.message_log, self.message, "message")
-      ]
-    for log_mode, log, log_name in logs:
-      if log_mode != LogMode.LogToError:
-        output = log.getvalue()
-        if len(output):
-          if log_mode == LogMode.LogToYAML:
-            self.print_raw("  ---\n")
-            self.print_raw("    " + log_name + ": |\n")
-            self.print_raw("      " + output.rstrip().replace("\n", "\n      ") + "\n")
-            self.print_raw("  ...\n")
-          elif log_mode == LogMode.LogToAttachment:
-            self.print_raw("  ---\n")
-            self.print_raw("    " + log_name + ":\n")
-            self.print_raw("      File-Name: " + log_name + ".txt\n")
-            self.print_raw("      File-Type: text/plain\n")
-            self.print_raw("      File-Content: " + base64.b64encode(output) + "\n")
-            self.print_raw("  ...\n")
-          else:
-            self.print_raw("# " + output.rstrip().replace("\n", "\n# ") + "\n")
-        # Truncate doesn't change the current stream position.
-        # Seek to the beginning to avoid extensions on subsequent writes.
-        log.seek(0)
-        log.truncate(0)
-
-  def addSuccess(self, test):
-    super(TAPTestResult, self).addSuccess(test)
-    self.ok(test)
-
-  def addError(self, test, err):
-    super(TAPTestResult, self).addError(test, err)
-    self.message.write(self.errors[-1][1] + "\n")
-    self.not_ok(test)
-
-  def addFailure(self, test, err):
-    super(TAPTestResult, self).addFailure(test, err)
-    self.message.write(self.failures[-1][1] + "\n")
-    self.not_ok(test)
-
-  def addSkip(self, test, reason):
-    super(TAPTestResult, self).addSkip(test, reason)
-    self.ok(test, "SKIP " + reason)
-
-  def addExpectedFailure(self, test, err):
-    super(TAPTestResult, self).addExpectedFailure(test, err)
-    self.ok(test)
-
-  def addUnexpectedSuccess(self, test):
-    super(TAPTestResult, self).addUnexpectedSuccess(test)
-    self.message.write("Unexpected success" + "\n")
-    self.not_ok(test)
+    def __init__(self, output_stream, error_stream, message_log, test_output_log):
+        super(TAPTestResult, self).__init__(self, output_stream)
+        self.output_stream = output_stream
+        self.error_stream = error_stream
+        self.orig_stdout = None
+        self.orig_stderr = None
+        self.message = None
+        self.test_output = None
+        self.message_log = message_log
+        self.test_output_log = test_output_log
+        self.output_stream.write("TAP version 13\n")
+        self._set_streams()
+
+    def printErrors(self):
+        self.print_raw("1..%d\n" % self.testsRun)
+        self._reset_streams()
+
+    def _set_streams(self):
+        self.orig_stdout = sys.stdout
+        self.orig_stderr = sys.stderr
+        if self.message_log == LogMode.LogToError:
+            self.message = self.error_stream
+        else:
+            self.message = StringIO()
+        if self.test_output_log == LogMode.LogToError:
+            self.test_output = self.error_stream
+        else:
+            self.test_output = StringIO()
+
+        if self.message_log == self.test_output_log:
+            self.test_output = self.message
+        sys.stdout = sys.stderr = self.test_output
+
+    def _reset_streams(self):
+        sys.stdout = self.orig_stdout
+        sys.stderr = self.orig_stderr
+
+    def print_raw(self, text):
+        self.output_stream.write(text)
+        self.output_stream.flush()
+
+    def print_result(self, result, test, directive=None):
+        self.output_stream.write("%s %d %s" % (result, self.testsRun, test.id()))
+        if directive:
+            self.output_stream.write(" # " + directive)
+        self.output_stream.write("\n")
+        self.output_stream.flush()
+
+    def ok(self, test, directive=None):
+        self.print_result("ok", test, directive)
+
+    def not_ok(self, test):
+        self.print_result("not ok", test)
+
+    def startTest(self, test):
+        super(TAPTestResult, self).startTest(test)
+
+    def stopTest(self, test):
+        super(TAPTestResult, self).stopTest(test)
+        if self.message_log == self.test_output_log:
+            logs = [(self.message_log, self.message, "output")]
+        else:
+            logs = [
+                (self.test_output_log, self.test_output, "test_output"),
+                (self.message_log, self.message, "message"),
+            ]
+        for log_mode, log, log_name in logs:
+            if log_mode != LogMode.LogToError:
+                output = log.getvalue()
+                if len(output):
+                    if log_mode == LogMode.LogToYAML:
+                        self.print_raw("  ---\n")
+                        self.print_raw("    " + log_name + ": |\n")
+                        self.print_raw(
+                            "      " + output.rstrip().replace("\n", "\n      ") + "\n"
+                        )
+                        self.print_raw("  ...\n")
+                    elif log_mode == LogMode.LogToAttachment:
+                        self.print_raw("  ---\n")
+                        self.print_raw("    " + log_name + ":\n")
+                        self.print_raw("      File-Name: " + log_name + ".txt\n")
+                        self.print_raw("      File-Type: text/plain\n")
+                        self.print_raw(
+                            "      File-Content: " + base64.b64encode(output) + "\n"
+                        )
+                        self.print_raw("  ...\n")
+                    else:
+                        self.print_raw(
+                            "# " + output.rstrip().replace("\n", "\n# ") + "\n"
+                        )
+                # Truncate doesn't change the current stream position.
+                # Seek to the beginning to avoid extensions on subsequent writes.
+                log.seek(0)
+                log.truncate(0)
+
+    def addSuccess(self, test):
+        super(TAPTestResult, self).addSuccess(test)
+        self.ok(test)
+
+    def addError(self, test, err):
+        super(TAPTestResult, self).addError(test, err)
+        self.message.write(self.errors[-1][1] + "\n")
+        self.not_ok(test)
+
+    def addFailure(self, test, err):
+        super(TAPTestResult, self).addFailure(test, err)
+        self.message.write(self.failures[-1][1] + "\n")
+        self.not_ok(test)
+
+    def addSkip(self, test, reason):
+        super(TAPTestResult, self).addSkip(test, reason)
+        self.ok(test, "SKIP " + reason)
+
+    def addExpectedFailure(self, test, err):
+        super(TAPTestResult, self).addExpectedFailure(test, err)
+        self.ok(test)
+
+    def addUnexpectedSuccess(self, test):
+        super(TAPTestResult, self).addUnexpectedSuccess(test)
+        self.message.write("Unexpected success" + "\n")
+        self.not_ok(test)
 
 
 class TAPTestRunner(object):
-  def __init__(self,
-      message_log = LogMode.LogToYAML,
-      test_output_log = LogMode.LogToDiagnostics,
-      output_stream = sys.stdout, error_stream = sys.stderr):
-    self.output_stream = output_stream
-    self.error_stream = error_stream
-    self.message_log = message_log
-    self.test_output_log = test_output_log
-
-  def run(self, test):
-    result = TAPTestResult(
-        self.output_stream,
-        self.error_stream,
-        self.message_log,
-        self.test_output_log)
-    test(result)
-    result.printErrors()
-
-    return result
+    def __init__(
+        self,
+        message_log=LogMode.LogToYAML,
+        test_output_log=LogMode.LogToDiagnostics,
+        output_stream=sys.stdout,
+        error_stream=sys.stderr,
+    ):
+        self.output_stream = output_stream
+        self.error_stream = error_stream
+        self.message_log = message_log
+        self.test_output_log = test_output_log
+
+    def run(self, test):
+        result = TAPTestResult(
+            self.output_stream,
+            self.error_stream,
+            self.message_log,
+            self.test_output_log,
+        )
+        test(result)
+        result.printErrors()
+
+        return result
index cca05ce..7ce8438 100644 (file)
@@ -957,7 +957,7 @@ task_weak_notify (gpointer  user_data,
   gboolean *weak_notify_ran = user_data;
 
   g_mutex_lock (&run_in_thread_mutex);
-  *weak_notify_ran = TRUE;
+  g_atomic_int_set (weak_notify_ran, TRUE);
   g_cond_signal (&run_in_thread_cond);
   g_mutex_unlock (&run_in_thread_mutex);
 }
@@ -1007,7 +1007,7 @@ run_in_thread_thread (GTask        *task,
   g_assert (g_thread_self () != main_thread);
 
   g_mutex_lock (&run_in_thread_mutex);
-  *thread_ran = TRUE;
+  g_atomic_int_set (thread_ran, TRUE);
   g_cond_signal (&run_in_thread_cond);
   g_mutex_unlock (&run_in_thread_mutex);
 
@@ -1018,8 +1018,8 @@ static void
 test_run_in_thread (void)
 {
   GTask *task;
-  volatile gboolean thread_ran = FALSE;
-  volatile gboolean weak_notify_ran = FALSE;
+  gboolean thread_ran = FALSE;  /* (atomic) */
+  gboolean weak_notify_ran = FALSE;  /* (atomic) */
   gboolean notification_emitted = FALSE;
   gboolean done = FALSE;
 
@@ -1033,12 +1033,12 @@ test_run_in_thread (void)
   g_task_run_in_thread (task, run_in_thread_thread);
 
   g_mutex_lock (&run_in_thread_mutex);
-  while (!thread_ran)
+  while (!g_atomic_int_get (&thread_ran))
     g_cond_wait (&run_in_thread_cond, &run_in_thread_mutex);
   g_mutex_unlock (&run_in_thread_mutex);
 
   g_assert (done == FALSE);
-  g_assert (weak_notify_ran == FALSE);
+  g_assert_false (g_atomic_int_get (&weak_notify_ran));
 
   g_main_loop_run (loop);
 
@@ -1050,7 +1050,7 @@ test_run_in_thread (void)
   g_object_unref (task);
 
   g_mutex_lock (&run_in_thread_mutex);
-  while (!weak_notify_ran)
+  while (!g_atomic_int_get (&weak_notify_ran))
     g_cond_wait (&run_in_thread_cond, &run_in_thread_mutex);
   g_mutex_unlock (&run_in_thread_mutex);
 }
@@ -1081,7 +1081,7 @@ run_in_thread_sync_thread (GTask        *task,
 
   g_assert (g_thread_self () != main_thread);
 
-  *thread_ran = TRUE;
+  g_atomic_int_set (thread_ran, TRUE);
   g_task_return_int (task, magic);
 }
 
@@ -1102,7 +1102,7 @@ test_run_in_thread_sync (void)
   g_task_set_task_data (task, &thread_ran, NULL);
   g_task_run_in_thread_sync (task, run_in_thread_sync_thread);
 
-  g_assert (thread_ran == TRUE);
+  g_assert_true (g_atomic_int_get (&thread_ran));
   g_assert (task != NULL);
   g_assert (!g_task_had_error (task));
   g_assert_true (g_task_get_completed (task));
@@ -1487,8 +1487,8 @@ test_return_on_cancel (void)
 {
   GTask *task;
   GCancellable *cancellable;
-  volatile ThreadState thread_state;
-  volatile gboolean weak_notify_ran = FALSE;
+  ThreadState thread_state;  /* (atomic) */
+  gboolean weak_notify_ran = FALSE;  /* (atomic) */
   gboolean callback_ran;
   gboolean notification_emitted = FALSE;
 
@@ -1498,7 +1498,7 @@ test_return_on_cancel (void)
    * early.
    */
   callback_ran = FALSE;
-  thread_state = THREAD_STARTING;
+  g_atomic_int_set (&thread_state, THREAD_STARTING);
   task = g_task_new (NULL, cancellable, return_on_cancel_callback, &callback_ran);
   g_signal_connect (task, "notify::completed",
                     (GCallback) completed_cb, &notification_emitted);
@@ -1509,18 +1509,18 @@ test_return_on_cancel (void)
   g_task_run_in_thread (task, return_on_cancel_thread);
   g_object_unref (task);
 
-  while (thread_state == THREAD_STARTING)
+  while (g_atomic_int_get (&thread_state) == THREAD_STARTING)
     g_cond_wait (&roc_init_cond, &roc_init_mutex);
   g_mutex_unlock (&roc_init_mutex);
 
-  g_assert (thread_state == THREAD_RUNNING);
+  g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING);
   g_assert (callback_ran == FALSE);
 
   g_cancellable_cancel (cancellable);
   g_mutex_unlock (&roc_finish_mutex);
   g_main_loop_run (loop);
 
-  g_assert (thread_state == THREAD_COMPLETED);
+  g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_COMPLETED);
   g_assert (callback_ran == TRUE);
   g_assert_true (notification_emitted);
 
@@ -1529,7 +1529,7 @@ test_return_on_cancel (void)
   /* If return-on-cancel is TRUE, it does return early */
   callback_ran = FALSE;
   notification_emitted = FALSE;
-  thread_state = THREAD_STARTING;
+  g_atomic_int_set (&thread_state, THREAD_STARTING);
   task = g_task_new (NULL, cancellable, return_on_cancel_callback, &callback_ran);
   g_object_weak_ref (G_OBJECT (task), task_weak_notify, (gpointer)&weak_notify_ran);
   g_signal_connect (task, "notify::completed",
@@ -1542,27 +1542,27 @@ test_return_on_cancel (void)
   g_task_run_in_thread (task, return_on_cancel_thread);
   g_object_unref (task);
 
-  while (thread_state == THREAD_STARTING)
+  while (g_atomic_int_get (&thread_state) == THREAD_STARTING)
     g_cond_wait (&roc_init_cond, &roc_init_mutex);
   g_mutex_unlock (&roc_init_mutex);
 
-  g_assert (thread_state == THREAD_RUNNING);
+  g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING);
   g_assert (callback_ran == FALSE);
 
   g_cancellable_cancel (cancellable);
   g_main_loop_run (loop);
-  g_assert (thread_state == THREAD_RUNNING);
+  g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING);
   g_assert (callback_ran == TRUE);
 
-  g_assert (weak_notify_ran == FALSE);
+  g_assert_false (g_atomic_int_get (&weak_notify_ran));
 
-  while (thread_state == THREAD_RUNNING)
+  while (g_atomic_int_get (&thread_state) == THREAD_RUNNING)
     g_cond_wait (&roc_finish_cond, &roc_finish_mutex);
   g_mutex_unlock (&roc_finish_mutex);
 
-  g_assert (thread_state == THREAD_CANCELLED);
+  g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_CANCELLED);
   g_mutex_lock (&run_in_thread_mutex);
-  while (!weak_notify_ran)
+  while (!g_atomic_int_get (&weak_notify_ran))
     g_cond_wait (&run_in_thread_cond, &run_in_thread_mutex);
   g_mutex_unlock (&run_in_thread_mutex);
 
@@ -1574,7 +1574,7 @@ test_return_on_cancel (void)
    */
   callback_ran = FALSE;
   notification_emitted = FALSE;
-  thread_state = THREAD_STARTING;
+  g_atomic_int_set (&thread_state, THREAD_STARTING);
   task = g_task_new (NULL, cancellable, return_on_cancel_callback, &callback_ran);
   g_signal_connect (task, "notify::completed",
                     (GCallback) completed_cb, &notification_emitted);
@@ -1591,17 +1591,17 @@ test_return_on_cancel (void)
   g_main_loop_run (loop);
   g_assert (callback_ran == TRUE);
 
-  while (thread_state == THREAD_STARTING)
+  while (g_atomic_int_get (&thread_state) == THREAD_STARTING)
     g_cond_wait (&roc_init_cond, &roc_init_mutex);
   g_mutex_unlock (&roc_init_mutex);
 
-  g_assert (thread_state == THREAD_RUNNING);
+  g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING);
 
-  while (thread_state == THREAD_RUNNING)
+  while (g_atomic_int_get (&thread_state) == THREAD_RUNNING)
     g_cond_wait (&roc_finish_cond, &roc_finish_mutex);
   g_mutex_unlock (&roc_finish_mutex);
 
-  g_assert (thread_state == THREAD_CANCELLED);
+  g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_CANCELLED);
   g_assert_true (notification_emitted);
 
   g_object_unref (cancellable);
@@ -1621,7 +1621,7 @@ test_return_on_cancel_sync (void)
 {
   GTask *task;
   GCancellable *cancellable;
-  volatile ThreadState thread_state;
+  ThreadState thread_state;  /* (atomic) */
   GThread *runner_thread;
   gssize ret;
   GError *error = NULL;
@@ -1630,7 +1630,7 @@ test_return_on_cancel_sync (void)
 
   /* If return-on-cancel is FALSE, the task does not return early.
    */
-  thread_state = THREAD_STARTING;
+  g_atomic_int_set (&thread_state, THREAD_STARTING);
   task = g_task_new (NULL, cancellable, run_in_thread_sync_callback, NULL);
 
   g_task_set_task_data (task, (gpointer)&thread_state, NULL);
@@ -1639,16 +1639,16 @@ test_return_on_cancel_sync (void)
   runner_thread = g_thread_new ("return-on-cancel-sync runner thread",
                                 cancel_sync_runner_thread, task);
 
-  while (thread_state == THREAD_STARTING)
+  while (g_atomic_int_get (&thread_state) == THREAD_STARTING)
     g_cond_wait (&roc_init_cond, &roc_init_mutex);
   g_mutex_unlock (&roc_init_mutex);
 
-  g_assert (thread_state == THREAD_RUNNING);
+  g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING);
 
   g_cancellable_cancel (cancellable);
   g_mutex_unlock (&roc_finish_mutex);
   g_thread_join (runner_thread);
-  g_assert (thread_state == THREAD_COMPLETED);
+  g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_COMPLETED);
 
   ret = g_task_propagate_int (task, &error);
   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
@@ -1660,7 +1660,7 @@ test_return_on_cancel_sync (void)
   g_cancellable_reset (cancellable);
 
   /* If return-on-cancel is TRUE, it does return early */
-  thread_state = THREAD_STARTING;
+  g_atomic_int_set (&thread_state, THREAD_STARTING);
   task = g_task_new (NULL, cancellable, run_in_thread_sync_callback, NULL);
   g_task_set_return_on_cancel (task, TRUE);
 
@@ -1670,15 +1670,15 @@ test_return_on_cancel_sync (void)
   runner_thread = g_thread_new ("return-on-cancel-sync runner thread",
                                 cancel_sync_runner_thread, task);
 
-  while (thread_state == THREAD_STARTING)
+  while (g_atomic_int_get (&thread_state) == THREAD_STARTING)
     g_cond_wait (&roc_init_cond, &roc_init_mutex);
   g_mutex_unlock (&roc_init_mutex);
 
-  g_assert (thread_state == THREAD_RUNNING);
+  g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING);
 
   g_cancellable_cancel (cancellable);
   g_thread_join (runner_thread);
-  g_assert (thread_state == THREAD_RUNNING);
+  g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING);
 
   ret = g_task_propagate_int (task, &error);
   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
@@ -1687,18 +1687,18 @@ test_return_on_cancel_sync (void)
 
   g_object_unref (task);
 
-  while (thread_state == THREAD_RUNNING)
+  while (g_atomic_int_get (&thread_state) == THREAD_RUNNING)
     g_cond_wait (&roc_finish_cond, &roc_finish_mutex);
   g_mutex_unlock (&roc_finish_mutex);
 
-  g_assert (thread_state == THREAD_CANCELLED);
+  g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_CANCELLED);
 
   g_cancellable_reset (cancellable);
 
   /* If the task is already cancelled before it starts, it returns
    * immediately, but the thread func still runs.
    */
-  thread_state = THREAD_STARTING;
+  g_atomic_int_set (&thread_state, THREAD_STARTING);
   task = g_task_new (NULL, cancellable, run_in_thread_sync_callback, NULL);
   g_task_set_return_on_cancel (task, TRUE);
 
@@ -1711,7 +1711,7 @@ test_return_on_cancel_sync (void)
                                 cancel_sync_runner_thread, task);
 
   g_thread_join (runner_thread);
-  g_assert (thread_state == THREAD_STARTING);
+  g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_STARTING);
 
   ret = g_task_propagate_int (task, &error);
   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
@@ -1720,17 +1720,17 @@ test_return_on_cancel_sync (void)
 
   g_object_unref (task);
 
-  while (thread_state == THREAD_STARTING)
+  while (g_atomic_int_get (&thread_state) == THREAD_STARTING)
     g_cond_wait (&roc_init_cond, &roc_init_mutex);
   g_mutex_unlock (&roc_init_mutex);
 
-  g_assert (thread_state == THREAD_RUNNING);
+  g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING);
 
-  while (thread_state == THREAD_RUNNING)
+  while (g_atomic_int_get (&thread_state) == THREAD_RUNNING)
     g_cond_wait (&roc_finish_cond, &roc_finish_mutex);
   g_mutex_unlock (&roc_finish_mutex);
 
-  g_assert (thread_state == THREAD_CANCELLED);
+  g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_CANCELLED);
 
   g_object_unref (cancellable);
 }
@@ -1776,7 +1776,7 @@ return_on_cancel_atomic_thread (GTask        *task,
                                 gpointer      task_data,
                                 GCancellable *cancellable)
 {
-  gint *state = task_data;
+  gint *state = task_data;  /* (atomic) */
 
   g_assert (source_object == g_task_get_source_object (task));
   g_assert (task_data == g_task_get_task_data (task));
@@ -1784,34 +1784,34 @@ return_on_cancel_atomic_thread (GTask        *task,
   g_assert_false (g_task_get_completed (task));
 
   g_assert (g_thread_self () != main_thread);
-  g_assert_cmpint (*state, ==, 0);
+  g_assert_cmpint (g_atomic_int_get (state), ==, 0);
 
   g_mutex_lock (&roca_mutex_1);
-  *state = 1;
+  g_atomic_int_set (state, 1);
   g_cond_signal (&roca_cond_1);
   g_mutex_unlock (&roca_mutex_1);
 
   g_mutex_lock (&roca_mutex_2);
   if (g_task_set_return_on_cancel (task, FALSE))
-    *state = 2;
+    g_atomic_int_set (state, 2);
   else
-    *state = 3;
+    g_atomic_int_set (state, 3);
   g_cond_signal (&roca_cond_2);
   g_mutex_unlock (&roca_mutex_2);
 
   g_mutex_lock (&roca_mutex_1);
   if (g_task_set_return_on_cancel (task, TRUE))
-    *state = 4;
+    g_atomic_int_set (state, 4);
   else
-    *state = 5;
+    g_atomic_int_set (state, 5);
   g_cond_signal (&roca_cond_1);
   g_mutex_unlock (&roca_mutex_1);
 
   g_mutex_lock (&roca_mutex_2);
   if (g_task_set_return_on_cancel (task, TRUE))
-    *state = 6;
+    g_atomic_int_set (state, 6);
   else
-    *state = 7;
+    g_atomic_int_set (state, 7);
   g_cond_signal (&roca_cond_2);
   g_mutex_unlock (&roca_mutex_2);
 
@@ -1823,7 +1823,7 @@ test_return_on_cancel_atomic (void)
 {
   GTask *task;
   GCancellable *cancellable;
-  volatile gint state;
+  gint state;  /* (atomic) */
   gboolean notification_emitted = FALSE;
   gboolean callback_ran;
 
@@ -1832,7 +1832,7 @@ test_return_on_cancel_atomic (void)
   g_mutex_lock (&roca_mutex_2);
 
   /* If we don't cancel it, each set_return_on_cancel() call will succeed */
-  state = 0;
+  g_atomic_int_set (&state, 0);
   callback_ran = FALSE;
   task = g_task_new (NULL, cancellable, return_on_cancel_atomic_callback, &callback_ran);
   g_task_set_return_on_cancel (task, TRUE);
@@ -1843,23 +1843,23 @@ test_return_on_cancel_atomic (void)
   g_task_run_in_thread (task, return_on_cancel_atomic_thread);
   g_object_unref (task);
 
-  g_assert_cmpint (state, ==, 0);
+  g_assert_cmpint (g_atomic_int_get (&state), ==, 0);
 
-  while (state == 0)
+  while (g_atomic_int_get (&state) == 0)
     g_cond_wait (&roca_cond_1, &roca_mutex_1);
-  g_assert (state == 1);
+  g_assert_cmpint (g_atomic_int_get (&state), ==, 1);
 
-  while (state == 1)
+  while (g_atomic_int_get (&state) == 1)
     g_cond_wait (&roca_cond_2, &roca_mutex_2);
-  g_assert (state == 2);
+  g_assert_cmpint (g_atomic_int_get (&state), ==, 2);
 
-  while (state == 2)
+  while (g_atomic_int_get (&state) == 2)
     g_cond_wait (&roca_cond_1, &roca_mutex_1);
-  g_assert (state == 4);
+  g_assert_cmpint (g_atomic_int_get (&state), ==, 4);
 
-  while (state == 4)
+  while (g_atomic_int_get (&state) == 4)
     g_cond_wait (&roca_cond_2, &roca_mutex_2);
-  g_assert (state == 6);
+  g_assert_cmpint (g_atomic_int_get (&state), ==, 6);
 
   /* callback assumes there'll be a cancelled error */
   g_cancellable_cancel (cancellable);
@@ -1876,7 +1876,7 @@ test_return_on_cancel_atomic (void)
    * task won't complete right away, and further
    * g_task_set_return_on_cancel() calls will return FALSE.
    */
-  state = 0;
+  g_atomic_int_set (&state, 0);
   callback_ran = FALSE;
   notification_emitted = FALSE;
   task = g_task_new (NULL, cancellable, return_on_cancel_atomic_callback, &callback_ran);
@@ -1887,16 +1887,16 @@ test_return_on_cancel_atomic (void)
   g_task_set_task_data (task, (gpointer)&state, NULL);
   g_task_run_in_thread (task, return_on_cancel_atomic_thread);
 
-  g_assert_cmpint (state, ==, 0);
+  g_assert_cmpint (g_atomic_int_get (&state), ==, 0);
 
-  while (state == 0)
+  while (g_atomic_int_get (&state) == 0)
     g_cond_wait (&roca_cond_1, &roca_mutex_1);
-  g_assert (state == 1);
+  g_assert_cmpint (g_atomic_int_get (&state), ==, 1);
   g_assert (g_task_get_return_on_cancel (task));
 
-  while (state == 1)
+  while (g_atomic_int_get (&state) == 1)
     g_cond_wait (&roca_cond_2, &roca_mutex_2);
-  g_assert (state == 2);
+  g_assert_cmpint (g_atomic_int_get (&state), ==, 2);
   g_assert (!g_task_get_return_on_cancel (task));
 
   g_cancellable_cancel (cancellable);
@@ -1904,18 +1904,18 @@ test_return_on_cancel_atomic (void)
   g_main_loop_run (loop);
   g_assert (callback_ran == FALSE);
 
-  while (state == 2)
+  while (g_atomic_int_get (&state) == 2)
     g_cond_wait (&roca_cond_1, &roca_mutex_1);
-  g_assert (state == 5);
+  g_assert_cmpint (g_atomic_int_get (&state), ==, 5);
   g_assert (!g_task_get_return_on_cancel (task));
 
   g_main_loop_run (loop);
   g_assert (callback_ran == TRUE);
   g_assert_true (notification_emitted);
 
-  while (state == 5)
+  while (g_atomic_int_get (&state) == 5)
     g_cond_wait (&roca_cond_2, &roca_mutex_2);
-  g_assert (state == 7);
+  g_assert_cmpint (g_atomic_int_get (&state), ==, 7);
 
   g_object_unref (cancellable);
   g_mutex_unlock (&roca_mutex_1);
index dd08aa0..62a31f4 100644 (file)
@@ -4,6 +4,7 @@
     <file >test-generated.txt</file>
     <file compressed="true">test1.txt</file>
     <file preprocess="xml-stripblanks">test.gresource.xml</file>
+    <file compressed="true">empty.txt</file>
   </gresource>
   <gresource prefix="/a_prefix">
     <file alias="test2-alias.txt">test2.txt</file>
index 8b8c645..0bc67aa 100644 (file)
  * This call acts as a full compiler and hardware
  * memory barrier (before the get).
  *
+ * While @atomic has a `volatile` qualifier, this is a historical artifact and
+ * the pointer passed to it should not be `volatile`.
+ *
  * Returns: the value of the integer
  *
  * Since: 2.4
@@ -125,6 +128,9 @@ gint
  * This call acts as a full compiler and hardware
  * memory barrier (after the set).
  *
+ * While @atomic has a `volatile` qualifier, this is a historical artifact and
+ * the pointer passed to it should not be `volatile`.
+ *
  * Since: 2.4
  */
 void
@@ -144,6 +150,9 @@ void
  *
  * This call acts as a full compiler and hardware memory barrier.
  *
+ * While @atomic has a `volatile` qualifier, this is a historical artifact and
+ * the pointer passed to it should not be `volatile`.
+ *
  * Since: 2.4
  **/
 void
@@ -163,6 +172,9 @@ void
  *
  * This call acts as a full compiler and hardware memory barrier.
  *
+ * While @atomic has a `volatile` qualifier, this is a historical artifact and
+ * the pointer passed to it should not be `volatile`.
+ *
  * Returns: %TRUE if the resultant value is zero
  *
  * Since: 2.4
@@ -189,6 +201,9 @@ gboolean
  *
  * This call acts as a full compiler and hardware memory barrier.
  *
+ * While @atomic has a `volatile` qualifier, this is a historical artifact and
+ * the pointer passed to it should not be `volatile`.
+ *
  * Returns: %TRUE if the exchange took place
  *
  * Since: 2.4
@@ -216,6 +231,9 @@ gboolean
  * Before version 2.30, this function did not return a value
  * (but g_atomic_int_exchange_and_add() did, and had the same meaning).
  *
+ * While @atomic has a `volatile` qualifier, this is a historical artifact and
+ * the pointer passed to it should not be `volatile`.
+ *
  * Returns: the value of @atomic before the add, signed
  *
  * Since: 2.4
@@ -240,6 +258,9 @@ gint
  * Think of this operation as an atomic version of
  * `{ tmp = *atomic; *atomic &= val; return tmp; }`.
  *
+ * While @atomic has a `volatile` qualifier, this is a historical artifact and
+ * the pointer passed to it should not be `volatile`.
+ *
  * Returns: the value of @atomic before the operation, unsigned
  *
  * Since: 2.30
@@ -264,6 +285,9 @@ guint
  *
  * This call acts as a full compiler and hardware memory barrier.
  *
+ * While @atomic has a `volatile` qualifier, this is a historical artifact and
+ * the pointer passed to it should not be `volatile`.
+ *
  * Returns: the value of @atomic before the operation, unsigned
  *
  * Since: 2.30
@@ -288,6 +312,9 @@ guint
  *
  * This call acts as a full compiler and hardware memory barrier.
  *
+ * While @atomic has a `volatile` qualifier, this is a historical artifact and
+ * the pointer passed to it should not be `volatile`.
+ *
  * Returns: the value of @atomic before the operation, unsigned
  *
  * Since: 2.30
@@ -309,6 +336,9 @@ guint
  * This call acts as a full compiler and hardware
  * memory barrier (before the get).
  *
+ * While @atomic has a `volatile` qualifier, this is a historical artifact and
+ * the pointer passed to it should not be `volatile`.
+ *
  * Returns: the value of the pointer
  *
  * Since: 2.4
@@ -316,7 +346,7 @@ guint
 gpointer
 (g_atomic_pointer_get) (const volatile void *atomic)
 {
-  return g_atomic_pointer_get ((const volatile gpointer *) atomic);
+  return g_atomic_pointer_get ((gpointer *) atomic);
 }
 
 /**
@@ -329,13 +359,16 @@ gpointer
  * This call acts as a full compiler and hardware
  * memory barrier (after the set).
  *
+ * While @atomic has a `volatile` qualifier, this is a historical artifact and
+ * the pointer passed to it should not be `volatile`.
+ *
  * Since: 2.4
  **/
 void
 (g_atomic_pointer_set) (volatile void *atomic,
                         gpointer       newval)
 {
-  g_atomic_pointer_set ((volatile gpointer *) atomic, newval);
+  g_atomic_pointer_set ((gpointer *) atomic, newval);
 }
 
 /**
@@ -354,6 +387,9 @@ void
  *
  * This call acts as a full compiler and hardware memory barrier.
  *
+ * While @atomic has a `volatile` qualifier, this is a historical artifact and
+ * the pointer passed to it should not be `volatile`.
+ *
  * Returns: %TRUE if the exchange took place
  *
  * Since: 2.4
@@ -363,7 +399,7 @@ gboolean
                                          gpointer       oldval,
                                          gpointer       newval)
 {
-  return g_atomic_pointer_compare_and_exchange ((volatile gpointer *) atomic,
+  return g_atomic_pointer_compare_and_exchange ((gpointer *) atomic,
                                                 oldval, newval);
 }
 
@@ -379,6 +415,9 @@ gboolean
  *
  * This call acts as a full compiler and hardware memory barrier.
  *
+ * While @atomic has a `volatile` qualifier, this is a historical artifact and
+ * the pointer passed to it should not be `volatile`.
+ *
  * Returns: the value of @atomic before the add, signed
  *
  * Since: 2.30
@@ -387,7 +426,7 @@ gssize
 (g_atomic_pointer_add) (volatile void *atomic,
                         gssize         val)
 {
-  return g_atomic_pointer_add ((volatile gpointer *) atomic, val);
+  return g_atomic_pointer_add ((gpointer *) atomic, val);
 }
 
 /**
@@ -403,6 +442,9 @@ gssize
  *
  * This call acts as a full compiler and hardware memory barrier.
  *
+ * While @atomic has a `volatile` qualifier, this is a historical artifact and
+ * the pointer passed to it should not be `volatile`.
+ *
  * Returns: the value of @atomic before the operation, unsigned
  *
  * Since: 2.30
@@ -411,7 +453,7 @@ gsize
 (g_atomic_pointer_and) (volatile void *atomic,
                         gsize          val)
 {
-  return g_atomic_pointer_and ((volatile gpointer *) atomic, val);
+  return g_atomic_pointer_and ((gpointer *) atomic, val);
 }
 
 /**
@@ -427,6 +469,9 @@ gsize
  *
  * This call acts as a full compiler and hardware memory barrier.
  *
+ * While @atomic has a `volatile` qualifier, this is a historical artifact and
+ * the pointer passed to it should not be `volatile`.
+ *
  * Returns: the value of @atomic before the operation, unsigned
  *
  * Since: 2.30
@@ -435,7 +480,7 @@ gsize
 (g_atomic_pointer_or) (volatile void *atomic,
                        gsize          val)
 {
-  return g_atomic_pointer_or ((volatile gpointer *) atomic, val);
+  return g_atomic_pointer_or ((gpointer *) atomic, val);
 }
 
 /**
@@ -451,6 +496,9 @@ gsize
  *
  * This call acts as a full compiler and hardware memory barrier.
  *
+ * While @atomic has a `volatile` qualifier, this is a historical artifact and
+ * the pointer passed to it should not be `volatile`.
+ *
  * Returns: the value of @atomic before the operation, unsigned
  *
  * Since: 2.30
@@ -459,7 +507,7 @@ gsize
 (g_atomic_pointer_xor) (volatile void *atomic,
                         gsize          val)
 {
-  return g_atomic_pointer_xor ((volatile gpointer *) atomic, val);
+  return g_atomic_pointer_xor ((gpointer *) atomic, val);
 }
 
 #elif defined (G_PLATFORM_WIN32)
@@ -591,7 +639,7 @@ guint
 gpointer
 (g_atomic_pointer_get) (const volatile void *atomic)
 {
-  const volatile gpointer *ptr = atomic;
+  const gpointer *ptr = atomic;
 
   MemoryBarrier ();
   return *ptr;
@@ -601,7 +649,7 @@ void
 (g_atomic_pointer_set) (volatile void *atomic,
                         gpointer       newval)
 {
-  volatile gpointer *ptr = atomic;
+  gpointer *ptr = atomic;
 
   *ptr = newval;
   MemoryBarrier ();
@@ -797,7 +845,7 @@ guint
 gpointer
 (g_atomic_pointer_get) (const volatile void *atomic)
 {
-  const volatile gpointer *ptr = atomic;
+  const gpointer *ptr = atomic;
   gpointer value;
 
   pthread_mutex_lock (&g_atomic_lock);
@@ -811,7 +859,7 @@ void
 (g_atomic_pointer_set) (volatile void *atomic,
                         gpointer       newval)
 {
-  volatile gpointer *ptr = atomic;
+  gpointer *ptr = atomic;
 
   pthread_mutex_lock (&g_atomic_lock);
   *ptr = newval;
@@ -823,7 +871,7 @@ gboolean
                                          gpointer       oldval,
                                          gpointer       newval)
 {
-  volatile gpointer *ptr = atomic;
+  gpointer *ptr = atomic;
   gboolean success;
 
   pthread_mutex_lock (&g_atomic_lock);
@@ -840,7 +888,7 @@ gssize
 (g_atomic_pointer_add) (volatile void *atomic,
                         gssize         val)
 {
-  volatile gssize *ptr = atomic;
+  gssize *ptr = atomic;
   gssize oldval;
 
   pthread_mutex_lock (&g_atomic_lock);
@@ -855,7 +903,7 @@ gsize
 (g_atomic_pointer_and) (volatile void *atomic,
                         gsize          val)
 {
-  volatile gsize *ptr = atomic;
+  gsize *ptr = atomic;
   gsize oldval;
 
   pthread_mutex_lock (&g_atomic_lock);
@@ -870,7 +918,7 @@ gsize
 (g_atomic_pointer_or) (volatile void *atomic,
                        gsize          val)
 {
-  volatile gsize *ptr = atomic;
+  gsize *ptr = atomic;
   gsize oldval;
 
   pthread_mutex_lock (&g_atomic_lock);
@@ -885,7 +933,7 @@ gsize
 (g_atomic_pointer_xor) (volatile void *atomic,
                         gsize          val)
 {
-  volatile gsize *ptr = atomic;
+  gsize *ptr = atomic;
   gsize oldval;
 
   pthread_mutex_lock (&g_atomic_lock);
@@ -915,5 +963,5 @@ gint
 g_atomic_int_exchange_and_add (volatile gint *atomic,
                                gint           val)
 {
-  return (g_atomic_int_add) (atomic, val);
+  return (g_atomic_int_add) ((gint *) atomic, val);
 }
index bb1435c..e6eccfa 100644 (file)
@@ -211,7 +211,7 @@ G_END_DECLS
   }))
 #define g_atomic_pointer_and(atomic, val) \
   (G_GNUC_EXTENSION ({                                                       \
-    volatile gsize *gapa_atomic = (volatile gsize *) (atomic);               \
+    gsize *gapa_atomic = (gsize *) (atomic);                                 \
     G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer));                 \
     G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gsize));                    \
     (void) (0 ? (gpointer) *(atomic) : NULL);                                \
@@ -220,7 +220,7 @@ G_END_DECLS
   }))
 #define g_atomic_pointer_or(atomic, val) \
   (G_GNUC_EXTENSION ({                                                       \
-    volatile gsize *gapo_atomic = (volatile gsize *) (atomic);               \
+    gsize *gapo_atomic = (gsize *) (atomic);                                 \
     G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer));                 \
     G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gsize));                    \
     (void) (0 ? (gpointer) *(atomic) : NULL);                                \
@@ -229,7 +229,7 @@ G_END_DECLS
   }))
 #define g_atomic_pointer_xor(atomic, val) \
   (G_GNUC_EXTENSION ({                                                       \
-    volatile gsize *gapx_atomic = (volatile gsize *) (atomic);               \
+    gsize *gapx_atomic = (gsize *) (atomic);                                 \
     G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer));                 \
     G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gsize));                    \
     (void) (0 ? (gpointer) *(atomic) : NULL);                                \
index 1755257..a2409f4 100644 (file)
@@ -126,7 +126,7 @@ struct _GDateTime
   /* 1 is 0001-01-01 in Proleptic Gregorian */
   gint32 days;
 
-  volatile gint ref_count;
+  gint ref_count;  /* (atomic) */
 };
 
 /* Time conversion {{{1 */
@@ -1383,15 +1383,15 @@ parse_iso8601_timezone (const gchar *text, gsize length, gssize *tz_offset)
     return NULL;
 
   *tz_offset = i;
-  tz = g_time_zone_new (text + i);
+  tz = g_time_zone_new_identifier (text + i);
 
   /* Double-check that the GTimeZone matches our interpretation of the timezone.
    * This can fail because our interpretation is less strict than (for example)
    * parse_time() in gtimezone.c, which restricts the range of the parsed
    * integers. */
-  if (g_time_zone_get_offset (tz, 0) != offset_sign * (offset_hours * 3600 + offset_minutes * 60))
+  if (tz == NULL || g_time_zone_get_offset (tz, 0) != offset_sign * (offset_hours * 3600 + offset_minutes * 60))
     {
-      g_time_zone_unref (tz);
+      g_clear_pointer (&tz, g_time_zone_unref);
       return NULL;
     }
 
@@ -2018,8 +2018,8 @@ g_date_time_add_full (GDateTime *datetime,
 /* Compare, difference, hash, equal {{{1 */
 /**
  * g_date_time_compare:
- * @dt1: (not nullable): first #GDateTime to compare
- * @dt2: (not nullable): second #GDateTime to compare
+ * @dt1: (type GDateTime) (not nullable): first #GDateTime to compare
+ * @dt2: (type GDateTime) (not nullable): second #GDateTime to compare
  *
  * A comparison function for #GDateTimes that is suitable
  * as a #GCompareFunc. Both #GDateTimes must be non-%NULL.
@@ -2074,7 +2074,7 @@ g_date_time_difference (GDateTime *end,
 
 /**
  * g_date_time_hash:
- * @datetime: (not nullable): a #GDateTime
+ * @datetime: (type GDateTime) (not nullable): a #GDateTime
  *
  * Hashes @datetime into a #guint, suitable for use within #GHashTable.
  *
@@ -2092,8 +2092,8 @@ g_date_time_hash (gconstpointer datetime)
 
 /**
  * g_date_time_equal:
- * @dt1: (not nullable): a #GDateTime
- * @dt2: (not nullable): a #GDateTime
+ * @dt1: (type GDateTime) (not nullable): a #GDateTime
+ * @dt2: (type GDateTime) (not nullable): a #GDateTime
  *
  * Checks to see if @dt1 and @dt2 are equal.
  *
index 66be5c9..6e671d6 100644 (file)
 
 #include <string.h>
 
+#ifdef G_OS_UNIX
+#include <unistd.h>
+#endif
+
 #include "ghostutils.h"
 
 #include "garray.h"
 #include "gstrfuncs.h"
 #include "glibintl.h"
 
+#ifdef G_PLATFORM_WIN32
+#include <windows.h>
+#endif
+
 
 /**
  * SECTION:ghostutils
@@ -405,6 +413,45 @@ idna_end_of_label (const gchar *str)
   return str;
 }
 
+static gsize
+get_hostname_max_length_bytes (void)
+{
+#if defined(G_OS_WIN32)
+  wchar_t tmp[MAX_COMPUTERNAME_LENGTH];
+  return sizeof (tmp) / sizeof (tmp[0]);
+#elif defined(_SC_HOST_NAME_MAX)
+  glong max = sysconf (_SC_HOST_NAME_MAX);
+  if (max > 0)
+    return (gsize) max;
+
+#ifdef HOST_NAME_MAX
+  return HOST_NAME_MAX;
+#else
+  return _POSIX_HOST_NAME_MAX;
+#endif /* HOST_NAME_MAX */
+#else
+  /* Fallback to some reasonable value
+   * See https://stackoverflow.com/questions/8724954/what-is-the-maximum-number-of-characters-for-a-host-name-in-unix/28918017#28918017 */
+  return 255;
+#endif
+}
+
+/* Returns %TRUE if `strlen (str) > comparison_length`, but without actually
+ * running `strlen(str)`, as that would take a very long time for long
+ * (untrusted) input strings. */
+static gboolean
+strlen_greater_than (const gchar *str,
+                     gsize        comparison_length)
+{
+  gsize i;
+
+  for (i = 0; str[i] != '\0'; i++)
+    if (i > comparison_length)
+      return TRUE;
+
+  return FALSE;
+}
+
 /**
  * g_hostname_to_ascii:
  * @hostname: a valid UTF-8 or ASCII hostname
@@ -413,8 +460,8 @@ idna_end_of_label (const gchar *str)
  * string containing no uppercase letters and not ending with a
  * trailing dot.
  *
- * Returns: an ASCII hostname, which must be freed, or %NULL if
- * @hostname is in some way invalid.
+ * Returns: (nullable) (transfer full): an ASCII hostname, which must be freed,
+ *    or %NULL if @hostname is in some way invalid.
  *
  * Since: 2.22
  **/
@@ -425,6 +472,32 @@ g_hostname_to_ascii (const gchar *hostname)
   GString *out;
   gssize llen, oldlen;
   gboolean unicode;
+  gsize hostname_max_length_bytes = get_hostname_max_length_bytes ();
+
+  /* Do an initial check on the hostname length, as overlong hostnames take a
+   * long time in the IDN cleanup algorithm in nameprep(). The ultimate
+   * restriction is that the IDN-decoded (i.e. pure ASCII) hostname cannot be
+   * longer than 255 bytes. That’s the least restrictive limit on hostname
+   * length of all the ways hostnames can be interpreted. Typically, the
+   * hostname will be an FQDN, which is limited to 253 bytes long. POSIX
+   * hostnames are limited to `get_hostname_max_length_bytes()` (typically 255
+   * bytes).
+   *
+   * See https://stackoverflow.com/a/28918017/2931197
+   *
+   * It’s possible for a hostname to be %-encoded, in which case its decoded
+   * length will be as much as 3× shorter.
+   *
+   * It’s also possible for a hostname to use overlong UTF-8 encodings, in which
+   * case its decoded length will be as much as 4× shorter.
+   *
+   * Note: This check is not intended as an absolute guarantee that a hostname
+   * is the right length and will be accepted by other systems. It’s intended to
+   * stop wildly-invalid hostnames from taking forever in nameprep().
+   */
+  if (hostname_max_length_bytes <= G_MAXSIZE / 4 &&
+      strlen_greater_than (hostname, 4 * MAX (255, hostname_max_length_bytes)))
+    return NULL;
 
   label = name = nameprep (hostname, -1, &unicode);
   if (!name || !unicode)
@@ -594,8 +667,8 @@ punycode_decode (const gchar *input,
  * Of course if @hostname is not an internationalized hostname, then
  * the canonical presentation form will be entirely ASCII.
  *
- * Returns: a UTF-8 hostname, which must be freed, or %NULL if
- * @hostname is in some way invalid.
+ * Returns: (nullable) (transfer full): a UTF-8 hostname, which must be freed,
+ *    or %NULL if @hostname is in some way invalid.
  *
  * Since: 2.22
  **/
@@ -604,6 +677,12 @@ g_hostname_to_unicode (const gchar *hostname)
 {
   GString *out;
   gssize llen;
+  gsize hostname_max_length_bytes = get_hostname_max_length_bytes ();
+
+  /* See the comment at the top of g_hostname_to_ascii(). */
+  if (hostname_max_length_bytes <= G_MAXSIZE / 4 &&
+      strlen_greater_than (hostname, 4 * MAX (255, hostname_max_length_bytes)))
+    return NULL;
 
   out = g_string_new (NULL);
 
index 9d02153..bbe638b 100644 (file)
@@ -512,7 +512,7 @@ struct _GKeyFile
 
   gchar **locales;
 
-  volatile gint ref_count;
+  gint ref_count;  /* (atomic) */
 };
 
 typedef struct _GKeyFileKeyValuePair GKeyFileKeyValuePair;
index fd8baf5..8c15d58 100644 (file)
@@ -4,48 +4,57 @@ import sys
 if sys.version_info[0] >= 3:
     long = int
 
+
 # This is not quite right, as local vars may override symname
-def read_global_var (symname):
+def read_global_var(symname):
     return gdb.selected_frame().read_var(symname)
 
-def g_quark_to_string (quark):
+
+def g_quark_to_string(quark):
     if quark is None:
         return None
     quark = long(quark)
     if quark == 0:
         return None
     try:
-        val = read_global_var ("quarks")
-        max_q = long(read_global_var ("quark_seq_id"))
-    except:
+        val = read_global_var("quarks")
+        max_q = long(read_global_var("quark_seq_id"))
+    except Exception:
         try:
-            val = read_global_var ("g_quarks")
-            max_q = long(read_global_var ("g_quark_seq_id"))
-        except:
-            return None;
+            val = read_global_var("g_quarks")
+            max_q = long(read_global_var("g_quark_seq_id"))
+        except Exception:
+            return None
     if quark < max_q:
         return val[quark].string()
     return None
 
+
 # We override the node printers too, so that node->next is not expanded
 class GListNodePrinter:
     "Prints a GList node"
 
-    def __init__ (self, val):
+    def __init__(self, val):
         self.val = val
 
-    def to_string (self):
-        return "{data=%s, next=0x%x, prev=0x%x}" % (str(self.val["data"]), long(self.val["next"]), long(self.val["prev"]))
+    def to_string(self):
+        return "{data=%s, next=0x%x, prev=0x%x}" % (
+            str(self.val["data"]),
+            long(self.val["next"]),
+            long(self.val["prev"]),
+        )
+
 
 class GSListNodePrinter:
     "Prints a GSList node"
 
-    def __init__ (self, val):
+    def __init__(self, val):
         self.val = val
 
-    def to_string (self):
+    def to_string(self):
         return "{data=%s, next=0x%x}" % (str(self.val["data"]), long(self.val["next"]))
 
+
 class GListPrinter:
     "Prints a GList"
 
@@ -61,27 +70,28 @@ class GListPrinter:
         def next(self):
             if self.link == 0:
                 raise StopIteration
-            data = self.link['data']
-            self.link = self.link['next']
+            data = self.link["data"]
+            self.link = self.link["next"]
             count = self.count
             self.count = self.count + 1
-            return ('[%d]' % count, data)
+            return ("[%d]" % count, data)
 
         __next__ = next
 
-    def __init__ (self, val, listtype):
+    def __init__(self, val, listtype):
         self.val = val
         self.listtype = listtype
 
     def children(self):
         return self._iterator(self.val, self.listtype)
 
-    def to_string (self):
-        return  "0x%x" % (long(self.val))
+    def to_string(self):
+        return "0x%x" % (long(self.val))
 
-    def display_hint (self):
+    def display_hint(self):
         return "array"
 
+
 class GHashPrinter:
     "Prints a GHashTable"
 
@@ -90,7 +100,9 @@ class GHashPrinter:
             def __init__(self, ptr, big_items):
                 self._big_items = big_items
                 self._gpointer_type = gdb.lookup_type("gpointer")
-                item_type = self._gpointer_type if self._big_items else gdb.lookup_type("guint")
+                item_type = (
+                    self._gpointer_type if self._big_items else gdb.lookup_type("guint")
+                )
 
                 self._items = ptr.cast(item_type.pointer())
 
@@ -119,23 +131,23 @@ class GHashPrinter:
         def next(self):
             if self.ht == 0:
                 raise StopIteration
-            if self.value != None:
+            if self.value is not None:
                 v = self.value
                 self.value = None
                 return v
             while long(self.pos) < long(self.size):
-                if long (self.hashes[self.pos]) >= 2:
+                if long(self.hashes[self.pos]) >= 2:
                     key = self.keys[self.pos]
                     val = self.values[self.pos]
 
                     if self.keys_are_strings:
-                        key = key.cast (gdb.lookup_type("char").pointer())
+                        key = key.cast(gdb.lookup_type("char").pointer())
 
                     # Queue value for next result
-                    self.value = ('[%dv]'% (self.pos), val)
+                    self.value = ("[%dv]" % (self.pos), val)
 
                     # Increment pos and return key
-                    key = ('[%dk]'% (self.pos), key)
+                    key = ("[%dk]" % (self.pos), key)
                     self.pos += 1
                     return key
 
@@ -144,33 +156,38 @@ class GHashPrinter:
 
         __next__ = next
 
-    def __init__ (self, val):
+    def __init__(self, val):
         self.val = val
         self.keys_are_strings = False
         try:
-            string_hash = read_global_var ("g_str_hash")
-        except:
+            string_hash = read_global_var("g_str_hash")
+        except Exception:
             string_hash = None
-        if self.val != 0 and string_hash != None and self.val["hash_func"] == string_hash:
+        if (
+            self.val != 0
+            and string_hash is not None
+            and self.val["hash_func"] == string_hash
+        ):
             self.keys_are_strings = True
 
     def children(self):
         return self._iterator(self.val, self.keys_are_strings)
 
-    def to_string (self):
-        return  "0x%x" % (long(self.val))
+    def to_string(self):
+        return "0x%x" % (long(self.val))
 
-    def display_hint (self):
+    def display_hint(self):
         return "map"
 
-def pretty_printer_lookup (val):
+
+def pretty_printer_lookup(val):
     # None yet, want things like hash table and list
 
     type = val.type.unqualified()
 
     # If it points to a reference, get the reference.
     if type.code == gdb.TYPE_CODE_REF:
-        type = type.target ()
+        type = type.target()
 
     if type.code == gdb.TYPE_CODE_PTR:
         type = type.target().unqualified()
@@ -189,52 +206,54 @@ def pretty_printer_lookup (val):
             return GListPrinter(val, "GSList")
     return None
 
-def register (obj):
+
+def register(obj):
     if obj is None:
         obj = gdb
 
     obj.pretty_printers.append(pretty_printer_lookup)
 
-class ForeachCommand (gdb.Command):
+
+class ForeachCommand(gdb.Command):
     """Foreach on list"""
 
-    def __init__ (self):
-        super (ForeachCommand, self).__init__ ("gforeach",
-                                               gdb.COMMAND_DATA,
-                                               gdb.COMPLETE_SYMBOL)
+    def __init__(self):
+        super(ForeachCommand, self).__init__(
+            "gforeach", gdb.COMMAND_DATA, gdb.COMPLETE_SYMBOL
+        )
 
-    def valid_name (self, name):
+    def valid_name(self, name):
         if not name[0].isalpha():
             return False
         return True
 
-    def parse_args (self, arg):
+    def parse_args(self, arg):
         i = arg.find(" ")
         if i <= 0:
-            raise Exception ("No var specified")
+            raise Exception("No var specified")
         var = arg[:i]
         if not self.valid_name(var):
-            raise Exception ("Invalid variable name")
+            raise Exception("Invalid variable name")
 
-        while i < len (arg) and arg[i].isspace():
+        while i < len(arg) and arg[i].isspace():
             i = i + 1
 
-        if arg[i:i+2] != "in":
-            raise Exception ("Invalid syntax, missing in")
+        if arg[i : i + 2] != "in":
+            raise Exception("Invalid syntax, missing in")
 
         i = i + 2
 
-        while i < len (arg) and arg[i].isspace():
+        while i < len(arg) and arg[i].isspace():
             i = i + 1
 
-        colon = arg.find (":", i)
+        colon = arg.find(":", i)
         if colon == -1:
-            raise Exception ("Invalid syntax, missing colon")
+            raise Exception("Invalid syntax, missing colon")
 
         val = arg[i:colon]
 
         colon = colon + 1
-        while colon < len (arg) and arg[colon].isspace():
+        while colon < len(arg) and arg[colon].isspace():
             colon = colon + 1
 
         command = arg[colon:]
@@ -242,25 +261,25 @@ class ForeachCommand (gdb.Command):
         return (var, val, command)
 
     def do_iter(self, arg, item, command):
-        item = item.cast (gdb.lookup_type("void").pointer())
+        item = item.cast(gdb.lookup_type("void").pointer())
         item = long(item)
-        to_eval = "set $%s = (void *)0x%x\n"%(arg, item)
+        to_eval = "set $%s = (void *)0x%x\n" % (arg, item)
         gdb.execute(to_eval)
         gdb.execute(command)
 
-    def slist_iterator (self, arg, container, command):
-        l = container.cast (gdb.lookup_type("GSList").pointer())
-        while long(l) != 0:
-            self.do_iter (arg, l["data"], command)
-            l = l["next"]
+    def slist_iterator(self, arg, container, command):
+        list_element = container.cast(gdb.lookup_type("GSList").pointer())
+        while long(list_element) != 0:
+            self.do_iter(arg, list_element["data"], command)
+            list_element = list_element["next"]
 
-    def list_iterator (self, arg, container, command):
-        l = container.cast (gdb.lookup_type("GList").pointer())
-        while long(l) != 0:
-            self.do_iter (arg, l["data"], command)
-            l = l["next"]
+    def list_iterator(self, arg, container, command):
+        list_element = container.cast(gdb.lookup_type("GList").pointer())
+        while long(list_element) != 0:
+            self.do_iter(arg, list_element["data"], command)
+            list_element = list_element["next"]
 
-    def pick_iterator (self, container):
+    def pick_iterator(self, container):
         t = container.type.unqualified()
         if t.code == gdb.TYPE_CODE_PTR:
             t = t.target().unqualified()
@@ -269,12 +288,13 @@ class ForeachCommand (gdb.Command):
                 return self.slist_iterator
             if t == "GList":
                 return self.list_iterator
-        raise Exception("Invalid container type %s"%(str(container.type)))
+        raise Exception("Invalid container type %s" % (str(container.type)))
 
-    def invoke (self, arg, from_tty):
+    def invoke(self, arg, from_tty):
         (var, container, command) = self.parse_args(arg)
-        container = gdb.parse_and_eval (container)
+        container = gdb.parse_and_eval(container)
         func = self.pick_iterator(container)
         func(var, container, command)
 
-ForeachCommand ()
+
+ForeachCommand()
index d294fa9..65f3738 100644 (file)
  * It is used for declaring functions which never return. It enables
  * optimization of the function, and avoids possible compiler warnings.
  *
+ * Since 2.68, it is recommended that code uses %G_NORETURN instead of
+ * %G_GNUC_NORETURN, as that works on more platforms and compilers (in
+ * particular, MSVC and C++11) than %G_GNUC_NORETURN, which works with GCC and
+ * Clang only. %G_GNUC_NORETURN continues to work, so has not been deprecated
+ * yet.
+ *
  * Place the attribute after the declaration, just before the semicolon.
  *
  * |[<!-- language="C" -->
 #define G_CONST_RETURN const GLIB_DEPRECATED_MACRO_IN_2_30_FOR(const)
 #endif
 
+/**
+ * G_NORETURN:
+ *
+ * Expands to the GNU C or MSVC `noreturn` function attribute depending on
+ * the compiler. It is used for declaring functions which never return.
+ * Enables optimization of the function, and avoids possible compiler warnings.
+ *
+ * Note that %G_NORETURN supersedes the previous %G_GNUC_NORETURN macro, which
+ * will eventually be deprecated. %G_NORETURN supports more platforms.
+ *
+ * Place the attribute before the function declaration as follows:
+ *
+ * |[<!-- language="C" -->
+ * G_NORETURN void g_abort (void);
+ * ]|
+ *
+ * Since: 2.68
+ */
+/* Note: We can’t annotate this with GLIB_AVAILABLE_MACRO_IN_2_68 because it’s
+ * used within the GLib headers in function declarations which are always
+ * evaluated when a header is included. This results in warnings in third party
+ * code which includes glib.h, even if the third party code doesn’t use the new
+ * macro itself. */
+#if (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__)) || (0x5110 <= __SUNPRO_C)
+  /* For compatibility with G_NORETURN_FUNCPTR on clang, use
+     __attribute__((__noreturn__)), not _Noreturn.  */
+# define G_NORETURN __attribute__ ((__noreturn__))
+#elif 1200 <= _MSC_VER
+  /* Use MSVC specific syntax.  */
+# define G_NORETURN __declspec (noreturn)
+  /* Use ISO C++11 syntax when the compiler supports it.  */
+#elif (__cplusplus >= 201103 && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) || (_MSC_VER >= 1900)
+# define G_NORETURN [[noreturn]]
+  /* Use ISO C11 syntax when the compiler supports it.  */
+#elif __STDC_VERSION__ >= 201112 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
+# define G_NORETURN _Noreturn
+#else
+# define G_NORETURN /* empty */
+#endif
+
+/**
+ * G_NORETURN_FUNCPTR:
+ *
+ * Expands to the GNU C or MSVC `noreturn` function attribute depending on
+ * the compiler. It is used for declaring function pointers which never return.
+ * Enables optimization of the function, and avoids possible compiler warnings.
+ *
+ * Place the attribute before the function declaration as follows:
+ *
+ * |[<!-- language="C" -->
+ * G_NORETURN_FUNCPTR void (*funcptr) (void);
+ * ]|
+ *
+ * Note that if the function is not a function pointer, you can simply use
+ * the %G_NORETURN macro as follows:
+ *
+ * |[<!-- language="C" -->
+ * G_NORETURN void g_abort (void);
+ * ]|
+ *
+ * Since: 2.68
+ */
+#if (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__)) || (0x5110 <= __SUNPRO_C)
+# define G_NORETURN_FUNCPTR __attribute__ ((__noreturn__))      \
+  GLIB_AVAILABLE_MACRO_IN_2_68
+#else
+# define G_NORETURN_FUNCPTR /* empty */         \
+  GLIB_AVAILABLE_MACRO_IN_2_68
+#endif
+
 /*
  * The G_LIKELY and G_UNLIKELY macros let the programmer give hints to 
  * the compiler about the expected result of an expression. Some compilers
index 4d057ba..9c5f0ef 100644 (file)
@@ -272,7 +272,7 @@ struct _GMainContext
   guint owner_count;
   GSList *waiters;
 
-  volatile gint ref_count;
+  gint ref_count;  /* (atomic) */
 
   GHashTable *sources;              /* guint -> GSource */
 
@@ -303,7 +303,7 @@ struct _GMainContext
 
 struct _GSourceCallback
 {
-  volatile gint ref_count;
+  gint ref_count;  /* (atomic) */
   GSourceFunc func;
   gpointer    data;
   GDestroyNotify notify;
@@ -313,7 +313,7 @@ struct _GMainLoop
 {
   GMainContext *context;
   gboolean is_running; /* (atomic) */
-  volatile gint ref_count;
+  gint ref_count;  /* (atomic) */
 };
 
 struct _GTimeoutSource
@@ -3733,7 +3733,10 @@ g_main_context_prepare (GMainContext *context,
  *       store #GPollFD records that need to be polled.
  * @n_fds: (in): length of @fds.
  *
- * Determines information necessary to poll this main loop.
+ * Determines information necessary to poll this main loop. You should
+ * be careful to pass the resulting @fds array and its length @n_fds
+ * as is when calling g_main_context_check(), as this function relies
+ * on assumptions made when the array is filled.
  *
  * You must have successfully acquired the context with
  * g_main_context_acquire() before you may call this function.
@@ -3757,6 +3760,10 @@ g_main_context_query (GMainContext *context,
 
   TRACE (GLIB_MAIN_CONTEXT_BEFORE_QUERY (context, max_priority));
 
+  /* fds is filled sequentially from poll_records. Since poll_records
+   * are incrementally sorted by file descriptor identifier, fds will
+   * also be incrementally sorted.
+   */
   n_poll = 0;
   lastpollrec = NULL;
   for (pollrec = context->poll_records; pollrec; pollrec = pollrec->next)
@@ -3771,6 +3778,10 @@ g_main_context_query (GMainContext *context,
        */
       events = pollrec->fd->events & ~(G_IO_ERR|G_IO_HUP|G_IO_NVAL);
 
+      /* This optimization --using the same GPollFD to poll for more
+       * than one poll record-- relies on the poll records being
+       * incrementally sorted.
+       */
       if (lastpollrec && pollrec->fd->fd == lastpollrec->fd->fd)
         {
           if (n_poll - 1 < n_fds)
@@ -3816,7 +3827,10 @@ g_main_context_query (GMainContext *context,
  *       the last call to g_main_context_query()
  * @n_fds: return value of g_main_context_query()
  *
- * Passes the results of polling back to the main loop.
+ * Passes the results of polling back to the main loop. You should be
+ * careful to pass @fds and its length @n_fds as received from
+ * g_main_context_query(), as this functions relies on assumptions
+ * on how @fds is filled.
  *
  * You must have successfully acquired the context with
  * g_main_context_acquire() before you may call this function.
@@ -3871,10 +3885,22 @@ g_main_context_check (GMainContext *context,
       return FALSE;
     }
 
+  /* The linear iteration below relies on the assumption that both
+   * poll records and the fds array are incrementally sorted by file
+   * descriptor identifier.
+   */
   pollrec = context->poll_records;
   i = 0;
   while (pollrec && i < n_fds)
     {
+      /* Make sure that fds is sorted by file descriptor identifier. */
+      g_assert (i <= 0 || fds[i - 1].fd < fds[i].fd);
+
+      /* Skip until finding the first GPollRec matching the current GPollFD. */
+      while (pollrec && pollrec->fd->fd != fds[i].fd)
+        pollrec = pollrec->next;
+
+      /* Update all consecutive GPollRecs that match. */
       while (pollrec && pollrec->fd->fd == fds[i].fd)
         {
           if (pollrec->priority <= max_priority)
@@ -3885,6 +3911,7 @@ g_main_context_check (GMainContext *context,
           pollrec = pollrec->next;
         }
 
+      /* Iterate to next GPollFD. */
       i++;
     }
 
@@ -4495,6 +4522,7 @@ g_main_context_add_poll_unlocked (GMainContext *context,
   newrec->fd = fd;
   newrec->priority = priority;
 
+  /* Poll records are incrementally sorted by file descriptor identifier. */
   prevrec = NULL;
   nextrec = context->poll_records;
   while (nextrec)
@@ -4721,7 +4749,7 @@ g_main_context_get_poll_func (GMainContext *context)
  *
  * |[<!-- language="C" --> 
  *   #define NUM_TASKS 10
- *   static volatile gint tasks_remaining = NUM_TASKS;
+ *   static gint tasks_remaining = NUM_TASKS;  // (atomic)
  *   ...
  *  
  *   while (g_atomic_int_get (&tasks_remaining) != 0)
index ba4dfd2..b8327fb 100644 (file)
@@ -119,7 +119,7 @@ struct _GMarkupParseContext
 {
   const GMarkupParser *parser;
 
-  volatile gint ref_count;
+  gint ref_count;  /* (atomic) */
 
   GMarkupParseFlags flags;
 
index 6a28443..43c6d67 100644 (file)
@@ -283,11 +283,12 @@ void g_warn_message           (const char     *domain,
                                const char     *func,
                                const char     *warnexpr) G_ANALYZER_NORETURN;
 GLIB_DEPRECATED
+G_NORETURN
 void g_assert_warning         (const char *log_domain,
                               const char *file,
                               const int   line,
                               const char *pretty_function,
-                              const char *expression) G_GNUC_NORETURN;
+                              const char *expression);
 
 GLIB_AVAILABLE_IN_2_56
 void g_log_structured_standard (const gchar    *log_domain,
@@ -399,7 +400,7 @@ void g_log_structured_standard (const gchar    *log_domain,
                                        format)
 #endif
 #else   /* no varargs macros */
-static void g_error (const gchar *format, ...) G_GNUC_NORETURN G_ANALYZER_NORETURN;
+static G_NORETURN void g_error (const gchar *format, ...) G_ANALYZER_NORETURN;
 static void g_critical (const gchar *format, ...) G_ANALYZER_NORETURN;
 
 static inline void
@@ -478,7 +479,7 @@ g_debug (const gchar *format,
 #if defined(G_HAVE_ISO_VARARGS) && !G_ANALYZER_ANALYZING
 #define g_warning_once(...) \
   G_STMT_START { \
-    static volatile int G_PASTE (_GWarningOnceBoolean, __LINE__) = 0; \
+    static int G_PASTE (_GWarningOnceBoolean, __LINE__) = 0;  /* (atomic) */ \
     if (g_atomic_int_compare_and_exchange (&G_PASTE (_GWarningOnceBoolean, __LINE__), \
                                            0, 1)) \
       g_warning (__VA_ARGS__); \
@@ -487,7 +488,7 @@ g_debug (const gchar *format,
 #elif defined(G_HAVE_GNUC_VARARGS)  && !G_ANALYZER_ANALYZING
 #define g_warning_once(format...) \
   G_STMT_START { \
-    static volatile int G_PASTE (_GWarningOnceBoolean, __LINE__) = 0; \
+    static int G_PASTE (_GWarningOnceBoolean, __LINE__) = 0;  /* (atomic) */ \
     if (g_atomic_int_compare_and_exchange (&G_PASTE (_GWarningOnceBoolean, __LINE__), \
                                            0, 1)) \
       g_warning (format); \
index 303ec63..50e614e 100644 (file)
@@ -120,7 +120,6 @@ if not meson.is_cross_build() or meson.has_exe_wrapper()
 else
   if (host_system.startswith ('aix') or
       host_system.startswith ('beos') or
-      host_system.startswith ('darwin') or
       host_system.startswith ('irix'))
     gl_cv_func_frexpl_works = false
     gl_cv_func_frexpl_broken_beyond_repair = true
index bb9093a..a351f84 100644 (file)
@@ -1091,7 +1091,7 @@ g_option_context_get_help (GOptionContext *context,
   return g_string_free (string, FALSE);
 }
 
-G_GNUC_NORETURN
+G_NORETURN
 static void
 print_help (GOptionContext *context,
             gboolean        main_help,
index 6be85c7..555a630 100644 (file)
@@ -257,7 +257,7 @@ g_vsprintf (gchar    *string,
  * @n: the maximum number of bytes to produce (including the 
  *     terminating nul character).
  * @format: a standard printf() format string, but notice 
- *          string precision pitfalls][string-precision]
+ *          [string precision pitfalls][string-precision]
  * @args: the list of arguments to insert in the output.
  *
  * A safer form of the standard vsprintf() function. The output is guaranteed
index 52416bb..5e6ddfb 100644 (file)
@@ -203,7 +203,7 @@ G_STATIC_ASSERT (G_REGEX_RAW               == PCRE_UTF8);
 
 struct _GMatchInfo
 {
-  volatile gint ref_count;      /* the ref count */
+  gint ref_count;               /* the ref count (atomic) */
   GRegex *regex;                /* the regex */
   GRegexMatchFlags match_opts;  /* options used at match time on the regex */
   gint matches;                 /* number of matching sub patterns */
@@ -218,7 +218,7 @@ struct _GMatchInfo
 
 struct _GRegex
 {
-  volatile gint ref_count;      /* the ref count for the immutable part */
+  gint ref_count;               /* the ref count for the immutable part (atomic) */
   gchar *pattern;               /* the pattern */
   pcre *pcre_re;                /* compiled form of the pattern */
   GRegexCompileFlags compile_opts;      /* options used at compile time on the pattern */
@@ -1300,7 +1300,7 @@ g_regex_new (const gchar         *pattern,
   pcre *re;
   const gchar *errmsg;
   gboolean optimize = FALSE;
-  static volatile gsize initialised = 0;
+  static gsize initialised = 0;
 
   g_return_val_if_fail (pattern != NULL, NULL);
   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
index b77514a..c858abf 100644 (file)
@@ -1696,12 +1696,19 @@ g_scanner_get_token_i (GScanner *scanner,
       scanner->config->int_2_float)
     {
       *token_p = G_TOKEN_FLOAT;
+
+      /* Have to assign through a temporary variable to avoid undefined behaviour
+       * by copying between potentially-overlapping union members. */
       if (scanner->config->store_int64)
         {
-          value_p->v_float = value_p->v_int64;
+          gint64 temp = value_p->v_int64;
+          value_p->v_float = temp;
         }
       else
-       value_p->v_float = value_p->v_int;
+        {
+          gint temp = value_p->v_int;
+          value_p->v_float = temp;
+        }
     }
   
   errno = 0;
index 96f21d6..9d76dbb 100644 (file)
@@ -1255,9 +1255,9 @@ g_sequence_set (GSequenceIter *iter,
  * g_sequence_get_length:
  * @seq: a #GSequence
  *
- * Returns the length of @seq. Note that this method is O(h) where `h' is the
- * height of the tree. It is thus more efficient to use g_sequence_is_empty()
- * when comparing the length to zero.
+ * Returns the positive length (>= 0) of @seq. Note that this method is
+ * O(h) where `h' is the height of the tree. It is thus more efficient
+ * to use g_sequence_is_empty() when comparing the length to zero.
  *
  * Returns: the length of @seq
  *
index af76629..9b503cf 100644 (file)
@@ -1116,7 +1116,7 @@ write_all (gint fd, gconstpointer vbuf, gsize to_write)
 
 /* This function is called between fork() and exec() and hence must be
  * async-signal-safe (see signal-safety(7)). */
-G_GNUC_NORETURN
+G_NORETURN
 static void
 write_err_and_exit (gint fd, gint msg)
 {
@@ -1273,7 +1273,7 @@ safe_fdwalk (int (*cb)(void *data, int fd), void *data)
   if (getrlimit (RLIMIT_NOFILE, &rl) == 0 && rl.rlim_max != RLIM_INFINITY)
     open_max = rl.rlim_max;
 #endif
-#if defined(__FreeBSD__) || defined(__OpenBSD__)
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
   /* Use sysconf() function provided by the system if it is known to be
    * async-signal safe.
    *
@@ -1282,6 +1282,9 @@ safe_fdwalk (int (*cb)(void *data, int fd), void *data)
    *
    * OpenBSD: sysconf() is included in the list of async-signal safe functions
    * found in https://man.openbsd.org/sigaction.2.
+   * 
+   * Apple: sysconf() is included in the list of async-signal safe functions
+   * found in https://opensource.apple.com/source/xnu/xnu-517.12.7/bsd/man/man2/sigaction.2
    */
   if (open_max < 0)
     open_max = sysconf (_SC_OPEN_MAX);
@@ -1327,12 +1330,17 @@ safe_closefrom (int lowfd)
    * simple wrapper of the fcntl command.
    */
   (void) fcntl (lowfd, F_CLOSEM);
-#elif defined(HAVE_CLOSE_RANGE)
+#else
+
+#if defined(HAVE_CLOSE_RANGE)
   /* close_range() is available in Linux since kernel 5.9, and on FreeBSD at
    * around the same time. It was designed for use in async-signal-safe
-   * situations: https://bugs.python.org/issue38061 */
-  (void) close_range (lowfd, G_MAXUINT);
-#else
+   * situations: https://bugs.python.org/issue38061
+   *
+   * Handle ENOSYS in case it’s supported in libc but not the kernel; if so,
+   * fall back to safe_fdwalk(). */
+  if (close_range (lowfd, G_MAXUINT) != 0 && errno == ENOSYS)
+#endif  /* HAVE_CLOSE_RANGE */
   (void) safe_fdwalk (close_func, GINT_TO_POINTER (lowfd));
 #endif
 }
index 01f4fe3..afedf4f 100644 (file)
@@ -2689,10 +2689,9 @@ g_strjoin (const gchar *separator,
 
 /**
  * g_strstr_len:
- * @haystack: a string
- * @haystack_len: the maximum length of @haystack. Note that -1 is
- *     a valid length, if @haystack is nul-terminated, meaning it will
- *     search through the whole string.
+ * @haystack: a nul-terminated string
+ * @haystack_len: the maximum length of @haystack in bytes. A length of -1
+ *     can be used to mean "search the entire string", like `strstr()`.
  * @needle: the string to search for
  *
  * Searches the string @haystack for the first occurrence
@@ -2796,7 +2795,8 @@ g_strrstr (const gchar *haystack,
 /**
  * g_strrstr_len:
  * @haystack: a nul-terminated string
- * @haystack_len: the maximum length of @haystack
+ * @haystack_len: the maximum length of @haystack in bytes. A length of -1
+ *     can be used to mean "search the entire string", like g_strrstr().
  * @needle: the nul-terminated string to search for
  *
  * Searches the string @haystack for the last occurrence
index 3b03e98..be6b68e 100644 (file)
  */
 
 /**
+ * g_assert_cmpstrv:
+ * @strv1: (nullable): a string array (may be %NULL)
+ * @strv2: (nullable): another string array (may be %NULL)
+ *
+ * Debugging macro to check if two %NULL-terminated string arrays (i.e. 2
+ * #GStrv) are equal. If they are not equal, an error message is logged and the
+ * application is either terminated or the testcase marked as failed.
+ * If both arrays are %NULL, the check passes. If one array is %NULL but the
+ * other is not, an error message is logged.
+ *
+ * The effect of `g_assert_cmpstrv (strv1, strv2)` is the same as
+ * `g_assert_true (g_strv_equal (strv1, strv2))` (if both arrays are not
+ * %NULL). The advantage of this macro is that it can produce a message that
+ * includes how @strv1 and @strv2 are different.
+ *
+ * |[<!-- language="C" -->
+ *   const char *expected[] = { "one", "two", "three", NULL };
+ *   g_assert_cmpstrv (mystrv, expected);
+ * ]|
+ *
+ * Since: 2.68
+ */
+
+/**
  * g_assert_cmpint:
  * @n1: an integer
  * @cmp: The comparison operator to use.
@@ -844,7 +868,11 @@ static guint       test_startup_skip_count = 0;
 static GTimer     *test_user_timer = NULL;
 static double      test_user_stamp = 0;
 static GSList     *test_paths = NULL;
+static gboolean    test_prefix = FALSE;
+static gboolean    test_prefix_extended = FALSE;
 static GSList     *test_paths_skipped = NULL;
+static gboolean    test_prefix_skipped = FALSE;
+static gboolean    test_prefix_extended_skipped = FALSE;
 static GTestSuite *test_suite_root = NULL;
 static int         test_trap_last_status = 0;  /* unmodified platform-specific status */
 static GPid        test_trap_last_pid = 0;
@@ -1175,6 +1203,31 @@ parse_args (gint    *argc_p,
               test_paths = g_slist_prepend (test_paths, argv[i]);
             }
           argv[i] = NULL;
+          if (test_prefix_extended) {
+            printf ("do not mix [-r | --run-prefix] with '-p'\n");
+            exit (1);
+          }
+          test_prefix = TRUE;
+        }
+      else if (strcmp ("-r", argv[i]) == 0 ||
+               strncmp ("-r=", argv[i], 3) == 0 ||
+               strcmp ("--run-prefix", argv[i]) == 0 ||
+               strncmp ("--run-prefix=", argv[i], 13) == 0)
+        {
+            gchar *equal = argv[i] + 2;
+            if (*equal == '=')
+              test_paths = g_slist_prepend (test_paths, equal + 1);
+            else if (i + 1 < argc)
+              {
+                argv[i++] = NULL;
+                test_paths = g_slist_prepend (test_paths, argv[i]);
+              }
+            argv[i] = NULL;
+            if (test_prefix) {
+              printf ("do not mix [-r | --run-prefix] with '-p'\n");
+              exit (1);
+            }
+            test_prefix_extended = TRUE;
         }
       else if (strcmp ("-s", argv[i]) == 0 || strncmp ("-s=", argv[i], 3) == 0)
         {
@@ -1187,6 +1240,31 @@ parse_args (gint    *argc_p,
               test_paths_skipped = g_slist_prepend (test_paths_skipped, argv[i]);
             }
           argv[i] = NULL;
+          if (test_prefix_extended_skipped) {
+            printf ("do not mix [-x | --skip-prefix] with '-s'\n");
+            exit (1);
+          }
+          test_prefix_skipped = TRUE;
+        }
+      else if (strcmp ("-x", argv[i]) == 0 ||
+               strncmp ("-x=", argv[i], 3) == 0 ||
+               strcmp ("--skip-prefix", argv[i]) == 0 ||
+               strncmp ("--skip-prefix=", argv[i], 14) == 0)
+        {
+          gchar *equal = argv[i] + 2;
+          if (*equal == '=')
+            test_paths_skipped = g_slist_prepend (test_paths_skipped, equal + 1);
+          else if (i + 1 < argc)
+            {
+              argv[i++] = NULL;
+              test_paths_skipped = g_slist_prepend (test_paths_skipped, argv[i]);
+            }
+          argv[i] = NULL;
+          if (test_prefix_skipped) {
+            printf ("do not mix [-x | --skip-prefix] with '-s'\n");
+            exit (1);
+          }
+          test_prefix_extended_skipped = TRUE;
         }
       else if (strcmp ("-m", argv[i]) == 0 || strncmp ("-m=", argv[i], 3) == 0)
         {
@@ -1262,6 +1340,13 @@ parse_args (gint    *argc_p,
                   "  -m {undefined|no-undefined}    Execute tests according to mode\n"
                   "  -p TESTPATH                    Only start test cases matching TESTPATH\n"
                   "  -s TESTPATH                    Skip all tests matching TESTPATH\n"
+                  "  [-r | --run-prefix] PREFIX     Only start test cases (or suites) matching PREFIX (incompatible with -p).\n"
+                  "                                 Unlike the -p option (which only goes one level deep), this option would \n"
+                  "                                 run all tests path that have PREFIX at the beginning of their name.\n"
+                  "                                 Note that the prefix used should be a valid test path (and not a simple prefix).\n"
+                  "  [-x | --skip-prefix] PREFIX    Skip all tests matching PREFIX (incompatible with -s)\n"
+                  "                                 Unlike the -s option (which only skips the exact TESTPATH), this option will \n"
+                  "                                 skip all the tests that begins with PREFIX).\n"
                   "  --seed=SEEDSTRING              Start tests with random seed SEEDSTRING\n"
                   "  --debug-log                    debug test logging output\n"
                   "  -q, --quiet                    Run tests quietly\n"
@@ -1297,8 +1382,8 @@ rm_rf (const gchar *path)
   dir = g_dir_open (path, 0, NULL);
   if (dir == NULL)
     {
-      /* Assume it’s a file. */
-      g_remove (path);
+      /* Assume it’s a file. Ignore failure. */
+      (void) g_remove (path);
       return;
     }
 
@@ -2606,6 +2691,22 @@ g_test_queue_destroy (GDestroyNotify destroy_func,
   test_destroy_queue = dentry;
 }
 
+static gint
+test_has_prefix (gconstpointer a,
+                 gconstpointer b)
+{
+    const gchar *test_path_skipped_local = (const gchar *)a;
+    const gchar* test_run_name_local = (const gchar*)b;
+    if (test_prefix_extended_skipped)
+      {
+        /* If both are null, we consider that it doesn't match */
+        if (!test_path_skipped_local || !test_run_name_local)
+          return FALSE;
+        return strncmp (test_run_name_local, test_path_skipped_local, strlen (test_path_skipped_local));
+      }
+    return g_strcmp0 (test_run_name_local, test_path_skipped_local);
+}
+
 static gboolean
 test_case_run (GTestCase *tc)
 {
@@ -2633,7 +2734,7 @@ test_case_run (GTestCase *tc)
       test_run_success = G_TEST_RUN_SUCCESS;
       g_clear_pointer (&test_run_msg, g_free);
       g_test_log_set_fatal_handler (NULL, NULL);
-      if (test_paths_skipped && g_slist_find_custom (test_paths_skipped, test_run_name, (GCompareFunc)g_strcmp0))
+      if (test_paths_skipped && g_slist_find_custom (test_paths_skipped, test_run_name, (GCompareFunc)test_has_prefix))
         g_test_skip ("by request (-s option)");
       else
         {
@@ -2751,8 +2852,15 @@ g_test_run_suite_internal (GTestSuite *suite,
       GTestSuite *ts = iter->data;
 
       test_run_name = g_build_path ("/", old_name, ts->name, NULL);
-      if (!path || path_has_prefix (path, test_run_name))
+      if (test_prefix_extended) {
+        if (!path || path_has_prefix (test_run_name, path))
+          n_bad += g_test_run_suite_internal (ts, test_run_name);
+        else if (!path || path_has_prefix (path, test_run_name))
+          n_bad += g_test_run_suite_internal (ts, path);
+      } else if (!path || path_has_prefix (path, test_run_name)) {
         n_bad += g_test_run_suite_internal (ts, path);
+      }
+
       g_free (test_run_name);
     }
 
@@ -3019,6 +3127,31 @@ g_assertion_message_cmpstr (const char     *domain,
 }
 
 void
+g_assertion_message_cmpstrv (const char         *domain,
+                             const char         *file,
+                             int                 line,
+                             const char         *func,
+                             const char         *expr,
+                             const char * const *arg1,
+                             const char * const *arg2,
+                             gsize               first_wrong_idx)
+{
+  const char *s1 = arg1[first_wrong_idx], *s2 = arg2[first_wrong_idx];
+  char *a1, *a2, *s, *t1 = NULL, *t2 = NULL;
+
+  a1 = g_strconcat ("\"", t1 = g_strescape (s1, NULL), "\"", NULL);
+  a2 = g_strconcat ("\"", t2 = g_strescape (s2, NULL), "\"", NULL);
+  g_free (t1);
+  g_free (t2);
+  s = g_strdup_printf ("assertion failed (%s): first differing element at index %" G_GSIZE_FORMAT ": %s does not equal %s",
+                       expr, first_wrong_idx, a1, a2);
+  g_free (a1);
+  g_free (a2);
+  g_assertion_message (domain, file, line, func, s);
+  g_free (s);
+}
+
+void
 g_assertion_message_error (const char     *domain,
                           const char     *file,
                           int             line,
index 10b65c1..e93c490 100644 (file)
@@ -111,6 +111,51 @@ typedef void (*GTestFixtureFunc) (gpointer      fixture,
       } \
   } \
   G_STMT_END
+#define g_assert_cmpstrv(strv1, strv2) \
+  G_STMT_START \
+  { \
+    const char * const *__strv1 = (const char * const *) (strv1); \
+    const char * const *__strv2 = (const char * const *) (strv2); \
+    if (!__strv1 || !__strv2) \
+      { \
+        if (__strv1) \
+          { \
+            g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+                                 "assertion failed (" #strv1 " == " #strv2 "): " #strv2 " is NULL, but " #strv1 " is not"); \
+          } \
+        else if (__strv2) \
+          { \
+            g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+                                 "assertion failed (" #strv1 " == " #strv2 "): " #strv1 " is NULL, but " #strv2 " is not"); \
+          } \
+      } \
+    else \
+      { \
+        guint __l1 = g_strv_length ((char **) __strv1); \
+        guint __l2 = g_strv_length ((char **) __strv2); \
+        if (__l1 != __l2) \
+          { \
+            char *__msg; \
+            __msg = g_strdup_printf ("assertion failed (" #strv1 " == " #strv2 "): length %u does not equal length %u", __l1, __l2); \
+            g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, __msg); \
+            g_free (__msg); \
+          } \
+        else \
+          { \
+            guint __i; \
+            for (__i = 0; __i < __l1; __i++) \
+              { \
+                if (g_strcmp0 (__strv1[__i], __strv2[__i]) != 0) \
+                  { \
+                    g_assertion_message_cmpstrv (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+                                                 #strv1 " == " #strv2, \
+                                                 __strv1, __strv2, __i); \
+                  } \
+              } \
+          } \
+      } \
+  } \
+  G_STMT_END
 #define g_assert_no_errno(expr)         G_STMT_START { \
                                              int __ret, __errsv; \
                                              errno = 0; \
@@ -469,11 +514,12 @@ void    g_assertion_message             (const char     *domain,
                                          const char     *func,
                                          const char     *message) G_ANALYZER_NORETURN;
 GLIB_AVAILABLE_IN_ALL
+G_NORETURN
 void    g_assertion_message_expr        (const char     *domain,
                                          const char     *file,
                                          int             line,
                                          const char     *func,
-                                         const char     *expr) G_GNUC_NORETURN;
+                                         const char     *expr);
 GLIB_AVAILABLE_IN_ALL
 void    g_assertion_message_cmpstr      (const char     *domain,
                                          const char     *file,
@@ -483,6 +529,16 @@ void    g_assertion_message_cmpstr      (const char     *domain,
                                          const char     *arg1,
                                          const char     *cmp,
                                          const char     *arg2) G_ANALYZER_NORETURN;
+
+GLIB_AVAILABLE_IN_2_68
+void    g_assertion_message_cmpstrv     (const char         *domain,
+                                         const char         *file,
+                                         int                 line,
+                                         const char         *func,
+                                         const char         *expr,
+                                         const char * const *arg1,
+                                         const char * const *arg2,
+                                         gsize               first_wrong_idx) G_ANALYZER_NORETURN;
 GLIB_AVAILABLE_IN_ALL
 void    g_assertion_message_cmpnum      (const char     *domain,
                                          const char     *file,
index 0c37dc6..20aca6f 100644 (file)
@@ -301,7 +301,7 @@ struct _GPrivateDestructor
   GPrivateDestructor *next;
 };
 
-static GPrivateDestructor * volatile g_private_destructors;
+static GPrivateDestructor *g_private_destructors;  /* (atomic) prepend-only */
 static CRITICAL_SECTION g_private_lock;
 
 static DWORD
@@ -329,7 +329,7 @@ g_private_get_impl (GPrivate *key)
                 g_thread_abort (errno, "malloc");
               destructor->index = impl;
               destructor->notify = key->notify;
-              destructor->next = g_private_destructors;
+              destructor->next = g_atomic_pointer_get (&g_private_destructors);
 
               /* We need to do an atomic store due to the unlocked
                * access to the destructor list from the thread exit
@@ -337,13 +337,14 @@ g_private_get_impl (GPrivate *key)
                *
                * It can double as a sanity check...
                */
-              if (InterlockedCompareExchangePointer (&g_private_destructors, destructor,
-                                                     destructor->next) != destructor->next)
+              if (!g_atomic_pointer_compare_and_exchange (&g_private_destructors,
+                                                          destructor->next,
+                                                          destructor))
                 g_thread_abort (0, "g_private_get_impl(1)");
             }
 
           /* Ditto, due to the unlocked access on the fast path */
-          if (InterlockedCompareExchangePointer (&key->p, impl, NULL) != NULL)
+          if (!g_atomic_pointer_compare_and_exchange (&key->p, NULL, impl))
             g_thread_abort (0, "g_private_get_impl(2)");
         }
       LeaveCriticalSection (&g_private_lock);
@@ -635,7 +636,7 @@ g_thread_win32_thread_detach (void)
        */
       dtors_called = FALSE;
 
-      for (dtor = g_private_destructors; dtor; dtor = dtor->next)
+      for (dtor = g_atomic_pointer_get (&g_private_destructors); dtor; dtor = dtor->next)
         {
           gpointer value;
 
index 53f3a08..29216d7 100644 (file)
@@ -513,7 +513,7 @@ static GMutex    g_once_mutex;
 static GCond     g_once_cond;
 static GSList   *g_once_init_list = NULL;
 
-static volatile guint g_thread_n_created_counter = 0;
+static guint g_thread_n_created_counter = 0;  /* (atomic) */
 
 static void g_thread_cleanup (gpointer data);
 static GPrivate     g_thread_specific_private = G_PRIVATE_INIT (g_thread_cleanup);
@@ -686,6 +686,9 @@ g_once_impl (GOnce       *once,
  *   // use initialization_value here
  * ]|
  *
+ * While @location has a `volatile` qualifier, this is a historical artifact and
+ * the pointer passed to it should not be `volatile`.
+ *
  * Returns: %TRUE if the initialization section should be entered,
  *     %FALSE and blocks otherwise
  *
@@ -694,7 +697,7 @@ g_once_impl (GOnce       *once,
 gboolean
 (g_once_init_enter) (volatile void *location)
 {
-  volatile gsize *value_location = location;
+  gsize *value_location = (gsize *) location;
   gboolean need_init = FALSE;
   g_mutex_lock (&g_once_mutex);
   if (g_atomic_pointer_get (value_location) == 0)
@@ -725,13 +728,16 @@ gboolean
  * releases concurrent threads blocking in g_once_init_enter() on this
  * initialization variable.
  *
+ * While @location has a `volatile` qualifier, this is a historical artifact and
+ * the pointer passed to it should not be `volatile`.
+ *
  * Since: 2.14
  */
 void
 (g_once_init_leave) (volatile void *location,
                      gsize          result)
 {
-  volatile gsize *value_location = location;
+  gsize *value_location = (gsize *) location;
 
   g_return_if_fail (g_atomic_pointer_get (value_location) == 0);
   g_return_if_fail (result != 0);
index 9651013..4b43242 100644 (file)
@@ -1604,7 +1604,39 @@ parse_footertz (const gchar *footer, size_t footerlen)
  * g_time_zone_new:
  * @identifier: (nullable): a timezone identifier
  *
- * Creates a #GTimeZone corresponding to @identifier.
+ * A version of g_time_zone_new_identifier() which returns the UTC time zone
+ * if @identifier could not be parsed or loaded.
+ *
+ * If you need to check whether @identifier was loaded successfully, use
+ * g_time_zone_new_identifier().
+ *
+ * Returns: (transfer full) (not nullable): the requested timezone
+ * Deprecated: 2.68: Use g_time_zone_new_identifier() instead, as it provides
+ *     error reporting. Change your code to handle a potentially %NULL return
+ *     value.
+ *
+ * Since: 2.26
+ **/
+GTimeZone *
+g_time_zone_new (const gchar *identifier)
+{
+  GTimeZone *tz = g_time_zone_new_identifier (identifier);
+
+  /* Always fall back to UTC. */
+  if (tz == NULL)
+    tz = g_time_zone_new_utc ();
+
+  g_assert (tz != NULL);
+
+  return g_steal_pointer (&tz);
+}
+
+/**
+ * g_time_zone_new_identifier:
+ * @identifier: (nullable): a timezone identifier
+ *
+ * Creates a #GTimeZone corresponding to @identifier. If @identifier cannot be
+ * parsed or loaded, %NULL is returned.
  *
  * @identifier can either be an RFC3339/ISO 8601 time offset or
  * something that would pass as a valid value for the `TZ` environment
@@ -1669,12 +1701,12 @@ parse_footertz (const gchar *footer, size_t footerlen)
  * You should release the return value by calling g_time_zone_unref()
  * when you are done with it.
  *
- * Returns: the requested timezone
- *
- * Since: 2.26
- **/
+ * Returns: (transfer full) (nullable): the requested timezone, or %NULL on
+ *     failure
+ * Since: 2.68
+ */
 GTimeZone *
-g_time_zone_new (const gchar *identifier)
+g_time_zone_new_identifier (const gchar *identifier)
 {
   GTimeZone *tz = NULL;
   TimeZoneRule *rules;
@@ -1788,24 +1820,31 @@ g_time_zone_new (const gchar *identifier)
 
   g_free (resolved_identifier);
 
-  /* Always fall back to UTC. */
+  /* Failed to load the timezone. */
   if (tz->t_info == NULL)
-    zone_for_constant_offset (tz, "UTC");
+    {
+      g_slice_free (GTimeZone, tz);
+
+      if (identifier)
+        G_UNLOCK (time_zones);
+      else
+        G_UNLOCK (tz_default);
+
+      return NULL;
+    }
 
   g_assert (tz->name != NULL);
   g_assert (tz->t_info != NULL);
 
-  if (tz->t_info != NULL)
+  if (identifier)
+    g_hash_table_insert (time_zones, tz->name, tz);
+  else if (tz->name)
     {
-      if (identifier)
-        g_hash_table_insert (time_zones, tz->name, tz);
-      else if (tz->name)
-        {
-          /* Caching reference */
-          g_atomic_int_inc (&tz->ref_count);
-          tz_default = tz;
-        }
+      /* Caching reference */
+      g_atomic_int_inc (&tz->ref_count);
+      tz_default = tz;
     }
+
   g_atomic_int_inc (&tz->ref_count);
 
   if (identifier)
@@ -1839,7 +1878,8 @@ g_time_zone_new_utc (void)
 
   if (g_once_init_enter (&initialised))
     {
-      utc = g_time_zone_new ("UTC");
+      utc = g_time_zone_new_identifier ("UTC");
+      g_assert (utc != NULL);
       g_once_init_leave (&initialised, TRUE);
     }
 
@@ -1876,7 +1916,9 @@ g_time_zone_new_local (void)
     g_clear_pointer (&tz_local, g_time_zone_unref);
 
   if (tz_local == NULL)
-    tz_local = g_time_zone_new (tzenv);
+    tz_local = g_time_zone_new_identifier (tzenv);
+  if (tz_local == NULL)
+    tz_local = g_time_zone_new_utc ();
 
   tz = g_time_zone_ref (tz_local);
 
@@ -1907,13 +1949,15 @@ g_time_zone_new_offset (gint32 seconds)
   /* Seemingly, we should be using @seconds directly to set the
    * #TransitionInfo.gmt_offset to avoid all this string building and parsing.
    * However, we always need to set the #GTimeZone.name to a constructed
-   * string anyway, so we might as well reuse its code. */
+   * string anyway, so we might as well reuse its code.
+   * g_time_zone_new_identifier() should never fail in this situation. */
   identifier = g_strdup_printf ("%c%02u:%02u:%02u",
                                 (seconds >= 0) ? '+' : '-',
                                 (ABS (seconds) / 60) / 60,
                                 (ABS (seconds) / 60) % 60,
                                 ABS (seconds) % 60);
-  tz = g_time_zone_new (identifier);
+  tz = g_time_zone_new_identifier (identifier);
+  g_assert (tz != NULL);
   g_free (identifier);
 
   g_assert (g_time_zone_get_offset (tz, 0) == seconds);
index 4e8b10a..d68a76d 100644 (file)
@@ -24,6 +24,7 @@
 #error "Only <glib.h> can be included directly."
 #endif
 
+#include <glib/gerror.h>
 #include <glib/gtypes.h>
 
 G_BEGIN_DECLS
@@ -52,8 +53,10 @@ typedef enum
   G_TIME_TYPE_UNIVERSAL
 } GTimeType;
 
-GLIB_AVAILABLE_IN_ALL
+GLIB_DEPRECATED_IN_2_68_FOR (g_time_zone_new_identifier)
 GTimeZone *             g_time_zone_new                                 (const gchar *identifier);
+GLIB_AVAILABLE_IN_2_68
+GTimeZone *             g_time_zone_new_identifier                      (const gchar *identifier);
 GLIB_AVAILABLE_IN_ALL
 GTimeZone *             g_time_zone_new_utc                             (void);
 GLIB_AVAILABLE_IN_ALL
index 78bf04a..31082c6 100644 (file)
@@ -23,8 +23,7 @@
 #include <sysprof-capture.h>
 #endif
 
-#include "gmem.h"
-#include "gmacros.h"
+#include "glib.h"
 
 G_BEGIN_DECLS
 
@@ -67,4 +66,15 @@ void (g_trace_mark) (gint64       begin_time_nsec,
 #endif
 #endif
 
+guint   (g_trace_define_int64_counter) (const char *group,
+                                        const char *name,
+                                        const char *description);
+void    (g_trace_set_int64_counter)    (guint       id,
+                                        gint64      value);
+
+#ifndef HAVE_SYSPROF
+#define g_trace_define_int64_counter(g, n, d) ((guint) -1)
+#define g_trace_set_int64_counter(i,v)
+#endif
+
 G_END_DECLS
index 2972677..c3c3653 100644 (file)
@@ -96,3 +96,82 @@ void
   va_end (args);
 #endif  /* HAVE_SYSPROF */
 }
+
+/*
+ * g_trace_define_int64_counter:
+ * @group: name of the group for categorising this counter
+ * @name: name of the counter
+ * @description: description for the counter
+ *
+ * Defines a new counter with integer values.
+ *
+ * The name should be unique within all counters defined with
+ * the same @group. The description will be shown in the sysprof UI.
+ *
+ * To add entries for this counter to a trace, use
+ * g_trace_set_int64_counter().
+ *
+ * Returns: ID of the counter, for use with g_trace_set_int64_counter(),
+ *     guaranteed to never be zero
+ *
+ * Since: 2.68
+ */
+guint
+(g_trace_define_int64_counter) (const char *group,
+                                const char *name,
+                                const char *description)
+{
+#ifdef HAVE_SYSPROF
+  SysprofCaptureCounter counter;
+
+  counter.id = sysprof_collector_request_counters (1);
+
+  /* sysprof not enabled? */
+  if (counter.id == 0)
+    return (guint) -1;
+
+  counter.type = SYSPROF_CAPTURE_COUNTER_INT64;
+  counter.value.v64 = 0;
+  g_strlcpy (counter.category, group, sizeof counter.category);
+  g_strlcpy (counter.name, name, sizeof counter.name);
+  g_strlcpy (counter.description, description, sizeof counter.description);
+
+  sysprof_collector_define_counters (&counter, 1);
+
+  g_assert (counter.id != 0);
+
+  return counter.id;
+#else
+  return (guint) -1;
+#endif
+}
+
+/*
+ * g_trace_set_int64_counter:
+ * @id: ID of the counter
+ * @val: the value to set the counter to
+ *
+ * Adds a counter value to a trace.
+ *
+ * The ID must be obtained via g_trace_define_int64_counter()
+ * before using this function.
+ *
+ * Since: 2.68
+ */
+void
+(g_trace_set_int64_counter) (guint  id,
+                             gint64 val)
+{
+#ifdef HAVE_SYSPROF
+  SysprofCaptureCounterValue value;
+
+  g_return_if_fail (id != 0);
+
+  /* Ignore setting the counter if we failed to define it in the first place. */
+  if (id == (guint) -1)
+    return;
+
+  value.v64 = val;
+  sysprof_collector_set_counters (&id, &value, 1);
+#endif
+}
index 23c5a12..2c48255 100644 (file)
@@ -550,8 +550,8 @@ struct _GTimeVal
   glong tv_usec;
 } GLIB_DEPRECATED_TYPE_IN_2_62_FOR(GDateTime);
 
-typedef gint            grefcount;
-typedef volatile gint   gatomicrefcount;
+typedef gint grefcount;
+typedef gint gatomicrefcount;  /* should be accessed only using atomics */
 
 G_END_DECLS
 
index 2f42a49..571cf10 100644 (file)
  *
  * Note that there is no `g_uri_equal ()` function, because comparing
  * URIs usefully requires scheme-specific knowledge that #GUri does
- * not have. For example, `http://example.com/` and
- * `http://EXAMPLE.COM:80` have exactly the same meaning according
- * to the HTTP specification, and `data:,foo` and
- * `data:;base64,Zm9v` resolve to the same thing according to the
- * `data:` URI specification.
+ * not have. #GUri can help with normalization if you use the various
+ * encoded #GUriFlags as well as %G_URI_FLAGS_SCHEME_NORMALIZE however
+ * it is not comprehensive.
+ * For example, `data:,foo` and `data:;base64,Zm9v` resolve to the same
+ * thing according to the `data:` URI specification which GLib does not
+ * handle.
  *
  * Since: 2.66
  */
@@ -289,15 +290,16 @@ uri_decoder (gchar       **out,
              GUriError     parse_error,
              GError      **error)
 {
-  gchar *decoded, *d, c;
+  gchar c;
+  GString *decoded;
   const gchar *invalid, *s, *end;
   gssize len;
 
   if (!(flags & G_URI_FLAGS_ENCODED))
     just_normalize = FALSE;
 
-  decoded = g_malloc (length + 1);
-  for (s = start, end = s + length, d = decoded; s < end; s++)
+  decoded = g_string_sized_new (length + 1);
+  for (s = start, end = s + length; s < end; s++)
     {
       if (*s == '%')
         {
@@ -311,7 +313,7 @@ uri_decoder (gchar       **out,
                   g_set_error_literal (error, G_URI_ERROR, parse_error,
                                        /* xgettext: no-c-format */
                                        _("Invalid %-encoding in URI"));
-                  g_free (decoded);
+                  g_string_free (decoded, TRUE);
                   return -1;
                 }
 
@@ -319,7 +321,7 @@ uri_decoder (gchar       **out,
                * fix it to "%25", since that might change the way that
                * the URI's owner would interpret it.
                */
-              *d++ = *s;
+              g_string_append_c (decoded, *s);
               continue;
             }
 
@@ -328,43 +330,49 @@ uri_decoder (gchar       **out,
             {
               g_set_error_literal (error, G_URI_ERROR, parse_error,
                                    _("Illegal character in URI"));
-              g_free (decoded);
+              g_string_free (decoded, TRUE);
               return -1;
             }
           if (just_normalize && !g_uri_char_is_unreserved (c))
             {
-              /* Leave the % sequence there. */
-              *d++ = *s;
+              /* Leave the % sequence there but normalize it. */
+              g_string_append_c (decoded, *s);
+              g_string_append_c (decoded, g_ascii_toupper (s[1]));
+              g_string_append_c (decoded, g_ascii_toupper (s[2]));
+              s += 2;
             }
           else
             {
-              *d++ = c;
+              g_string_append_c (decoded, c);
               s += 2;
             }
         }
       else if (www_form && *s == '+')
-        *d++ = ' ';
+        g_string_append_c (decoded, ' ');
+      /* Normalize any illegal characters. */
+      else if (just_normalize && (!g_ascii_isgraph (*s)))
+        g_string_append_printf (decoded, "%%%02X", (guchar)*s);
       else
-        *d++ = *s;
+        g_string_append_c (decoded, *s);
     }
-  *d = '\0';
 
-  len = d - decoded;
+  len = decoded->len;
   g_assert (len >= 0);
 
   if (!(flags & G_URI_FLAGS_ENCODED) &&
-      !g_utf8_validate (decoded, len, &invalid))
+      !g_utf8_validate (decoded->str, len, &invalid))
     {
       g_set_error_literal (error, G_URI_ERROR, parse_error,
                            _("Non-UTF-8 characters in URI"));
-      g_free (decoded);
+      g_string_free (decoded, TRUE);
       return -1;
     }
 
   if (out)
-    *out = g_steal_pointer (&decoded);
+    *out = g_string_free (decoded, FALSE);
+  else
+    g_string_free (decoded, TRUE);
 
-  g_free (decoded);
   return len;
 }
 
@@ -596,9 +604,21 @@ parse_host (const gchar  *start,
     }
 
   if (g_hostname_is_non_ascii (decoded))
-    host = g_hostname_to_ascii (decoded);
+    {
+      host = g_hostname_to_ascii (decoded);
+      if (host == NULL)
+        {
+          g_free (decoded);
+          g_set_error (error, G_URI_ERROR, G_URI_ERROR_BAD_HOST,
+                       _("Illegal internationalized hostname ‘%.*s’ in URI"),
+                       (gint) length, start);
+          return FALSE;
+        }
+    }
   else
-    host = g_steal_pointer (&decoded);
+    {
+      host = g_steal_pointer (&decoded);
+    }
 
  ok:
   if (out)
@@ -741,6 +761,67 @@ uri_cleanup (const gchar *uri_string)
 }
 
 static gboolean
+should_normalize_empty_path (const char *scheme)
+{
+  const char * const schemes[] = { "https", "http", "wss", "ws" };
+  gsize i;
+  for (i = 0; i < G_N_ELEMENTS (schemes); ++i)
+    {
+      if (!strcmp (schemes[i], scheme))
+        return TRUE;
+    }
+  return FALSE;
+}
+
+static int
+normalize_port (const char *scheme,
+                int         port)
+{
+  const char *default_schemes[3] = { NULL };
+  int i;
+
+  switch (port)
+    {
+    case 21:
+      default_schemes[0] = "ftp";
+      break;
+    case 80:
+      default_schemes[0] = "http";
+      default_schemes[1] = "ws";
+      break;
+    case 443:
+      default_schemes[0] = "https";
+      default_schemes[1] = "wss";
+      break;
+    default:
+      break;
+    }
+
+  for (i = 0; default_schemes[i]; ++i)
+    {
+      if (!strcmp (scheme, default_schemes[i]))
+        return -1;
+    }
+
+  return port;
+}
+
+static int
+default_scheme_port (const char *scheme)
+{
+  if (strcmp (scheme, "http") == 0 || strcmp (scheme, "ws") == 0)
+    return 80;
+
+  if (strcmp (scheme, "https") == 0 || strcmp (scheme, "wss") == 0)
+    return 443;
+
+  if (strcmp (scheme, "ftp") == 0)
+    return 21;
+
+  return -1;
+}
+
+static gboolean
 g_uri_split_internal (const gchar  *uri_string,
                       GUriFlags     flags,
                       gchar       **scheme,
@@ -758,6 +839,7 @@ g_uri_split_internal (const gchar  *uri_string,
   const gchar *end, *colon, *at, *path_start, *semi, *question;
   const gchar *p, *bracket, *hostend;
   gchar *cleaned_uri_string = NULL;
+  gchar *normalized_scheme = NULL;
 
   if (scheme)
     *scheme = NULL;
@@ -795,8 +877,9 @@ g_uri_split_internal (const gchar  *uri_string,
 
   if (p > uri_string && *p == ':')
     {
+      normalized_scheme = g_ascii_strdown (uri_string, p - uri_string);
       if (scheme)
-        *scheme = g_ascii_strdown (uri_string, p - uri_string);
+        *scheme = g_steal_pointer (&normalized_scheme);
       p++;
     }
   else
@@ -922,6 +1005,22 @@ g_uri_split_internal (const gchar  *uri_string,
                       G_URI_ERROR_BAD_PATH, error))
     goto fail;
 
+  /* Scheme-based normalization */
+  if (flags & G_URI_FLAGS_SCHEME_NORMALIZE && ((scheme && *scheme) || normalized_scheme))
+    {
+      const char *scheme_str = scheme && *scheme ? *scheme : normalized_scheme;
+
+      if (should_normalize_empty_path (scheme_str) && path && !**path)
+        {
+          g_free (*path);
+          *path = g_strdup ("/");
+        }
+
+      if (port && *port == -1)
+        *port = default_scheme_port (scheme_str);
+    }
+
+  g_free (normalized_scheme);
   g_free (cleaned_uri_string);
   return TRUE;
 
@@ -941,6 +1040,7 @@ g_uri_split_internal (const gchar  *uri_string,
   if (fragment)
     g_clear_pointer (fragment, g_free);
 
+  g_free (normalized_scheme);
   g_free (cleaned_uri_string);
   return FALSE;
 }
@@ -1394,6 +1494,19 @@ g_uri_parse_relative (GUri         *base_uri,
               uri->port = base_uri->port;
             }
         }
+
+      /* Scheme normalization couldn't have been done earlier
+       * as the relative URI may not have had a scheme */
+      if (flags & G_URI_FLAGS_SCHEME_NORMALIZE)
+        {
+          if (should_normalize_empty_path (uri->scheme) && !*uri->path)
+            {
+              g_free (uri->path);
+              uri->path = g_strdup ("/");
+            }
+
+          uri->port = normalize_port (uri->scheme, uri->port);
+        }
     }
 
   return g_steal_pointer (&uri);
@@ -1482,6 +1595,7 @@ g_uri_join_internal (GUriFlags    flags,
 {
   gboolean encoded = (flags & G_URI_FLAGS_ENCODED);
   GString *str;
+  char *normalized_scheme = NULL;
 
   /* Restrictions on path prefixes. See:
    * https://tools.ietf.org/html/rfc3986#section-3
@@ -1494,6 +1608,9 @@ g_uri_join_internal (GUriFlags    flags,
   if (scheme)
     g_string_append_c (str, ':');
 
+  if (flags & G_URI_FLAGS_SCHEME_NORMALIZE && scheme && ((host && port != -1) || path[0] == '\0'))
+    normalized_scheme = g_ascii_strdown (scheme, -1);
+
   if (host)
     {
       g_string_append (str, "//");
@@ -1554,15 +1671,19 @@ g_uri_join_internal (GUriFlags    flags,
             g_string_append_uri_escaped (str, host, HOST_ALLOWED_CHARS, TRUE);
         }
 
-      if (port != -1)
+      if (port != -1 && (!normalized_scheme || normalize_port (normalized_scheme, port) != -1))
         g_string_append_printf (str, ":%d", port);
     }
 
-  if (encoded || flags & G_URI_FLAGS_ENCODED_PATH)
+  if (path[0] == '\0' && normalized_scheme && should_normalize_empty_path (normalized_scheme))
+    g_string_append (str, "/");
+  else if (encoded || flags & G_URI_FLAGS_ENCODED_PATH)
     g_string_append (str, path);
   else
     g_string_append_uri_escaped (str, path, PATH_ALLOWED_CHARS, TRUE);
 
+  g_free (normalized_scheme);
+
   if (query)
     {
       g_string_append_c (str, '?');
@@ -2346,6 +2467,9 @@ g_uri_get_port (GUri *uri)
 {
   g_return_val_if_fail (uri != NULL, -1);
 
+  if (uri->port == -1 && uri->flags & G_URI_FLAGS_SCHEME_NORMALIZE)
+    return default_scheme_port (uri->scheme);
+
   return uri->port;
 }
 
index 3a7bb5c..b6a4fd0 100644 (file)
@@ -62,6 +62,10 @@ void         g_uri_unref            (GUri *uri);
  * @G_URI_FLAGS_ENCODED_PATH: Same as %G_URI_FLAGS_ENCODED, for the path only.
  * @G_URI_FLAGS_ENCODED_FRAGMENT: Same as %G_URI_FLAGS_ENCODED, for the
  *     fragment only.
+ * @G_URI_FLAGS_SCHEME_NORMALIZE: A scheme-based normalization will be applied.
+ *     For example, when parsing an HTTP URI changing omitted path to `/` and
+ *     omitted port to `80`; and when building a URI, changing empty path to `/`
+ *     and default port `80`). This only supports a subset of known schemes. (Since: 2.68)
  *
  * Flags that describe a URI.
  *
@@ -83,6 +87,7 @@ typedef enum {
   G_URI_FLAGS_ENCODED_QUERY   = 1 << 5,
   G_URI_FLAGS_ENCODED_PATH    = 1 << 6,
   G_URI_FLAGS_ENCODED_FRAGMENT = 1 << 7,
+  G_URI_FLAGS_SCHEME_NORMALIZE = 1 << 8,
 } GUriFlags;
 
 GLIB_AVAILABLE_IN_2_66
index 8a927d0..f8a6049 100644 (file)
@@ -434,7 +434,7 @@ g_bit_storage_impl (gulong number)
 #  define g_abort() abort ()
 #else
 GLIB_AVAILABLE_IN_2_50
-void g_abort (void) G_GNUC_NORETURN G_ANALYZER_NORETURN;
+G_NORETURN void g_abort (void) G_ANALYZER_NORETURN;
 #endif
 #endif
 
index 83e9d85..06f419f 100644 (file)
@@ -1666,7 +1666,7 @@ g_variant_serialiser_is_string (gconstpointer data,
  *
  * Performs the checks for being a valid string.
  *
- * Also, ensures that @data is a valid DBus object path, as per the D-Bus
+ * Also, ensures that @data is a valid D-Bus object path, as per the D-Bus
  * specification.
  */
 gboolean
index 6b460d8..039f355 100644 (file)
@@ -49,7 +49,7 @@
  * its type nor its content can be modified further.
  *
  * GVariant is useful whenever data needs to be serialized, for example when
- * sending method parameters in DBus, or when saving settings using GSettings.
+ * sending method parameters in D-Bus, or when saving settings using GSettings.
  *
  * When creating a new #GVariant, you pass the data you want to store in it
  * along with a string representing the type of data you wish to pass to it.
index c46f1a2..831fed4 100644 (file)
@@ -62,7 +62,7 @@
  *
  * Just as in D-Bus, GVariant types are described with strings ("type
  * strings").  Subject to the differences mentioned above, these strings
- * are of the same form as those found in DBus.  Note, however: D-Bus
+ * are of the same form as those found in D-Bus.  Note, however: D-Bus
  * always works in terms of messages and therefore individual type
  * strings appear nowhere in its interface.  Instead, "signatures"
  * are a concatenation of the strings of the type of each argument in a
index aaf40a2..583a31b 100644 (file)
@@ -8,7 +8,7 @@ if not use_system_pcre
 endif
 
 # libsysprof-capture support
-libsysprof_capture_dep = dependency('sysprof-capture-4',
+libsysprof_capture_dep = dependency('sysprof-capture-4', version: '>= 3.38.0',
   required: get_option('sysprof'),
   default_options: [
     'enable_examples=false',
index ef54f14..26ab2ed 100644 (file)
@@ -25,7 +25,7 @@ static GMutex *mutex;
 static GCond *cond;
 static guint i;
 
-static volatile gint freed = 0;
+static gint freed = 0;  /* (atomic) */
 
 static void
 notify (gpointer p)
@@ -63,7 +63,7 @@ testcase (void)
       GThread *t1;
 
       g_static_private_init (&sp);
-      freed = 0;
+      g_atomic_int_set (&freed, 0);
 
       t1 = g_thread_create (thread_func, NULL, TRUE, NULL);
       g_assert (t1 != NULL);
index 6b6cc7f..14e6e45 100644 (file)
@@ -94,6 +94,9 @@ test_types (void)
   res = g_atomic_pointer_compare_and_exchange (&vp_str, NULL, str);
   g_assert_true (res);
 
+  /* Note that atomic variables should almost certainly not be marked as
+   * `volatile` — see http://isvolatileusefulwiththreads.in/c/. This test exists
+   * to make sure that we don’t warn when built against older third party code. */
   g_atomic_pointer_set (&vp_str_vol, NULL);
   res = g_atomic_pointer_compare_and_exchange (&vp_str_vol, NULL, str);
   g_assert_true (res);
@@ -210,6 +213,9 @@ G_GNUC_END_IGNORE_DEPRECATIONS
   res = g_atomic_pointer_compare_and_exchange (&vp_str, NULL, (char *) str);
   g_assert_true (res);
 
+  /* Note that atomic variables should almost certainly not be marked as
+   * `volatile` — see http://isvolatileusefulwiththreads.in/c/. This test exists
+   * to make sure that we don’t warn when built against older third party code. */
   g_atomic_pointer_set (&vp_str_vol, NULL);
   res = g_atomic_pointer_compare_and_exchange (&vp_str_vol, NULL, (char *) str);
   g_assert_true (res);
@@ -248,8 +254,8 @@ G_GNUC_END_IGNORE_DEPRECATIONS
 #define THREADS 10
 #define ROUNDS 10000
 
-volatile gint bucket[THREADS];
-volatile gint atomic;
+gint bucket[THREADS];  /* never contested by threads, not accessed atomically */
+gint atomic;  /* (atomic) */
 
 static gpointer
 thread_func (gpointer data)
index cd510ed..59471d0 100644 (file)
@@ -537,7 +537,7 @@ test_g_timer (void)
 static void
 test_g_time_zone (void)
 {
-  g_autoptr(GTimeZone) val = g_time_zone_new ("UTC");
+  g_autoptr(GTimeZone) val = g_time_zone_new_utc ();
   g_assert_nonnull (val);
 }
 
index 0f0b3d2..ed338cc 100644 (file)
@@ -29,7 +29,7 @@
 
 static GCond cond;
 static GMutex mutex;
-static volatile gint next;
+static gint next;  /* locked by @mutex */
 
 static void
 push_value (gint value)
index fa6fc6a..76ba908 100644 (file)
@@ -524,10 +524,10 @@ test_mkdir_with_parents (void)
   g_assert_cmpint (errno, ==, EINVAL);
 }
 
-#ifdef G_OS_UNIX
 /*
  * check_cap_dac_override:
- * @tmpdir: A temporary directory in which we can create and delete files
+ * @tmpdir: (nullable): A temporary directory in which we can create
+ *  and delete files. If %NULL, use the g_get_tmp_dir(), safely.
  *
  * Check whether the current process can bypass DAC permissions.
  *
@@ -550,20 +550,39 @@ test_mkdir_with_parents (void)
 static gboolean
 check_cap_dac_override (const char *tmpdir)
 {
+#ifdef G_OS_UNIX
+  gchar *safe_tmpdir = NULL;
   gchar *dac_denies_write;
   gchar *inside;
   gboolean have_cap;
 
+  if (tmpdir == NULL)
+    {
+      /* It's unsafe to write predictable filenames into g_get_tmp_dir(),
+       * because it's usually a shared directory that can be subject to
+       * symlink attacks, so use a subdirectory for this check. */
+      GError *error = NULL;
+
+      safe_tmpdir = g_dir_make_tmp (NULL, &error);
+      g_assert_no_error (error);
+      g_clear_error (&error);
+
+      if (safe_tmpdir == NULL)
+        return FALSE;
+
+      tmpdir = safe_tmpdir;
+    }
+
   dac_denies_write = g_build_filename (tmpdir, "dac-denies-write", NULL);
   inside = g_build_filename (dac_denies_write, "inside", NULL);
 
-  g_assert_cmpint (mkdir (dac_denies_write, S_IRWXU) == 0 ? 0 : errno, ==, 0);
-  g_assert_cmpint (chmod (dac_denies_write, 0) == 0 ? 0 : errno, ==, 0);
+  g_assert_no_errno (mkdir (dac_denies_write, S_IRWXU));
+  g_assert_no_errno (chmod (dac_denies_write, 0));
 
   if (mkdir (inside, S_IRWXU) == 0)
     {
       g_test_message ("Looks like we have CAP_DAC_OVERRIDE or equivalent");
-      g_assert_cmpint (rmdir (inside) == 0 ? 0 : errno, ==, 0);
+      g_assert_no_errno (rmdir (inside));
       have_cap = TRUE;
     }
   else
@@ -575,13 +594,20 @@ check_cap_dac_override (const char *tmpdir)
       have_cap = FALSE;
     }
 
-  g_assert_cmpint (chmod (dac_denies_write, S_IRWXU) == 0 ? 0 : errno, ==, 0);
-  g_assert_cmpint (rmdir (dac_denies_write) == 0 ? 0 : errno, ==, 0);
+  g_assert_no_errno (chmod (dac_denies_write, S_IRWXU));
+  g_assert_no_errno (rmdir (dac_denies_write));
+
+  if (safe_tmpdir != NULL)
+    g_assert_no_errno (rmdir (safe_tmpdir));
+
   g_free (dac_denies_write);
   g_free (inside);
+  g_free (safe_tmpdir);
   return have_cap;
-}
+#else
+  return FALSE;
 #endif
+}
 
 /* Reproducer for https://gitlab.gnome.org/GNOME/glib/issues/1852 */
 static void
@@ -606,8 +632,8 @@ test_mkdir_with_parents_permission (void)
   subdir = g_build_filename (tmpdir, "sub", NULL);
   subdir2 = g_build_filename (subdir, "sub2", NULL);
   subdir3 = g_build_filename (subdir2, "sub3", NULL);
-  g_assert_cmpint (g_mkdir (subdir, 0700) == 0 ? 0 : errno, ==, 0);
-  g_assert_cmpint (g_chmod (subdir, 0) == 0 ? 0 : errno, ==, 0);
+  g_assert_no_errno (g_mkdir (subdir, 0700));
+  g_assert_no_errno (g_chmod (subdir, 0));
 
   if (have_cap_dac_override)
     {
@@ -625,11 +651,11 @@ test_mkdir_with_parents_permission (void)
       g_assert_cmpint (result, ==, -1);
       g_assert_cmpint (saved_errno, ==, EACCES);
 
-      g_assert_cmpint (g_chmod (subdir, 0700) == 0 ? 0 : errno, ==, 0);
+      g_assert_no_errno (g_chmod (subdir, 0700));
     }
 
-  g_assert_cmpint (g_remove (subdir) == 0 ? 0 : errno, ==, 0);
-  g_assert_cmpint (g_remove (tmpdir) == 0 ? 0 : errno, ==, 0);
+  g_assert_no_errno (g_remove (subdir));
+  g_assert_no_errno (g_remove (tmpdir));
   g_free (subdir3);
   g_free (subdir2);
   g_free (subdir);
@@ -1132,6 +1158,7 @@ test_set_contents_full_read_only_file (void)
   GError *error = NULL;
   gchar *file_name = NULL;
   gboolean ret;
+  gboolean can_override_dac = check_cap_dac_override (NULL);
 
   g_test_summary ("Test g_file_set_contents_full() on a read-only file");
 
@@ -1147,8 +1174,18 @@ test_set_contents_full_read_only_file (void)
 
   /* Set the file contents */
   ret = g_file_set_contents_full (file_name, "b", 1, G_FILE_SET_CONTENTS_NONE, 0644, &error);
-  g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_ACCES);
-  g_assert_false (ret);
+
+  if (can_override_dac)
+    {
+      g_assert_no_error (error);
+      g_assert_true (ret);
+    }
+  else
+    {
+      g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_ACCES);
+      g_assert_false (ret);
+    }
+
   g_clear_error (&error);
 
   g_remove (file_name);
@@ -1174,11 +1211,13 @@ test_set_contents_full_read_only_directory (void)
       gchar *dir_name = NULL;
       gchar *file_name = NULL;
       gboolean ret;
+      gboolean can_override_dac;
 
       g_test_message ("Flags %d", flags);
 
       dir_name = g_dir_make_tmp ("glib-file-set-contents-full-rodir-XXXXXX", &error);
       g_assert_no_error (error);
+      can_override_dac = check_cap_dac_override (dir_name);
 
       file_name = g_build_filename (dir_name, "file", NULL);
       fd = g_open (file_name, O_CREAT | O_RDWR, 0644);
@@ -1191,10 +1230,19 @@ test_set_contents_full_read_only_directory (void)
 
       /* Set the file contents */
       ret = g_file_set_contents_full (file_name, "b", 1, flags, 0644, &error);
-      g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_ACCES);
-      g_assert_false (ret);
-      g_clear_error (&error);
 
+      if (can_override_dac)
+        {
+          g_assert_no_error (error);
+          g_assert_true (ret);
+        }
+      else
+        {
+          g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_ACCES);
+          g_assert_false (ret);
+        }
+
+      g_clear_error (&error);
       g_remove (file_name);
       g_unlink (dir_name);
 
index 4ea0fc6..2da3dcc 100644 (file)
@@ -234,7 +234,8 @@ test_GDateTime_equal (void)
   g_date_time_unref (dt2);
 
   /* UTC-0300 and not in DST */
-  tz = g_time_zone_new ("-03:00");
+  tz = g_time_zone_new_identifier ("-03:00");
+  g_assert_nonnull (tz);
   dt1 = g_date_time_new (tz, 2010, 5, 24,  8, 0, 0);
   g_time_zone_unref (tz);
   g_assert_cmpint (g_date_time_get_utc_offset (dt1) / G_USEC_PER_SEC, ==, (-3 * 3600));
@@ -247,10 +248,11 @@ test_GDateTime_equal (void)
 
   /* America/Recife is in UTC-0300 */
 #ifdef G_OS_UNIX
-  tz = g_time_zone_new ("America/Recife");
+  tz = g_time_zone_new_identifier ("America/Recife");
 #elif defined G_OS_WIN32
-  tz = g_time_zone_new ("E. South America Standard Time");
+  tz = g_time_zone_new_identifier ("E. South America Standard Time");
 #endif
+  g_assert_nonnull (tz);
   dt1 = g_date_time_new (tz, 2010, 5, 24,  8, 0, 0);
   g_time_zone_unref (tz);
   g_assert_cmpint (g_date_time_get_utc_offset (dt1) / G_USEC_PER_SEC, ==, (-3 * 3600));
@@ -1174,10 +1176,11 @@ test_GDateTime_new_full (void)
   g_date_time_unref (dt);
 
 #ifdef G_OS_UNIX
-  tz = g_time_zone_new ("America/Tijuana");
+  tz = g_time_zone_new_identifier ("America/Tijuana");
 #elif defined G_OS_WIN32
-  tz = g_time_zone_new ("Pacific Standard Time");
+  tz = g_time_zone_new_identifier ("Pacific Standard Time");
 #endif
+  g_assert_nonnull (tz);
   dt = g_date_time_new (tz, 2010, 11, 24, 8, 4, 0);
 
   dt_tz = g_date_time_get_timezone (dt);
@@ -1523,12 +1526,6 @@ GDateTime *__dt = g_date_time_new_local (2009, 10, 24, 0, 0, 0);\
   get_localtime_tm (t, &tt);
   strftime (dst, sizeof(dst), "%Z", &tt);
 
-  /* get current time_t for 20090924 in the local timezone */
-  tt.tm_sec = 0;
-  tt.tm_min = 0;
-  tt.tm_hour = 0;
-  t = mktime (&tt);
-
   TEST_PRINTF ("%a", "Sat");
   TEST_PRINTF ("%A", "Saturday");
   TEST_PRINTF ("%b", "Oct");
@@ -1938,10 +1935,11 @@ test_GDateTime_dst (void)
 
   /* this date has the DST state set for Europe/London */
 #ifdef G_OS_UNIX
-  tz = g_time_zone_new ("Europe/London");
+  tz = g_time_zone_new_identifier ("Europe/London");
 #elif defined G_OS_WIN32
-  tz = g_time_zone_new ("GMT Standard Time");
+  tz = g_time_zone_new_identifier ("GMT Standard Time");
 #endif
+  g_assert_nonnull (tz);
   dt1 = g_date_time_new (tz, 2009, 8, 15, 3, 0, 1);
   g_assert (g_date_time_is_daylight_savings (dt1));
   g_assert_cmpint (g_date_time_get_utc_offset (dt1) / G_USEC_PER_SEC, ==, 3600);
@@ -2123,7 +2121,8 @@ test_z (void)
 
   g_test_bug ("http://bugzilla.gnome.org/642935");
 
-  tz = g_time_zone_new ("-08:00");
+  tz = g_time_zone_new_identifier ("-08:00");
+  g_assert_nonnull (tz);
   dt = g_date_time_new (tz, 1, 1, 1, 0, 0, 0);
 
   p = g_date_time_format (dt, "%z");
@@ -2145,7 +2144,8 @@ test_z (void)
   g_date_time_unref (dt);
   g_time_zone_unref (tz);
 
-  tz = g_time_zone_new ("+00:00");
+  tz = g_time_zone_new_identifier ("+00:00");
+  g_assert_nonnull (tz);
   dt = g_date_time_new (tz, 1, 1, 1, 0, 0, 0);
   p = g_date_time_format (dt, "%:::z");
   g_assert_cmpstr (p, ==, "+00");
@@ -2153,7 +2153,8 @@ test_z (void)
   g_date_time_unref (dt);
   g_time_zone_unref (tz);
 
-  tz = g_time_zone_new ("+08:23");
+  tz = g_time_zone_new_identifier ("+08:23");
+  g_assert_nonnull (tz);
   dt = g_date_time_new (tz, 1, 1, 1, 0, 0, 0);
   p = g_date_time_format (dt, "%:::z");
   g_assert_cmpstr (p, ==, "+08:23");
@@ -2161,7 +2162,8 @@ test_z (void)
   g_date_time_unref (dt);
   g_time_zone_unref (tz);
 
-  tz = g_time_zone_new ("+08:23:45");
+  tz = g_time_zone_new_identifier ("+08:23:45");
+  g_assert_nonnull (tz);
   dt = g_date_time_new (tz, 1, 1, 1, 0, 0, 0);
   p = g_date_time_format (dt, "%:::z");
   g_assert_cmpstr (p, ==, "+08:23:45");
@@ -2169,7 +2171,8 @@ test_z (void)
   g_date_time_unref (dt);
   g_time_zone_unref (tz);
 
-  tz = g_time_zone_new ("-00:15");
+  tz = g_time_zone_new_identifier ("-00:15");
+  g_assert_nonnull (tz);
   dt = g_date_time_new (tz, 1, 1, 1, 0, 0, 0);
 
   p = g_date_time_format (dt, "%z");
@@ -2214,10 +2217,11 @@ test_6_days_until_end_of_the_month (void)
    *  - https://tools.ietf.org/id/draft-murchison-tzdist-tzif-15.html#rfc.section.3.3
    *  - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03
    */
-  tz = g_time_zone_new ("CET-1CEST,M3.5.0,M10.5.0/3");
+  tz = g_time_zone_new_identifier ("CET-1CEST,M3.5.0,M10.5.0/3");
 #elif defined (G_OS_WIN32)
-  tz = g_time_zone_new ("Romance Standard Time");
+  tz = g_time_zone_new_identifier ("Romance Standard Time");
 #endif
+  g_assert_nonnull (tz);
   dt = g_date_time_new (tz, 2020, 10, 5, 1, 1, 1);
 
   p = g_date_time_format (dt, "%Y-%m-%d %H:%M:%S%z");
@@ -2320,10 +2324,11 @@ test_find_interval (void)
   gint i1, i2;
 
 #ifdef G_OS_UNIX
-  tz = g_time_zone_new ("America/Toronto");
+  tz = g_time_zone_new_identifier ("America/Toronto");
 #elif defined G_OS_WIN32
-  tz = g_time_zone_new ("Eastern Standard Time");
+  tz = g_time_zone_new_identifier ("Eastern Standard Time");
 #endif
+  g_assert_nonnull (tz);
   dt = g_date_time_new_utc (2010, 11, 7, 1, 30, 0);
   u = g_date_time_to_unix (dt);
 
@@ -2353,10 +2358,11 @@ test_adjust_time (void)
   gint i1, i2;
 
 #ifdef G_OS_UNIX
-  tz = g_time_zone_new ("America/Toronto");
+  tz = g_time_zone_new_identifier ("America/Toronto");
 #elif defined G_OS_WIN32
-  tz = g_time_zone_new ("Eastern Standard Time");
+  tz = g_time_zone_new_identifier ("Eastern Standard Time");
 #endif
+  g_assert_nonnull (tz);
   dt = g_date_time_new_utc (2010, 11, 7, 1, 30, 0);
   u = g_date_time_to_unix (dt);
   u2 = u;
@@ -2378,6 +2384,7 @@ test_adjust_time (void)
   g_date_time_unref (dt);
 
   i1 = g_time_zone_adjust_time (tz, G_TIME_TYPE_DAYLIGHT, &u2);
+  g_assert_cmpint (i1, >=, 0);
   g_assert (u == u2);
 
   g_time_zone_unref (tz);
@@ -2388,7 +2395,9 @@ test_no_header (void)
 {
   GTimeZone *tz;
 
+  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
   tz = g_time_zone_new ("blabla");
+  G_GNUC_END_IGNORE_DEPRECATIONS
 
   g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "UTC");
   g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "UTC");
@@ -2399,13 +2408,25 @@ test_no_header (void)
 }
 
 static void
+test_no_header_identifier (void)
+{
+  GTimeZone *tz;
+
+  tz = g_time_zone_new_identifier ("blabla");
+
+  g_assert_null (tz);
+}
+
+static void
 test_posix_parse (void)
 {
   GTimeZone *tz;
   GDateTime *gdt1, *gdt2;
 
   /* Check that an unknown zone name falls back to UTC. */
+  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
   tz = g_time_zone_new ("nonexistent");
+  G_GNUC_END_IGNORE_DEPRECATIONS
   g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "UTC");
   g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "UTC");
   g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, 0);
@@ -2413,7 +2434,9 @@ test_posix_parse (void)
   g_time_zone_unref (tz);
 
   /* An existent zone name should not fall back to UTC. */
+  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
   tz = g_time_zone_new ("PST8");
+  G_GNUC_END_IGNORE_DEPRECATIONS
   g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "PST8");
   g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "PST");
   g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, - 8 * 3600);
@@ -2423,7 +2446,8 @@ test_posix_parse (void)
 /* This fails rules_from_identifier on Unix (though not on Windows)
  * but passes anyway because PST8PDT is a zone name.
  */
-  tz = g_time_zone_new ("PST8PDT");
+  tz = g_time_zone_new_identifier ("PST8PDT");
+  g_assert_nonnull (tz);
   g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "PST8PDT");
   g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "PST");
   g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, - 8 * 3600);
@@ -2433,8 +2457,9 @@ test_posix_parse (void)
   g_assert (g_time_zone_is_dst (tz, 1));
   g_time_zone_unref (tz);
 
-  tz = g_time_zone_new ("PST8PDT6:32:15");
+  tz = g_time_zone_new_identifier ("PST8PDT6:32:15");
 #ifdef G_OS_WIN32
+  g_assert_nonnull (tz);
   g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "PST8PDT6:32:15");
   g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "PST");
   g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, - 8 * 3600);
@@ -2451,14 +2476,12 @@ test_posix_parse (void)
   g_date_time_unref (gdt1);
   g_date_time_unref (gdt2);
 #else
-  g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "UTC");
-  g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "UTC");
-  g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, 0);
-  g_assert (!g_time_zone_is_dst (tz, 0));
+  g_assert_null (tz);
 #endif
-  g_time_zone_unref (tz);
+  g_clear_pointer (&tz, g_time_zone_unref);
 
-  tz = g_time_zone_new ("NZST-12:00:00NZDT-13:00:00,M10.1.0,M3.3.0");
+  tz = g_time_zone_new_identifier ("NZST-12:00:00NZDT-13:00:00,M10.1.0,M3.3.0");
+  g_assert_nonnull (tz);
   g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "NZST-12:00:00NZDT-13:00:00,M10.1.0,M3.3.0");
   g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "NZST");
   g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, 12 * 3600);
@@ -2484,7 +2507,8 @@ test_posix_parse (void)
   g_date_time_unref (gdt2);
   g_time_zone_unref (tz);
 
-  tz = g_time_zone_new ("NZST-12:00:00NZDT-13:00:00,279,76");
+  tz = g_time_zone_new_identifier ("NZST-12:00:00NZDT-13:00:00,279,76");
+  g_assert_nonnull (tz);
   g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "NZST-12:00:00NZDT-13:00:00,279,76");
   g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "NZST");
   g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, 12 * 3600);
@@ -2510,7 +2534,8 @@ test_posix_parse (void)
   g_date_time_unref (gdt2);
   g_time_zone_unref (tz);
 
-  tz = g_time_zone_new ("NZST-12:00:00NZDT-13:00:00,J279,J76");
+  tz = g_time_zone_new_identifier ("NZST-12:00:00NZDT-13:00:00,J279,J76");
+  g_assert_nonnull (tz);
   g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "NZST-12:00:00NZDT-13:00:00,J279,J76");
   g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "NZST");
   g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, 12 * 3600);
@@ -2536,7 +2561,8 @@ test_posix_parse (void)
   g_date_time_unref (gdt2);
   g_time_zone_unref (tz);
 
-  tz = g_time_zone_new ("NZST-12:00:00NZDT-13:00:00,M10.1.0/07:00,M3.3.0/07:00");
+  tz = g_time_zone_new_identifier ("NZST-12:00:00NZDT-13:00:00,M10.1.0/07:00,M3.3.0/07:00");
+  g_assert_nonnull (tz);
   g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "NZST-12:00:00NZDT-13:00:00,M10.1.0/07:00,M3.3.0/07:00");
   g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "NZST");
   g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, 12 * 3600);
@@ -2586,13 +2612,15 @@ test_posix_parse (void)
   g_date_time_unref (gdt2);
   g_time_zone_unref (tz);
 
-  tz = g_time_zone_new ("VIR-00:30");
+  tz = g_time_zone_new_identifier ("VIR-00:30");
+  g_assert_nonnull (tz);
   g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "VIR-00:30");
   g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "VIR");
   g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, (30 * 60));
   g_assert_false (g_time_zone_is_dst (tz, 0));
 
-  tz = g_time_zone_new ("VIR-00:30VID,0/00:00:00,365/23:59:59");
+  tz = g_time_zone_new_identifier ("VIR-00:30VID,0/00:00:00,365/23:59:59");
+  g_assert_nonnull (tz);
   g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "VIR-00:30VID,0/00:00:00,365/23:59:59");
   g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "VIR");
   g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, (30 * 60));
@@ -2601,7 +2629,8 @@ test_posix_parse (void)
   g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==, (90 * 60));
   g_assert_true (g_time_zone_is_dst (tz, 1));
 
-  tz = g_time_zone_new ("VIR-02:30VID,0/00:00:00,365/23:59:59");
+  tz = g_time_zone_new_identifier ("VIR-02:30VID,0/00:00:00,365/23:59:59");
+  g_assert_nonnull (tz);
   g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "VIR-02:30VID,0/00:00:00,365/23:59:59");
   g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "VIR");
   g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, (150 * 60));
@@ -2610,7 +2639,8 @@ test_posix_parse (void)
   g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==, (210 * 60));
   g_assert_true (g_time_zone_is_dst (tz, 1));
 
-  tz = g_time_zone_new ("VIR-02:30VID-04:30,0/00:00:00,365/23:59:59");
+  tz = g_time_zone_new_identifier ("VIR-02:30VID-04:30,0/00:00:00,365/23:59:59");
+  g_assert_nonnull (tz);
   g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "VIR-02:30VID-04:30,0/00:00:00,365/23:59:59");
   g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "VIR");
   g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, (150 * 60));
@@ -2619,7 +2649,8 @@ test_posix_parse (void)
   g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==, (270 * 60));
   g_assert_true (g_time_zone_is_dst (tz, 1));
 
-  tz = g_time_zone_new ("VIR-12:00VID-13:00,0/00:00:00,365/23:59:59");
+  tz = g_time_zone_new_identifier ("VIR-12:00VID-13:00,0/00:00:00,365/23:59:59");
+  g_assert_nonnull (tz);
   g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "VIR-12:00VID-13:00,0/00:00:00,365/23:59:59");
   g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "VIR");
   g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, (720 * 60));
@@ -2637,7 +2668,8 @@ test_GDateTime_floating_point (void)
 
   g_test_bug ("http://bugzilla.gnome.org/697715");
 
-  tz = g_time_zone_new ("-03:00");
+  tz = g_time_zone_new_identifier ("-03:00");
+  g_assert_nonnull (tz);
   g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "-03:00");
   dt = g_date_time_new (tz, 2010, 5, 24,  8, 0, 1.000001);
   g_time_zone_unref (tz);
@@ -2659,7 +2691,8 @@ test_identifier (void)
   const char *recife_tz = "America/Recife";
 #endif
 
-  tz = g_time_zone_new ("UTC");
+  tz = g_time_zone_new_identifier ("UTC");
+  g_assert_nonnull (tz);
   g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "UTC");
   g_time_zone_unref (tz);
 
@@ -2667,21 +2700,27 @@ test_identifier (void)
   g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "UTC");
   g_time_zone_unref (tz);
 
+  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
   tz = g_time_zone_new ("some rubbish");
+  G_GNUC_END_IGNORE_DEPRECATIONS
   g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "UTC");
   g_time_zone_unref (tz);
 
-  tz = g_time_zone_new ("Z");
+  tz = g_time_zone_new_identifier ("Z");
+  g_assert_nonnull (tz);
   g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "Z");
   g_time_zone_unref (tz);
 
-  tz = g_time_zone_new ("+03:15");
+  tz = g_time_zone_new_identifier ("+03:15");
+  g_assert_nonnull (tz);
   g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "+03:15");
   g_time_zone_unref (tz);
 
   /* System timezone. We can’t change this, but we can at least assert that
    * the identifier is non-NULL and non-empty. */
+  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
   tz = g_time_zone_new (NULL);
+  G_GNUC_END_IGNORE_DEPRECATIONS
   g_test_message ("System time zone identifier: %s", g_time_zone_get_identifier (tz));
   g_assert_nonnull (g_time_zone_get_identifier (tz));
   g_assert_cmpstr (g_time_zone_get_identifier (tz), !=, "");
@@ -2767,10 +2806,8 @@ test_time_zone_parse_rfc8536 (void)
 
       path = g_test_build_filename (G_TEST_DIST, "time-zones", test_files[i], NULL);
       g_assert_true (g_path_is_absolute (path));
-      tz = g_time_zone_new (path);
+      tz = g_time_zone_new_identifier (path);
       g_assert_nonnull (tz);
-      /* UTC will be loaded as a fallback if parsing fails */
-      g_assert_cmpstr (g_time_zone_get_identifier (tz), !=, "UTC");
       g_time_zone_unref (tz);
       g_free (path);
     }
@@ -2787,13 +2824,17 @@ test_time_zone_caching (void)
   /* Check a specific (arbitrary) timezone. These are only cached while third
    * party code holds a ref to at least one instance. */
 #ifdef G_OS_UNIX
-  tz1 = g_time_zone_new ("Europe/London");
-  tz2 = g_time_zone_new ("Europe/London");
+  tz1 = g_time_zone_new_identifier ("Europe/London");
+  g_assert_nonnull (tz1);
+  tz2 = g_time_zone_new_identifier ("Europe/London");
+  g_assert_nonnull (tz2);
   g_time_zone_unref (tz1);
   g_time_zone_unref (tz2);
 #elif defined G_OS_WIN32
-  tz1 = g_time_zone_new ("GMT Standard Time");
-  tz2 = g_time_zone_new ("GMT Standard Time");
+  tz1 = g_time_zone_new_identifier ("GMT Standard Time");
+  g_assert_nonnull (tz1);
+  tz2 = g_time_zone_new_identifier ("GMT Standard Time");
+  g_assert_nonnull (tz2);
   g_time_zone_unref (tz1);
   g_time_zone_unref (tz2);
 #endif
@@ -2803,13 +2844,21 @@ test_time_zone_caching (void)
 
   /* Check the default timezone, local and UTC. These are cached internally in
    * GLib, so should persist even after the last third party reference is
-   * dropped. */
-  tz1 = g_time_zone_new (NULL);
-  g_time_zone_unref (tz1);
-  tz2 = g_time_zone_new (NULL);
-  g_time_zone_unref (tz2);
+   * dropped.
+   *
+   * The default timezone could be NULL on some platforms (FreeBSD) if
+   * `/etc/localtime` is not set correctly. */
+  tz1 = g_time_zone_new_identifier (NULL);
+  if (tz1 != NULL)
+    {
+      g_assert_nonnull (tz1);
+      g_time_zone_unref (tz1);
+      tz2 = g_time_zone_new_identifier (NULL);
+      g_assert_nonnull (tz2);
+      g_time_zone_unref (tz2);
 
-  g_assert_true (tz1 == tz2);
+      g_assert_true (tz1 == tz2);
+    }
 
   tz1 = g_time_zone_new_utc ();
   g_time_zone_unref (tz1);
@@ -2893,6 +2942,7 @@ main (gint   argc,
   g_test_add_func ("/GTimeZone/find-interval", test_find_interval);
   g_test_add_func ("/GTimeZone/adjust-time", test_adjust_time);
   g_test_add_func ("/GTimeZone/no-header", test_no_header);
+  g_test_add_func ("/GTimeZone/no-header-identifier", test_no_header_identifier);
   g_test_add_func ("/GTimeZone/posix-parse", test_posix_parse);
   g_test_add_func ("/GTimeZone/floating-point", test_GDateTime_floating_point);
   g_test_add_func ("/GTimeZone/identifier", test_identifier);
index 3905e20..35434ca 100644 (file)
@@ -194,8 +194,7 @@ append_tuple_type_string (GString  *string,
 {
   GVariantType *result, *other_result;
   GVariantType **types;
-  gint size;
-  gsize i;
+  gsize i, size;
 
   g_string_append_c (string, '(');
   g_string_append (description, "t of [");
@@ -376,8 +375,7 @@ describe_type (const GVariantType *type)
             {
               const GVariantType *sub;
               GString *string;
-              gint length;
-              gsize i;
+              gsize i, length;
 
               string = g_string_new ("t of [");
 
@@ -873,8 +871,7 @@ describe_info (GVariantTypeInfo *info)
       {
         const gchar *sep = "";
         GString *string;
-        gint length;
-        gsize i;
+        gsize i, length;
 
         string = g_string_new ("t of [");
         length = g_variant_type_info_n_members (info);
@@ -935,11 +932,10 @@ static void
 check_offsets (GVariantTypeInfo   *info,
                const GVariantType *type)
 {
-  gsize flavour;
-  gint length;
+  gsize flavour, length;
 
   length = g_variant_type_info_n_members (info);
-  g_assert_cmpint (length, ==, g_variant_type_n_items (type));
+  g_assert_cmpuint (length, ==, g_variant_type_n_items (type));
 
   /* the 'flavour' is the low order bits of the ending point of
    * variable-size items in the tuple.  this lets us test that the type
@@ -2637,7 +2633,7 @@ tree_instance_check_gvariant (TreeInstance *tree,
       break;
 
     case 'b':
-      return g_variant_get_boolean (value) == tree->data.integer;
+      return g_variant_get_boolean (value) == (gboolean) tree->data.integer;
 
     case 'y':
       return g_variant_get_byte (value) == (guchar) tree->data.integer;
@@ -2997,18 +2993,6 @@ test_varargs_empty_array (void)
 }
 
 static void
-assert_cmpstrv (const gchar **strv1, const gchar **strv2)
-{
-  gsize i;
-
-  for (i = 0; strv1[i] != NULL && strv2[i] != NULL; i++)
-    g_assert_cmpstr (strv1[i], ==, strv2[i]);
-
-  g_assert_null (strv1[i]);
-  g_assert_null (strv2[i]);
-}
-
-static void
 test_varargs (void)
 {
   {
@@ -3091,7 +3075,7 @@ test_varargs (void)
     i = 0;
     g_variant_iter_init (&iter, value);
     while (g_variant_iter_loop (&iter, "mi", NULL, &val))
-      g_assert_true (val == i++ || val == 0);
+      g_assert_true (val == (gint) i++ || val == 0);
     g_assert_cmpuint (i, ==, 100);
 
     i = 0;
@@ -3157,8 +3141,8 @@ test_varargs (void)
     g_variant_iter_next (&tuple, "^a&s", &strv);
     g_variant_iter_next (&tuple, "^as", &my_strv);
 
-    assert_cmpstrv (strv, strvector);
-    assert_cmpstrv ((const char **)my_strv, strvector);
+    g_assert_cmpstrv (strv, strvector);
+    g_assert_cmpstrv (my_strv, strvector);
 
     g_variant_unref (value);
     g_strfreev (my_strv);
@@ -3227,8 +3211,8 @@ test_varargs (void)
     g_variant_iter_next (&tuple, "^a&ay", &strv);
     g_variant_iter_next (&tuple, "^aay", &my_strv);
 
-    assert_cmpstrv (strv, strvector);
-    assert_cmpstrv ((const char **)my_strv, strvector);
+    g_assert_cmpstrv (strv, strvector);
+    g_assert_cmpstrv (my_strv, strvector);
 
     g_variant_unref (value);
     g_strfreev (my_strv);
@@ -3276,8 +3260,8 @@ test_varargs (void)
     g_variant_iter_next (&tuple, "^a&o", &strv);
     g_variant_iter_next (&tuple, "^ao", &my_strv);
 
-    assert_cmpstrv (strv, strvector);
-    assert_cmpstrv ((const char **)my_strv, strvector);
+    g_assert_cmpstrv (strv, strvector);
+    g_assert_cmpstrv (my_strv, strvector);
 
     g_variant_unref (value);
     g_strfreev (my_strv);
@@ -4355,12 +4339,12 @@ test_lookup_value (void)
     const gchar *dict, *key, *value;
   } cases[] = {
     { "@a{ss} {'x':  'y'}",   "x",  "'y'" },
-    { "@a{ss} {'x':  'y'}",   "y"         },
+    { "@a{ss} {'x':  'y'}",   "y",  NULL  },
     { "@a{os} {'/x': 'y'}",   "/x", "'y'" },
-    { "@a{os} {'/x': 'y'}",   "/y"        },
+    { "@a{os} {'/x': 'y'}",   "/y", NULL  },
     { "@a{sv} {'x':  <'y'>}", "x",  "'y'" },
     { "@a{sv} {'x':  <5>}",   "x",  "5"   },
-    { "@a{sv} {'x':  <'y'>}", "y"         }
+    { "@a{sv} {'x':  <'y'>}", "y",  NULL  }
   };
   gsize i;
 
index 461a7d3..b37fb43 100644 (file)
@@ -92,7 +92,7 @@ struct context
 static struct context contexts[NUM_THREADS];
 static GThread *threads[NUM_THREADS];
 static GWakeup *last_token_wakeup;
-static volatile gint tokens_alive;
+static gint tokens_alive;  /* (atomic) */
 
 static void
 context_init (struct context *ctx)
index 6b01971..f4ff55c 100644 (file)
@@ -591,7 +591,7 @@ test_hash_misc (void)
   gint value = 120;
   gint *pvalue;
   GList *keys, *values;
-  gint keys_len, values_len;
+  gsize keys_len, values_len;
   GHashTableIter iter;
   gpointer ikey, ivalue;
   int result_array[10000];
@@ -1362,7 +1362,7 @@ struct _GHashTable
 
   GHashFunc        hash_func;
   GEqualFunc       key_equal_func;
-  volatile gint    ref_count;
+  gint             ref_count;  /* (atomic) */
 
 #ifndef G_DISABLE_ASSERT
   int              version;
index d694e62..1d6f855 100644 (file)
@@ -69,7 +69,23 @@ static const gint num_non_round_trip_names = G_N_ELEMENTS (non_round_trip_names)
 static const gchar *bad_names[] = {
   "disallowed\xef\xbf\xbd" "character",
   "non-utf\x88",
-  "xn--mixed-\xc3\xbcp"
+  "xn--mixed-\xc3\xbcp",
+  "verylongverylongverylongverylongverylongverylongverylongverylongverylong"
+  "verylongverylongverylongverylongverylongverylongverylongverylongverylong"
+  "verylongverylongverylongverylongverylongverylongverylongverylongverylong"
+  "verylongverylongverylongverylongverylongverylongverylongverylongverylong"
+  "verylongverylongverylongverylongverylongverylongverylongverylongverylong"
+  "verylongverylongverylongverylongverylongverylongverylongverylongverylong"
+  "verylongverylongverylongverylongverylongverylongverylongverylongverylong"
+  "verylongverylongverylongverylongverylongverylongverylongverylongverylong"
+  "verylongverylongverylongverylongverylongverylongverylongverylongverylong"
+  "verylongverylongverylongverylongverylongverylongverylongverylongverylong"
+  "verylongverylongverylongverylongverylongverylongverylongverylongverylong"
+  "verylongverylongverylongverylongverylongverylongverylongverylongverylong"
+  "verylongverylongverylongverylongverylongverylongverylongverylongverylong"
+  "verylongverylongverylongverylongverylongverylongverylongverylongverylong"
+  "verylongverylongverylongverylongverylongverylongverylongverylongverylong"
+  "verylongverylongverylongverylongverylongverylongverylongverylongverylong",
 };
 static const gint num_bad_names = G_N_ELEMENTS (bad_names);
 
@@ -81,7 +97,7 @@ test_to_ascii (void)
 
   for (i = 0; i < num_idn_test_domains; i++)
     {
-      g_assert (g_hostname_is_non_ascii (idn_test_domains[i].unicode_name));
+      g_assert_true (g_hostname_is_non_ascii (idn_test_domains[i].unicode_name));
       ascii = g_hostname_to_ascii (idn_test_domains[i].unicode_name);
       g_assert_cmpstr (idn_test_domains[i].ascii_name, ==, ascii);
       g_free (ascii);
@@ -94,14 +110,14 @@ test_to_ascii (void)
   for (i = 0; i < num_non_round_trip_names; i++)
     {
       if (non_round_trip_names[i].orig_is_unicode)
-       g_assert (g_hostname_is_non_ascii (non_round_trip_names[i].orig_name));
+        g_assert_true (g_hostname_is_non_ascii (non_round_trip_names[i].orig_name));
       else
-       g_assert (!g_hostname_is_non_ascii (non_round_trip_names[i].orig_name));
+        g_assert_true (!g_hostname_is_non_ascii (non_round_trip_names[i].orig_name));
 
       if (non_round_trip_names[i].ascii_is_encoded)
-       g_assert (g_hostname_is_ascii_encoded (non_round_trip_names[i].ascii_name));
+        g_assert_true (g_hostname_is_ascii_encoded (non_round_trip_names[i].ascii_name));
       else
-       g_assert (!g_hostname_is_ascii_encoded (non_round_trip_names[i].ascii_name));
+        g_assert_true (!g_hostname_is_ascii_encoded (non_round_trip_names[i].ascii_name));
 
       ascii = g_hostname_to_ascii (non_round_trip_names[i].orig_name);
       g_assert_cmpstr (non_round_trip_names[i].ascii_name, ==, ascii);
@@ -127,7 +143,7 @@ test_to_unicode (void)
 
   for (i = 0; i < num_idn_test_domains; i++)
     {
-      g_assert (g_hostname_is_ascii_encoded (idn_test_domains[i].ascii_name));
+      g_assert_true (g_hostname_is_ascii_encoded (idn_test_domains[i].ascii_name));
       unicode = g_hostname_to_unicode (idn_test_domains[i].ascii_name);
       g_assert_cmpstr (idn_test_domains[i].unicode_name, ==, unicode);
       g_free (unicode);
index f16503a..096fe44 100644 (file)
@@ -398,7 +398,7 @@ compare_field (const GLogField *f1, const GLogField *f2)
 static gboolean
 compare_fields (const GLogField *f1, gsize n1, const GLogField *f2, gsize n2)
 {
-  int i, j;
+  gsize i, j;
 
   for (i = 0; i < n1; i++)
     {
index ec96bfa..563a951 100644 (file)
@@ -51,6 +51,8 @@ static GSourceFuncs funcs = {
   prepare,
   check,
   dispatch,
+  NULL,
+  NULL,
   NULL
 };
 
@@ -419,6 +421,8 @@ static GSourceFuncs counter_source_funcs = {
   NULL,
   counter_source_dispatch,
   NULL,
+  NULL,
+  NULL
 };
 
 static GSource *
@@ -914,7 +918,7 @@ test_mainloop_overflow (void)
   g_main_context_unref (ctx);
 }
 
-static volatile gint ready_time_dispatched;
+static gint ready_time_dispatched;  /* (atomic) */
 
 static gboolean
 ready_time_dispatch (GSource     *source,
@@ -942,7 +946,7 @@ test_ready_time (void)
   GThread *thread;
   GSource *source;
   GSourceFuncs source_funcs = {
-    NULL, NULL, ready_time_dispatch
+    NULL, NULL, ready_time_dispatch, NULL, NULL, NULL
   };
   GMainLoop *loop;
 
@@ -960,7 +964,7 @@ test_ready_time (void)
   /* A source with no ready time set should not fire */
   g_assert_cmpint (g_source_get_ready_time (source), ==, -1);
   while (g_main_context_iteration (NULL, FALSE));
-  g_assert_false (ready_time_dispatched);
+  g_assert_false (g_atomic_int_get (&ready_time_dispatched));
 
   /* The ready time should not have been changed */
   g_assert_cmpint (g_source_get_ready_time (source), ==, -1);
@@ -974,37 +978,37 @@ test_ready_time (void)
    */
   g_source_set_ready_time (source, g_get_monotonic_time () + G_TIME_SPAN_DAY);
   while (g_main_context_iteration (NULL, FALSE));
-  g_assert_false (ready_time_dispatched);
+  g_assert_false (g_atomic_int_get (&ready_time_dispatched));
   /* Make sure it didn't get reset */
   g_assert_cmpint (g_source_get_ready_time (source), !=, -1);
 
   /* Ready time of -1 -> don't fire */
   g_source_set_ready_time (source, -1);
   while (g_main_context_iteration (NULL, FALSE));
-  g_assert_false (ready_time_dispatched);
+  g_assert_false (g_atomic_int_get (&ready_time_dispatched));
   /* Not reset, but should still be -1 from above */
   g_assert_cmpint (g_source_get_ready_time (source), ==, -1);
 
   /* A ready time of the current time should fire immediately */
   g_source_set_ready_time (source, g_get_monotonic_time ());
   while (g_main_context_iteration (NULL, FALSE));
-  g_assert_true (ready_time_dispatched);
-  ready_time_dispatched = FALSE;
+  g_assert_true (g_atomic_int_get (&ready_time_dispatched));
+  g_atomic_int_set (&ready_time_dispatched, FALSE);
   /* Should have gotten reset by the handler function */
   g_assert_cmpint (g_source_get_ready_time (source), ==, -1);
 
   /* As well as one in the recent past... */
   g_source_set_ready_time (source, g_get_monotonic_time () - G_TIME_SPAN_SECOND);
   while (g_main_context_iteration (NULL, FALSE));
-  g_assert_true (ready_time_dispatched);
-  ready_time_dispatched = FALSE;
+  g_assert_true (g_atomic_int_get (&ready_time_dispatched));
+  g_atomic_int_set (&ready_time_dispatched, FALSE);
   g_assert_cmpint (g_source_get_ready_time (source), ==, -1);
 
   /* Zero is the 'official' way to get a source to fire immediately */
   g_source_set_ready_time (source, 0);
   while (g_main_context_iteration (NULL, FALSE));
-  g_assert_true (ready_time_dispatched);
-  ready_time_dispatched = FALSE;
+  g_assert_true (g_atomic_int_get (&ready_time_dispatched));
+  g_atomic_int_set (&ready_time_dispatched, FALSE);
   g_assert_cmpint (g_source_get_ready_time (source), ==, -1);
 
   /* Now do some tests of cross-thread wakeups.
@@ -1085,7 +1089,9 @@ trivial_finalize (GSource *source)
 static void
 test_unref_while_pending (void)
 {
-  static GSourceFuncs funcs = { trivial_prepare, NULL, NULL, trivial_finalize };
+  static GSourceFuncs funcs = {
+    trivial_prepare, NULL, NULL, trivial_finalize, NULL, NULL
+  };
   GMainContext *context;
   GSource *source;
 
@@ -1143,7 +1149,7 @@ write_bytes (gint         fd,
   /* Detect if we run before we should */
   g_assert_cmpint (*to_write, >=, 0);
 
-  limit = MIN (*to_write, sizeof zeros);
+  limit = MIN ((gsize) *to_write, sizeof zeros);
   *to_write -= write (fd, zeros, limit);
 
   return TRUE;
@@ -1399,7 +1405,7 @@ static void
 test_source_unix_fd_api (void)
 {
   GSourceFuncs no_funcs = {
-    NULL, NULL, return_true
+    NULL, NULL, return_true, NULL, NULL, NULL
   };
   GSource *source_a;
   GSource *source_b;
@@ -1542,6 +1548,62 @@ test_unix_file_poll (void)
   close (fd);
 }
 
+static void
+test_unix_fd_priority (void)
+{
+  gint fd1, fd2;
+  GMainLoop *loop;
+  GSource *source;
+
+  gint s1 = 0;
+  gboolean s2 = FALSE, s3 = FALSE;
+
+  g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/1592");
+
+  loop = g_main_loop_new (NULL, FALSE);
+
+  source = g_idle_source_new ();
+  g_source_set_callback (source, count_calls, &s1, NULL);
+  g_source_set_priority (source, 0);
+  g_source_attach (source, NULL);
+  g_source_unref (source);
+
+  fd1 = open ("/dev/random", O_RDONLY);
+  g_assert_cmpint (fd1, >=, 0);
+  source = g_unix_fd_source_new (fd1, G_IO_IN);
+  g_source_set_callback (source, G_SOURCE_FUNC (flag_bool), &s2, NULL);
+  g_source_set_priority (source, 10);
+  g_source_attach (source, NULL);
+  g_source_unref (source);
+
+  fd2 = open ("/dev/random", O_RDONLY);
+  g_assert_cmpint (fd2, >=, 0);
+  source = g_unix_fd_source_new (fd2, G_IO_IN);
+  g_source_set_callback (source, G_SOURCE_FUNC (flag_bool), &s3, NULL);
+  g_source_set_priority (source, 0);
+  g_source_attach (source, NULL);
+  g_source_unref (source);
+
+  /* This tests a bug that depends on the source with the lowest FD
+     identifier to have the lowest priority. Make sure that this is
+     the case. */
+  g_assert_cmpint (fd1, <, fd2);
+
+  g_assert_true (g_main_context_iteration (NULL, FALSE));
+
+  /* Idle source should have been dispatched. */
+  g_assert_cmpint (s1, ==, 1);
+  /* Low priority FD source shouldn't have been dispatched. */
+  g_assert_false (s2);
+  /* Default priority FD source should have been dispatched. */
+  g_assert_true (s3);
+
+  g_main_loop_unref (loop);
+
+  close (fd1);
+  close (fd2);
+}
+
 #endif
 
 #ifdef G_OS_UNIX
@@ -1783,7 +1845,9 @@ static GSourceFuncs source_funcs = {
   prepare,
   check,
   dispatch,
-  finalize
+  finalize,
+  NULL,
+  NULL
 };
 
 static void
@@ -1859,7 +1923,9 @@ static GSourceFuncs source_with_source_funcs = {
   NULL,
   NULL,
   NULL,
-  finalize_source_with_source
+  finalize_source_with_source,
+  NULL,
+  NULL
 };
 
 static void
@@ -1942,7 +2008,9 @@ static GSourceFuncs source_with_source_funcs_dispatch = {
   NULL,
   NULL,
   dispatch_source_with_source,
-  finalize_source_with_source
+  finalize_source_with_source,
+  NULL,
+  NULL
 };
 
 static void
@@ -2035,6 +2103,7 @@ main (int argc, char *argv[])
   g_test_add_func ("/mainloop/source-unix-fd-api", test_source_unix_fd_api);
   g_test_add_func ("/mainloop/wait", test_mainloop_wait);
   g_test_add_func ("/mainloop/unix-file-poll", test_unix_file_poll);
+  g_test_add_func ("/mainloop/unix-fd-priority", test_unix_fd_priority);
 #endif
   g_test_add_func ("/mainloop/nfds", test_nfds);
 
index dd9b1b4..04b814b 100644 (file)
@@ -76,7 +76,7 @@ start (GMarkupParseContext  *context,
     }
 }
 
-static GMarkupParser parser = { start };
+static GMarkupParser parser = { start, NULL, NULL, NULL, NULL };
 
 struct test
 {
@@ -91,13 +91,14 @@ static struct test tests[] =
   { "<bool mb='y'>", "<bool(1) 1 0 -1>",
     G_MARKUP_ERROR_PARSE, "'bool'" },
 
-  { "<bool mb='false'/>", "<bool(1) 0 0 -1>" },
-  { "<bool mb='true'/>", "<bool(1) 1 0 -1>" },
-  { "<bool mb='t' ob='f' tri='1'/>", "<bool(1) 1 0 1>" },
-  { "<bool mb='y' ob='n' tri='0'/>", "<bool(1) 1 0 0>" },
+  { "<bool mb='false'/>", "<bool(1) 0 0 -1>", 0, NULL },
+  { "<bool mb='true'/>", "<bool(1) 1 0 -1>", 0, NULL },
+  { "<bool mb='t' ob='f' tri='1'/>", "<bool(1) 1 0 1>", 0, NULL },
+  { "<bool mb='y' ob='n' tri='0'/>", "<bool(1) 1 0 0>", 0, NULL },
 
-  { "<bool mb='y' my:attr='q'><my:tag/></bool>", "<bool(1) 1 0 -1>" },
-  { "<bool mb='y' my:attr='q'><my:tag>some <b>text</b> is in here</my:tag></bool>", "<bool(1) 1 0 -1>" },
+  { "<bool mb='y' my:attr='q'><my:tag/></bool>", "<bool(1) 1 0 -1>", 0, NULL },
+  { "<bool mb='y' my:attr='q'><my:tag>some <b>text</b> is in here</my:tag></bool>",
+    "<bool(1) 1 0 -1>", 0, NULL },
 
   { "<bool ob='y'/>", "<bool(0) 0 0 -1>",
     G_MARKUP_ERROR_MISSING_ATTRIBUTE, "'mb'" },
@@ -108,7 +109,7 @@ static struct test tests[] =
   { "<bool mb='y' tri='y' tri='n'/>", "<bool(0) 0 0 -1>",
     G_MARKUP_ERROR_INVALID_CONTENT, "'tri'" },
 
-  { "<str cm='x' am='y'/>", "<str(1) x y (null) (null)>" },
+  { "<str cm='x' am='y'/>", "<str(1) x y (null) (null)>", 0, NULL },
 
   { "<str am='x' co='y'/>", "<str(0) (null) (null) (null) (null)>",
     G_MARKUP_ERROR_MISSING_ATTRIBUTE, "'cm'" },
@@ -165,7 +166,7 @@ test_collect (gconstpointer d)
     }
   else
     {
-      g_assert_error (error, G_MARKUP_ERROR, test->error_code);
+      g_assert_error (error, G_MARKUP_ERROR, (gint) test->error_code);
     }
 
   g_markup_parse_context_free (ctx);
@@ -194,7 +195,7 @@ start_element (GMarkupParseContext  *context,
 }
 
 static GMarkupParser cleanup_parser = {
-  start_element
+  start_element, NULL, NULL, NULL, NULL
 };
 
 static void
@@ -219,14 +220,14 @@ test_cleanup (void)
 int
 main (int argc, char **argv)
 {
-  int i;
+  gsize i;
   gchar *path;
 
   g_test_init (&argc, &argv, NULL);
 
   for (i = 0; i < G_N_ELEMENTS (tests); i++)
     {
-      path = g_strdup_printf ("/markup/collect/%d", i);
+      path = g_strdup_printf ("/markup/collect/%" G_GSIZE_FORMAT, i);
       g_test_add_data_func (path, &tests[i], test_collect);
       g_free (path);
     }
index 2d5de85..44290fe 100644 (file)
@@ -144,21 +144,21 @@ format_test (void)
 
 int main (int argc, char **argv)
 {
-  gint i;
+  gsize i;
   gchar *path;
 
   g_test_init (&argc, &argv, NULL);
 
   for (i = 0; i < G_N_ELEMENTS (escape_tests); i++)
     {
-      path = g_strdup_printf ("/markup/escape-text/%d", i);
+      path = g_strdup_printf ("/markup/escape-text/%" G_GSIZE_FORMAT, i);
       g_test_add_data_func (path, &escape_tests[i], escape_test);
       g_free (path);
     }
 
   for (i = 0; i < G_N_ELEMENTS (unichar_tests); i++)
     {
-      path = g_strdup_printf ("/markup/escape-unichar/%d", i);
+      path = g_strdup_printf ("/markup/escape-unichar/%" G_GSIZE_FORMAT, i);
       g_test_add_data_func (path, &unichar_tests[i], unichar_test);
       g_free (path);
     }
index d1ceffb..71b9ac6 100644 (file)
@@ -265,7 +265,10 @@ end_element (GMarkupParseContext  *context,
 static GMarkupParser parser =
 {
   start_element,
-  end_element
+  end_element,
+  NULL,
+  NULL,
+  NULL
 };
 
 typedef struct
@@ -331,15 +334,15 @@ test (gconstpointer user_data)
 
 TestCase test_cases[] = /* successful runs */
 {
-    /* in */                    /* out */
-  { "<test/>",                  "<test></test>" },
-  { "<sub><foo/></sub>",        "<sub><<{foo}{/foo}>></sub>" },
-  { "<sub><foo/><bar/></sub>",  "<sub><<{foo}{/foo}{bar}{/bar}>></sub>" },
-  { "<foo><bar/></foo>",        "<foo>[[{foo}{bar}{/bar}{/foo}]]</foo>" },
-  { "<foo><x/><y/></foo>",      "<foo>[[{foo}{x}{/x}{y}{/y}{/foo}]]</foo>" },
-  { "<foo/>",                   "<foo>[[{foo}{/foo}]]</foo>" },
+  /* in */                    /* out */                               /* error */
+  { "<test/>",                  "<test></test>",                            NULL },
+  { "<sub><foo/></sub>",        "<sub><<{foo}{/foo}>></sub>",               NULL },
+  { "<sub><foo/><bar/></sub>",  "<sub><<{foo}{/foo}{bar}{/bar}>></sub>",    NULL },
+  { "<foo><bar/></foo>",        "<foo>[[{foo}{bar}{/bar}{/foo}]]</foo>",    NULL },
+  { "<foo><x/><y/></foo>",      "<foo>[[{foo}{x}{/x}{y}{/y}{/foo}]]</foo>", NULL },
+  { "<foo/>",                   "<foo>[[{foo}{/foo}]]</foo>",               NULL },
   { "<sub><foo/></sub><bar/>",  "<sub><<{foo}{/foo}>></sub>"
-                                "<bar>[[{bar}{/bar}]]</bar>" }
+                                "<bar>[[{bar}{/bar}]]</bar>",               NULL }
 };
 
 TestCase error_cases[] = /* error cases */
@@ -356,7 +359,7 @@ TestCase error_cases[] = /* error cases */
 
 #define add_tests(func, basename, array) \
   G_STMT_START { \
-    int __add_tests_i;                                                  \
+    gsize __add_tests_i;                                                \
                                                                         \
     for (__add_tests_i  = 0;                                            \
          __add_tests_i < G_N_ELEMENTS (array);                          \
@@ -364,7 +367,8 @@ TestCase error_cases[] = /* error cases */
       {                                                                 \
         char *testname;                                                 \
                                                                         \
-        testname = g_strdup_printf ("%s/%d", basename, __add_tests_i);  \
+        testname = g_strdup_printf ("%s/%" G_GSIZE_FORMAT,              \
+                                    basename, __add_tests_i);           \
         g_test_add_data_func (testname, &array[__add_tests_i], func);   \
         g_free (testname);                                              \
       }                                                                 \
index a62b95f..22e8023 100644 (file)
@@ -168,7 +168,7 @@ traversal_test (void)
     { G_LEVEL_ORDER, G_TRAVERSE_ALL,        3,  7, "ABFCDEG"     },
     { G_LEVEL_ORDER, G_TRAVERSE_ALL,        3,  8, "ABFCDEG"     },
   };
-  gint i;
+  gsize i;
   CallbackData data;
 
   root = g_node_new (C2P ('A'));
index c341561..8fc8d50 100644 (file)
@@ -173,7 +173,7 @@ thread_func (gpointer data)
 static void
 test_once_init_multi_threaded (void)
 {
-  gint i;
+  gsize i;
   GThread *threads[THREADS];
 
   g_test_summary ("Test g_once_init_{enter,leave}() usage from multiple threads");
index 149d223..ec66e6f 100644 (file)
@@ -111,7 +111,8 @@ test_group_captions (void)
 {
   const gchar *test_name_base[] = { "help", "help-all", "help-test" };
   gchar *test_name;
-  gint i, j;
+  guint i;
+  gsize j;
 
   g_test_bug ("504142");
 
@@ -132,7 +133,7 @@ test_group_captions (void)
           if (g_test_verbose ())
             trap_flags |= G_TEST_SUBPROCESS_INHERIT_STDOUT | G_TEST_SUBPROCESS_INHERIT_STDERR;
 
-          test_name = g_strdup_printf ("/option/group/captions/subprocess/%s-%d",
+          test_name = g_strdup_printf ("/option/group/captions/subprocess/%s-%u",
                                        test_name_base[j], i);
           g_test_trap_subprocess (test_name, 0, trap_flags);
           g_free (test_name);
@@ -942,7 +943,7 @@ callback_test_optional_5 (void)
   gchar **argv_copy;
   int argc;
   GOptionEntry entries [] =
-    { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL },
+    { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL, NULL },
       { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, 
        callback_parse_optional, NULL, NULL },
       { NULL } };
@@ -980,7 +981,7 @@ callback_test_optional_6 (void)
   gchar **argv_copy;
   int argc;
   GOptionEntry entries [] =
-    { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL },
+    { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL, NULL },
       { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, 
        callback_parse_optional, NULL, NULL },
       { NULL } };
@@ -1018,7 +1019,7 @@ callback_test_optional_7 (void)
   gchar **argv_copy;
   int argc;
   GOptionEntry entries [] =
-    { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL },
+    { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL, NULL },
       { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, 
        callback_parse_optional, NULL, NULL },
       { NULL } };
@@ -1056,7 +1057,7 @@ callback_test_optional_8 (void)
   gchar **argv_copy;
   int argc;
   GOptionEntry entries [] =
-    { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL },
+    { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL, NULL },
       { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, 
        callback_parse_optional, NULL, NULL },
       { NULL } };
@@ -1331,8 +1332,8 @@ ignore_test3 (void)
   g_option_context_free (context);
 }
 
-void
-static array_test1 (void)
+static void
+array_test1 (void)
 {
   GOptionContext *context;
   gboolean retval;
@@ -2361,7 +2362,7 @@ option_context_parse_command_line (GOptionContext *context,
   argv_new_len = g_strv_length (argv);
 
   g_strfreev (argv);
-  return success ? argv_len - argv_new_len : -1;
+  return success ? (gint) (argv_len - argv_new_len) : -1;
 }
 
 static void
index 2f3f9e8..70553a8 100644 (file)
@@ -210,28 +210,28 @@ test_equal (gconstpointer d)
 int
 main (int argc, char** argv)
 {
-  gint i;
+  gsize i;
   gchar *path;
 
   g_test_init (&argc, &argv, NULL);
 
   for (i = 0; i < G_N_ELEMENTS (compile_tests); i++)
     {
-      path = g_strdup_printf ("/pattern/compile/%d", i);
+      path = g_strdup_printf ("/pattern/compile/%" G_GSIZE_FORMAT, i);
       g_test_add_data_func (path, &compile_tests[i], test_compilation);
       g_free (path);
     }
 
   for (i = 0; i < G_N_ELEMENTS (match_tests); i++)
     {
-      path = g_strdup_printf ("/pattern/match/%d", i);
+      path = g_strdup_printf ("/pattern/match/%" G_GSIZE_FORMAT, i);
       g_test_add_data_func (path, &match_tests[i], test_match);
       g_free (path);
     }
 
   for (i = 0; i < G_N_ELEMENTS (equal_tests); i++)
     {
-      path = g_strdup_printf ("/pattern/equal/%d", i);
+      path = g_strdup_printf ("/pattern/equal/%" G_GSIZE_FORMAT, i);
       g_test_add_data_func (path, &equal_tests[i], test_equal);
       g_free (path);
     }
index f1e969a..27ebd99 100644 (file)
@@ -246,7 +246,7 @@ test_error (void)
           "/glib/testing/protocol/critical",
           "/glib/testing/protocol/error"
   };
-  gint i;
+  gsize i;
   int             messages = 0;
 
   for (i = 0; i < G_N_ELEMENTS (tests); i++)
index dd9dd21..e778213 100644 (file)
@@ -14,7 +14,7 @@ check_integrity (GQueue *queue)
   GList *last;
   GList *links;
   GList *link;
-  gint n;
+  guint n;
 
   g_assert (queue->length < 4000000000u);
 
@@ -266,7 +266,7 @@ random_test (gconstpointer d)
           break;
         case GET_LENGTH:
           {
-            int l;
+            guint l;
 
             l = g_queue_get_length (q);
 
@@ -416,13 +416,13 @@ random_test (gconstpointer d)
               int n = get_random_position (q, TRUE);
               gpointer elm = g_queue_peek_nth (q, n);
 
-              if (n == q->length - 1)
+              if (n == (int) (q->length - 1))
                 qinf->tail = qinf->tail->prev;
 
               if (n == 0)
                 qinf->head = qinf->head->next;
 
-              if (n >= 0 && n < q->length)
+              if (n >= 0 && (guint) n < q->length)
                 qinf->length--;
 
               g_assert (elm == g_queue_pop_nth (q, n));
@@ -450,7 +450,7 @@ random_test (gconstpointer d)
             {
               GList *list;
               int n = get_random_position (q, TRUE);
-              if (n < 0 || n >= q->length)
+              if (n < 0 || (guint) n >= q->length)
                 {
                   g_assert (g_queue_peek_nth (q, n) == NULL);
                 }
@@ -637,7 +637,7 @@ random_test (gconstpointer d)
             {
               int n = get_random_position (q, FALSE);
 
-              if (n == g_queue_get_length (q) - 1)
+              if (n == (int) (g_queue_get_length (q) - 1))
                 qinf->tail = qinf->tail->prev;
 
               if (n == 0)
index 73126c7..fe10075 100644 (file)
@@ -241,7 +241,7 @@ test_rcbox_alignment (void)
     sizeof (gint32) * 3,
   };
 
-  int i;
+  gsize i;
 
   for (i = 0; i < G_N_ELEMENTS (block_sizes); i++)
     {
@@ -265,7 +265,7 @@ test_atomic_rcbox_alignment (void)
     sizeof (gint32) * 3,
   };
 
-  int i;
+  gsize i;
 
   for (i = 0; i < G_N_ELEMENTS (block_sizes); i++)
     {
index 1ea6f92..c57bd8c 100644 (file)
@@ -1305,8 +1305,7 @@ test_match_all (gconstpointer d)
   GMatchInfo *match_info;
   GSList *l_exp;
   gboolean match_ok;
-  gint match_count;
-  gint i;
+  guint i, match_count;
 
   regex = g_regex_new (data->pattern, 0, 0, NULL);
   match_ok = g_regex_match_all (regex, data->string, 0, &match_info);
@@ -1317,6 +1316,7 @@ test_match_all (gconstpointer d)
     g_assert (match_ok);
 
   match_count = g_match_info_get_match_count (match_info);
+  g_assert_cmpint (match_count, >=, 0);
 
   if (match_count != g_slist_length (data->expected))
     {
@@ -1331,7 +1331,7 @@ test_match_all (gconstpointer d)
 
           matched_string = g_match_info_fetch (match_info, i);
           g_match_info_fetch_pos (match_info, i, &start, &end);
-          g_message ("%d. %d-%d '%s'", i, start, end, matched_string);
+          g_message ("%u. %d-%d '%s'", i, start, end, matched_string);
           g_free (matched_string);
         }
 
@@ -1342,11 +1342,11 @@ test_match_all (gconstpointer d)
         {
           Match *exp = l_exp->data;
 
-          g_message ("%d. %d-%d '%s'", i, exp->start, exp->end, exp->string);
+          g_message ("%u. %d-%d '%s'", i, exp->start, exp->end, exp->string);
           i++;
         }
 
-      g_error ("match_count not as expected: %d != %d",
+      g_error ("match_count not as expected: %u != %d",
           match_count, g_slist_length (data->expected));
     }
 
index a8c6879..6813184 100644 (file)
@@ -111,8 +111,8 @@ test_scanner_tokens (ScannerFixture *fix,
   gchar buf[] = "(\t\n\r\\){}";
   const gint buflen = strlen (buf);
   gchar tokbuf[] = "(\\){}";
-  const gint tokbuflen = strlen (tokbuf);
-  guint i;
+  const gsize tokbuflen = strlen (tokbuf);
+  gsize i;
 
   g_scanner_input_text (fix->scanner, buf, buflen);
 
index db7d2a5..c2eba2c 100644 (file)
@@ -15,7 +15,7 @@ struct _GSequence
 
 struct _GSequenceNode
 {
-  gint                  n_nodes;
+  guint                 n_nodes;
   GSequenceNode *       parent;
   GSequenceNode *       left;
   GSequenceNode *       right;
@@ -99,7 +99,7 @@ typedef struct SequenceInfo
 {
   GQueue *      queue;
   GSequence *   sequence;
-  int           n_items;
+  guint         n_items;
 } SequenceInfo;
 
 typedef struct
@@ -137,7 +137,7 @@ check_integrity (SequenceInfo *info)
              g_sequence_get_length (info->sequence), info->n_items);
 #endif
   g_assert (info->n_items == g_queue_get_length (info->queue));
-  g_assert (g_sequence_get_length (info->sequence) == info->n_items);
+  g_assert ((guint) g_sequence_get_length (info->sequence) == info->n_items);
 
   iter = g_sequence_get_begin_iter (info->sequence);
   list = info->queue->head;
@@ -155,7 +155,7 @@ check_integrity (SequenceInfo *info)
     }
 
   g_assert (info->n_items == g_queue_get_length (info->queue));
-  g_assert (g_sequence_get_length (info->sequence) == info->n_items);
+  g_assert ((guint) g_sequence_get_length (info->sequence) == info->n_items);
 }
 
 static gpointer
@@ -551,7 +551,7 @@ run_random_tests (gconstpointer d)
           {
             int i;
 
-            g_assert (g_queue_get_length (seq->queue) == g_sequence_get_length (seq->sequence));
+            g_assert (g_queue_get_length (seq->queue) == (guint) g_sequence_get_length (seq->sequence));
 
             for (i = 0; i < 10; ++i)
               {
@@ -1387,7 +1387,7 @@ int
 main (int argc,
       char **argv)
 {
-  gint i;
+  gsize i;
   guint32 seed;
   gchar *path;
 
index 1ed356e..5cde371 100644 (file)
@@ -186,28 +186,28 @@ do_unquote_test (gconstpointer d)
 int
 main (int   argc, char *argv[])
 {
-  gint i;
+  gsize i;
   gchar *path;
 
   g_test_init (&argc, &argv, NULL);
 
   for (i = 0; i < G_N_ELEMENTS (cmdline_tests); i++)
     {
-      path = g_strdup_printf ("/shell/cmdline/%d", i);
+      path = g_strdup_printf ("/shell/cmdline/%" G_GSIZE_FORMAT, i);
       g_test_add_data_func (path, &cmdline_tests[i], do_cmdline_test);
       g_free (path);
     }
 
   for (i = 0; i < G_N_ELEMENTS (quote_tests); i++)
     {
-      path = g_strdup_printf ("/shell/quote/%d", i);
+      path = g_strdup_printf ("/shell/quote/%" G_GSIZE_FORMAT, i);
       g_test_add_data_func (path, &quote_tests[i], do_quote_test);
       g_free (path);
     }
 
   for (i = 0; i < G_N_ELEMENTS (unquote_tests); i++)
     {
-      path = g_strdup_printf ("/shell/unquote/%d", i);
+      path = g_strdup_printf ("/shell/unquote/%" G_GSIZE_FORMAT, i);
       g_test_add_data_func (path, &unquote_tests[i], do_unquote_test);
       g_free (path);
     }
index b0ad3da..a566280 100644 (file)
@@ -107,7 +107,7 @@ thread_allocate (gpointer data)
   gint b;
   gint size;
   gpointer p;
-  volatile gpointer *loc;
+  gpointer *loc;  /* (atomic) */
 
   for (i = 0; i < 10000; i++)
     {
@@ -137,7 +137,7 @@ test_allocate (void)
 {
   GThread *threads[30];
   gint size;
-  gint i;
+  gsize i;
 
   for (i = 0; i < 30; i++)
     for (size = 1; size <= 4096; size++)
index 99f99b4..bf2c8a5 100644 (file)
@@ -31,7 +31,7 @@ static char *echo_prog_path;
 static void
 multithreaded_test_run (GThreadFunc function)
 {
-  int i;
+  guint i;
   GPtrArray *threads = g_ptr_array_new ();
   guint n_threads;
 
@@ -42,7 +42,7 @@ multithreaded_test_run (GThreadFunc function)
     {
       GThread *thread;
 
-      thread = g_thread_new ("test", function, GINT_TO_POINTER (i));
+      thread = g_thread_new ("test", function, GUINT_TO_POINTER (i));
       g_ptr_array_add (threads, thread);
     }
 
@@ -50,7 +50,7 @@ multithreaded_test_run (GThreadFunc function)
     {
       gpointer ret;
       ret = g_thread_join (g_ptr_array_index (threads, i));
-      g_assert_cmpint (GPOINTER_TO_INT (ret), ==, i);
+      g_assert_cmpint (GPOINTER_TO_UINT (ret), ==, i);
     }
   g_ptr_array_free (threads, TRUE);
 }
@@ -58,14 +58,14 @@ multithreaded_test_run (GThreadFunc function)
 static gpointer
 test_spawn_sync_multithreaded_instance (gpointer data)
 {
-  int tnum = GPOINTER_TO_INT (data);
+  guint tnum = GPOINTER_TO_UINT (data);
   GError *error = NULL;
   GPtrArray *argv;
   char *arg;
   char *stdout_str;
   int estatus;
 
-  arg = g_strdup_printf ("thread %d", tnum);
+  arg = g_strdup_printf ("thread %u", tnum);
 
   argv = g_ptr_array_new ();
   g_ptr_array_add (argv, echo_prog_path);
@@ -79,7 +79,7 @@ test_spawn_sync_multithreaded_instance (gpointer data)
   g_free (stdout_str);
   g_ptr_array_free (argv, TRUE);
 
-  return GINT_TO_POINTER (tnum);
+  return GUINT_TO_POINTER (tnum);
 }
 
 static void
@@ -147,7 +147,7 @@ on_child_stdout (GIOChannel   *channel,
 static gpointer
 test_spawn_async_multithreaded_instance (gpointer thread_data)
 {
-  int tnum = GPOINTER_TO_INT (thread_data);
+  guint tnum = GPOINTER_TO_UINT (thread_data);
   GError *error = NULL;
   GPtrArray *argv;
   char *arg;
@@ -162,7 +162,7 @@ test_spawn_async_multithreaded_instance (gpointer thread_data)
   context = g_main_context_new ();
   loop = g_main_loop_new (context, TRUE);
 
-  arg = g_strdup_printf ("thread %d", tnum);
+  arg = g_strdup_printf ("thread %u", tnum);
 
   argv = g_ptr_array_new ();
   g_ptr_array_add (argv, echo_prog_path);
@@ -203,7 +203,7 @@ test_spawn_async_multithreaded_instance (gpointer thread_data)
 
   g_free (arg);
 
-  return GINT_TO_POINTER (tnum);
+  return GUINT_TO_POINTER (tnum);
 }
 
 static void
index ab449eb..c4417fe 100644 (file)
@@ -179,7 +179,7 @@ test_spawn_async_with_fds (void)
   int tnum = 1;
   GPtrArray *argv;
   char *arg;
-  int i;
+  gsize i;
 
   /* Each test has 3 variable parameters: stdin, stdout, stderr */
   enum fd_type {
index 3947fdf..37cbc5a 100644 (file)
@@ -525,9 +525,7 @@ test_strdupv (void)
 
   copy = g_strdupv (vec);
   g_assert_nonnull (copy);
-  g_assert_cmpstr (copy[0], ==, "Foo");
-  g_assert_cmpstr (copy[1], ==, "Bar");
-  g_assert_null (copy[2]);
+  g_assert_cmpstrv (copy, vec);
   g_strfreev (copy);
 }
 
index 07820f6..cc6afe5 100644 (file)
@@ -115,10 +115,15 @@ main (int   argc,
   else if (g_strcmp0 (argv1, "skip-options") == 0)
     {
       /* The caller is expected to skip some of these with
-       * -p, -s and/or --GTestSkipCount */
+       * -p/-r, -s/-x and/or --GTestSkipCount */
       g_test_add_func ("/a", test_pass);
+      g_test_add_func ("/b", test_pass);
       g_test_add_func ("/b/a", test_pass);
       g_test_add_func ("/b/b", test_pass);
+      g_test_add_func ("/b/b/a", test_pass);
+      g_test_add_func ("/prefix/a", test_pass);
+      g_test_add_func ("/prefix/b/b", test_pass);
+      g_test_add_func ("/prefix-long/a", test_pass);
       g_test_add_func ("/c/a", test_pass);
       g_test_add_func ("/d/a", test_pass);
     }
index ed4c8d6..29551b9 100644 (file)
@@ -67,6 +67,40 @@ test_assertions_bad_cmpvariant_values (void)
 }
 
 static void
+test_assertions_bad_cmpstrv_null1 (void)
+{
+  const char *strv[] = { "one", "two", "three", NULL };
+  g_assert_cmpstrv (strv, NULL);
+  exit (0);
+}
+
+static void
+test_assertions_bad_cmpstrv_null2 (void)
+{
+  const char *strv[] = { "one", "two", "three", NULL };
+  g_assert_cmpstrv (NULL, strv);
+  exit (0);
+}
+
+static void
+test_assertions_bad_cmpstrv_length (void)
+{
+  const char *strv1[] = { "one", "two", "three", NULL };
+  const char *strv2[] = { "one", "two", NULL };
+  g_assert_cmpstrv (strv1, strv2);
+  exit (0);
+}
+
+static void
+test_assertions_bad_cmpstrv_values (void)
+{
+  const char *strv1[] = { "one", "two", "three", NULL };
+  const char *strv2[] = { "one", "too", "three", NULL };
+  g_assert_cmpstrv (strv1, strv2);
+  exit (0);
+}
+
+static void
 test_assertions_bad_cmpstr (void)
 {
   g_assert_cmpstr ("fzz", !=, "fzz");
@@ -132,6 +166,8 @@ test_assertions_bad_no_errno (void)
 static void
 test_assertions (void)
 {
+  const char *strv1[] = { "one", "two", "three", NULL };
+  const char *strv2[] = { "one", "two", "three", NULL };
   GVariant *v1, *v2;
   gchar *fuu;
 
@@ -160,6 +196,9 @@ test_assertions (void)
   g_assert_cmpmem ("foo", 0, NULL, 0);
   g_assert_no_errno (return_no_errno ());
 
+  g_assert_cmpstrv (NULL, NULL);
+  g_assert_cmpstrv (strv1, strv2);
+
   v1 = g_variant_new_parsed ("['hello', 'there']");
   v2 = g_variant_new_parsed ("['hello', 'there']");
 
@@ -181,6 +220,22 @@ test_assertions (void)
   g_test_trap_assert_failed ();
   g_test_trap_assert_stderr ("*assertion failed*");
 
+  g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpstrv_null1", 0, 0);
+  g_test_trap_assert_failed ();
+  g_test_trap_assert_stderr ("*assertion failed*");
+
+  g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpstrv_null2", 0, 0);
+  g_test_trap_assert_failed ();
+  g_test_trap_assert_stderr ("*assertion failed*");
+
+  g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpstrv_length", 0, 0);
+  g_test_trap_assert_failed ();
+  g_test_trap_assert_stderr ("*assertion failed*");
+
+  g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpstrv_values", 0, 0);
+  g_test_trap_assert_failed ();
+  g_test_trap_assert_stderr ("*assertion failed*");
+
   g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpint", 0, 0);
   g_test_trap_assert_failed ();
   g_test_trap_assert_stderr ("*assertion failed*");
@@ -1118,12 +1173,17 @@ test_tap (void)
                 NULL, NULL, &output, NULL, &status,
                 &error);
   g_assert_no_error (error);
-  g_assert_nonnull (strstr (output, "1..5\n"));
+  g_assert_nonnull (strstr (output, "1..10\n"));
   g_assert_nonnull (strstr (output, "\nok 1 /a # SKIP\n"));
-  g_assert_nonnull (strstr (output, "\nok 2 /b/a # SKIP\n"));
-  g_assert_nonnull (strstr (output, "\nok 3 /b/b\n"));
-  g_assert_nonnull (strstr (output, "\nok 4 /c/a\n"));
-  g_assert_nonnull (strstr (output, "\nok 5 /d/a\n"));
+  g_assert_nonnull (strstr (output, "\nok 2 /b # SKIP\n"));
+  g_assert_nonnull (strstr (output, "\nok 3 /b/a\n"));
+  g_assert_nonnull (strstr (output, "\nok 4 /b/b\n"));
+  g_assert_nonnull (strstr (output, "\nok 5 /b/b/a\n"));
+  g_assert_nonnull (strstr (output, "\nok 6 /prefix/a\n"));
+  g_assert_nonnull (strstr (output, "\nok 7 /prefix/b/b\n"));
+  g_assert_nonnull (strstr (output, "\nok 8 /prefix-long/a\n"));
+  g_assert_nonnull (strstr (output, "\nok 9 /c/a\n"));
+  g_assert_nonnull (strstr (output, "\nok 10 /d/a\n"));
 
   g_spawn_check_exit_status (status, &error);
   g_assert_no_error (error);
@@ -1145,12 +1205,17 @@ test_tap (void)
                 NULL, NULL, &output, NULL, &status,
                 &error);
   g_assert_no_error (error);
-  g_assert_nonnull (strstr (output, "1..5\n"));
+  g_assert_nonnull (strstr (output, "1..10\n"));
   g_assert_nonnull (strstr (output, "\nok 1 /a\n"));
-  g_assert_nonnull (strstr (output, "\nok 2 /b/a\n"));
-  g_assert_nonnull (strstr (output, "\nok 3 /b/b\n"));
-  g_assert_nonnull (strstr (output, "\nok 4 /c/a\n"));
-  g_assert_nonnull (strstr (output, "\nok 5 /d/a\n"));
+  g_assert_nonnull (strstr (output, "\nok 2 /b\n"));
+  g_assert_nonnull (strstr (output, "\nok 3 /b/a\n"));
+  g_assert_nonnull (strstr (output, "\nok 4 /b/b\n"));
+  g_assert_nonnull (strstr (output, "\nok 5 /b/b/a\n"));
+  g_assert_nonnull (strstr (output, "\nok 6 /prefix/a\n"));
+  g_assert_nonnull (strstr (output, "\nok 7 /prefix/b/b\n"));
+  g_assert_nonnull (strstr (output, "\nok 8 /prefix-long/a\n"));
+  g_assert_nonnull (strstr (output, "\nok 9 /c/a\n"));
+  g_assert_nonnull (strstr (output, "\nok 10 /d/a\n"));
 
   g_spawn_check_exit_status (status, &error);
   g_assert_no_error (error);
@@ -1164,7 +1229,7 @@ test_tap (void)
   g_ptr_array_add (argv, "skip-options");
   g_ptr_array_add (argv, "--tap");
   g_ptr_array_add (argv, "--GTestSkipCount");
-  g_ptr_array_add (argv, "6");
+  g_ptr_array_add (argv, "11");
   g_ptr_array_add (argv, NULL);
 
   g_spawn_sync (NULL, (char **) argv->pdata, NULL,
@@ -1172,12 +1237,17 @@ test_tap (void)
                 NULL, NULL, &output, NULL, &status,
                 &error);
   g_assert_no_error (error);
-  g_assert_nonnull (strstr (output, "1..5\n"));
+  g_assert_nonnull (strstr (output, "1..10\n"));
   g_assert_nonnull (strstr (output, "\nok 1 /a # SKIP\n"));
-  g_assert_nonnull (strstr (output, "\nok 2 /b/a # SKIP\n"));
-  g_assert_nonnull (strstr (output, "\nok 3 /b/b # SKIP\n"));
-  g_assert_nonnull (strstr (output, "\nok 4 /c/a # SKIP\n"));
-  g_assert_nonnull (strstr (output, "\nok 5 /d/a # SKIP\n"));
+  g_assert_nonnull (strstr (output, "\nok 2 /b # SKIP\n"));
+  g_assert_nonnull (strstr (output, "\nok 3 /b/a # SKIP\n"));
+  g_assert_nonnull (strstr (output, "\nok 4 /b/b # SKIP\n"));
+  g_assert_nonnull (strstr (output, "\nok 5 /b/b/a # SKIP\n"));
+  g_assert_nonnull (strstr (output, "\nok 6 /prefix/a # SKIP\n"));
+  g_assert_nonnull (strstr (output, "\nok 7 /prefix/b/b # SKIP\n"));
+  g_assert_nonnull (strstr (output, "\nok 8 /prefix-long/a # SKIP\n"));
+  g_assert_nonnull (strstr (output, "\nok 9 /c/a # SKIP\n"));
+  g_assert_nonnull (strstr (output, "\nok 10 /d/a # SKIP\n"));
 
   g_spawn_check_exit_status (status, &error);
   g_assert_no_error (error);
@@ -1205,9 +1275,10 @@ test_tap (void)
   g_assert_no_error (error);
   g_assert_nonnull (strstr (output, "\nok 1 /c/a\n"));
   g_assert_nonnull (strstr (output, "\nok 2 /c/a\n"));
-  g_assert_nonnull (strstr (output, "\nok 3 /b/a\n"));
-  g_assert_nonnull (strstr (output, "\nok 4 /b/b\n"));
-  g_assert_nonnull (strstr (output, "\n1..4\n"));
+  g_assert_nonnull (strstr (output, "\nok 3 /b\n"));
+  g_assert_nonnull (strstr (output, "\nok 4 /b/a\n"));
+  g_assert_nonnull (strstr (output, "\nok 5 /b/b\n"));
+  g_assert_nonnull (strstr (output, "\n1..5\n"));
 
   g_spawn_check_exit_status (status, &error);
   g_assert_no_error (error);
@@ -1215,6 +1286,90 @@ test_tap (void)
   g_free (output);
   g_ptr_array_unref (argv);
 
+  g_test_message ("--run-prefix");
+  argv = g_ptr_array_new ();
+  g_ptr_array_add (argv, (char *) testing_helper);
+  g_ptr_array_add (argv, "skip-options");
+  g_ptr_array_add (argv, "--tap");
+  g_ptr_array_add (argv, "-r");
+  g_ptr_array_add (argv, "/c/a");
+  g_ptr_array_add (argv, "-r");
+  g_ptr_array_add (argv, "/c/a");
+  g_ptr_array_add (argv, "--run-prefix");
+  g_ptr_array_add (argv, "/b");
+  g_ptr_array_add (argv, NULL);
+
+  g_spawn_sync (NULL, (char **) argv->pdata, NULL,
+                G_SPAWN_STDERR_TO_DEV_NULL,
+                NULL, NULL, &output, NULL, &status,
+                &error);
+  g_assert_no_error (error);
+  g_assert_nonnull (strstr (output, "\nok 1 /c/a\n"));
+  g_assert_nonnull (strstr (output, "\nok 2 /c/a\n"));
+  g_assert_nonnull (strstr (output, "\nok 3 /b\n"));
+  g_assert_nonnull (strstr (output, "\nok 4 /b/a\n"));
+  g_assert_nonnull (strstr (output, "\nok 5 /b/b\n"));
+  g_assert_nonnull (strstr (output, "\nok 6 /b/b/a\n"));
+  g_assert_nonnull (strstr (output, "\n1..6\n"));
+
+  g_spawn_check_exit_status (status, &error);
+  g_assert_no_error (error);
+
+  g_free (output);
+  g_ptr_array_unref (argv);
+
+  g_test_message ("--run-prefix 2");
+  argv = g_ptr_array_new ();
+  g_ptr_array_add (argv, (char *) testing_helper);
+  g_ptr_array_add (argv, "skip-options");
+  g_ptr_array_add (argv, "--tap");
+  g_ptr_array_add (argv, "-r");
+  g_ptr_array_add (argv, "/pre");
+  g_ptr_array_add (argv, "--run-prefix");
+  g_ptr_array_add (argv, "/b/b");
+  g_ptr_array_add (argv, NULL);
+
+  g_spawn_sync (NULL, (char **) argv->pdata, NULL,
+                G_SPAWN_STDERR_TO_DEV_NULL,
+                NULL, NULL, &output, NULL, &status,
+                &error);
+  g_assert_no_error (error);
+  g_assert_nonnull (strstr (output, "\nok 1 /b/b\n"));
+  g_assert_nonnull (strstr (output, "\nok 2 /b/b/a\n"));
+  g_assert_nonnull (strstr (output, "\n1..2\n"));
+
+  g_spawn_check_exit_status (status, &error);
+  g_assert_no_error (error);
+
+  g_free (output);
+  g_ptr_array_unref (argv);
+
+  g_test_message ("--run-prefix conflict");
+  argv = g_ptr_array_new ();
+  g_ptr_array_add (argv, (char *) testing_helper);
+  g_ptr_array_add (argv, "skip-options");
+  g_ptr_array_add (argv, "--tap");
+  g_ptr_array_add (argv, "-r");
+  g_ptr_array_add (argv, "/c/a");
+  g_ptr_array_add (argv, "-p");
+  g_ptr_array_add (argv, "/c/a");
+  g_ptr_array_add (argv, "--run-prefix");
+  g_ptr_array_add (argv, "/b");
+  g_ptr_array_add (argv, NULL);
+
+  g_spawn_sync (NULL, (char **) argv->pdata, NULL,
+                G_SPAWN_STDERR_TO_DEV_NULL,
+                NULL, NULL, &output, NULL, &status,
+                &error);
+  g_assert_no_error (error);
+  g_spawn_check_exit_status (status, &error);
+  g_assert_nonnull (error);
+  g_assert_nonnull (strstr (output, "do not mix [-r | --run-prefix] with '-p'\n"));
+  g_clear_error (&error);
+
+  g_free (output);
+  g_ptr_array_unref (argv);
+
   g_test_message ("-s");
   argv = g_ptr_array_new ();
   g_ptr_array_add (argv, (char *) testing_helper);
@@ -1225,6 +1380,8 @@ test_tap (void)
   g_ptr_array_add (argv, "-s");
   g_ptr_array_add (argv, "/b");
   g_ptr_array_add (argv, "-s");
+  g_ptr_array_add (argv, "/pre");
+  g_ptr_array_add (argv, "-s");
   g_ptr_array_add (argv, "/c/a");
   g_ptr_array_add (argv, NULL);
 
@@ -1233,20 +1390,88 @@ test_tap (void)
                 NULL, NULL, &output, NULL, &status,
                 &error);
   g_assert_no_error (error);
-  g_assert_nonnull (strstr (output, "1..5\n"));
+  g_assert_nonnull (strstr (output, "1..10\n"));
   g_assert_nonnull (strstr (output, "\nok 1 /a # SKIP by request"));
+  g_assert_nonnull (strstr (output, "\nok 2 /b # SKIP by request"));
   /* "-s /b" would skip a test named exactly /b, but not a test named
    * /b/anything */
-  g_assert_nonnull (strstr (output, "\nok 2 /b/a\n"));
-  g_assert_nonnull (strstr (output, "\nok 3 /b/b\n"));
-  g_assert_nonnull (strstr (output, "\nok 4 /c/a # SKIP by request"));
-  g_assert_nonnull (strstr (output, "\nok 5 /d/a\n"));
+  g_assert_nonnull (strstr (output, "\nok 3 /b/a\n"));
+  g_assert_nonnull (strstr (output, "\nok 4 /b/b\n"));
+  g_assert_nonnull (strstr (output, "\nok 5 /b/b/a\n"));
+  g_assert_nonnull (strstr (output, "\nok 6 /prefix/a\n"));
+  g_assert_nonnull (strstr (output, "\nok 7 /prefix/b/b\n"));
+  g_assert_nonnull (strstr (output, "\nok 8 /prefix-long/a\n"));
+  g_assert_nonnull (strstr (output, "\nok 9 /c/a # SKIP by request"));
+  g_assert_nonnull (strstr (output, "\nok 10 /d/a\n"));
 
   g_spawn_check_exit_status (status, &error);
   g_assert_no_error (error);
 
   g_free (output);
   g_ptr_array_unref (argv);
+
+  g_test_message ("--skip-prefix");
+  argv = g_ptr_array_new ();
+  g_ptr_array_add (argv, (char *) testing_helper);
+  g_ptr_array_add (argv, "skip-options");
+  g_ptr_array_add (argv, "--tap");
+  g_ptr_array_add (argv, "-x");
+  g_ptr_array_add (argv, "/a");
+  g_ptr_array_add (argv, "--skip-prefix");
+  g_ptr_array_add (argv, "/pre");
+  g_ptr_array_add (argv, "-x");
+  g_ptr_array_add (argv, "/c/a");
+  g_ptr_array_add (argv, NULL);
+
+  g_spawn_sync (NULL, (char **) argv->pdata, NULL,
+                G_SPAWN_STDERR_TO_DEV_NULL,
+                NULL, NULL, &output, NULL, &status,
+                &error);
+  g_assert_no_error (error);
+  g_assert_nonnull (strstr (output, "1..10\n"));
+  g_assert_nonnull (strstr (output, "\nok 1 /a # SKIP by request"));
+  g_assert_nonnull (strstr (output, "\nok 2 /b\n"));
+  g_assert_nonnull (strstr (output, "\nok 3 /b/a\n"));
+  g_assert_nonnull (strstr (output, "\nok 4 /b/b\n"));
+  g_assert_nonnull (strstr (output, "\nok 5 /b/b/a\n"));
+  /* "--skip-prefix /pre" will skip all test path which begins with /pre */
+  g_assert_nonnull (strstr (output, "\nok 6 /prefix/a # SKIP by request"));
+  g_assert_nonnull (strstr (output, "\nok 7 /prefix/b/b # SKIP by request"));
+  g_assert_nonnull (strstr (output, "\nok 8 /prefix-long/a # SKIP by request"));
+  g_assert_nonnull (strstr (output, "\nok 9 /c/a # SKIP by request"));
+  g_assert_nonnull (strstr (output, "\nok 10 /d/a\n"));
+
+  g_spawn_check_exit_status (status, &error);
+  g_assert_no_error (error);
+
+  g_free (output);
+  g_ptr_array_unref (argv);
+
+  g_test_message ("--skip-prefix conflict");
+  argv = g_ptr_array_new ();
+  g_ptr_array_add (argv, (char *) testing_helper);
+  g_ptr_array_add (argv, "skip-options");
+  g_ptr_array_add (argv, "--tap");
+  g_ptr_array_add (argv, "-s");
+  g_ptr_array_add (argv, "/a");
+  g_ptr_array_add (argv, "--skip-prefix");
+  g_ptr_array_add (argv, "/pre");
+  g_ptr_array_add (argv, "-x");
+  g_ptr_array_add (argv, "/c/a");
+  g_ptr_array_add (argv, NULL);
+
+  g_spawn_sync (NULL, (char **) argv->pdata, NULL,
+                G_SPAWN_STDERR_TO_DEV_NULL,
+                NULL, NULL, &output, NULL, &status,
+                &error);
+  g_assert_no_error (error);
+  g_spawn_check_exit_status (status, &error);
+  g_assert_nonnull (error);
+  g_assert_nonnull (strstr (output, "do not mix [-x | --skip-prefix] with '-s'\n"));
+  g_clear_error (&error);
+
+  g_free (output);
+  g_ptr_array_unref (argv);
 }
 
 static void
@@ -1303,6 +1528,10 @@ main (int   argc,
   g_test_add_func ("/misc/assertions/subprocess/bad_cmpvariant_types", test_assertions_bad_cmpvariant_types);
   g_test_add_func ("/misc/assertions/subprocess/bad_cmpvariant_values", test_assertions_bad_cmpvariant_values);
   g_test_add_func ("/misc/assertions/subprocess/bad_cmpstr", test_assertions_bad_cmpstr);
+  g_test_add_func ("/misc/assertions/subprocess/bad_cmpstrv_null1", test_assertions_bad_cmpstrv_null1);
+  g_test_add_func ("/misc/assertions/subprocess/bad_cmpstrv_null2", test_assertions_bad_cmpstrv_null2);
+  g_test_add_func ("/misc/assertions/subprocess/bad_cmpstrv_length", test_assertions_bad_cmpstrv_length);
+  g_test_add_func ("/misc/assertions/subprocess/bad_cmpstrv_values", test_assertions_bad_cmpstrv_values);
   g_test_add_func ("/misc/assertions/subprocess/bad_cmpint", test_assertions_bad_cmpint);
   g_test_add_func ("/misc/assertions/subprocess/bad_cmpmem_len", test_assertions_bad_cmpmem_len);
   g_test_add_func ("/misc/assertions/subprocess/bad_cmpmem_data", test_assertions_bad_cmpmem_data);
index 47f00ba..fc836f3 100644 (file)
@@ -126,6 +126,8 @@ test_far_future_ready_time (void)
   n_fds = 0;
   n_fds = g_main_context_query (context, priority, &timeout_, NULL, n_fds);
 
+  g_assert_cmpint (n_fds, >=, 0);
+
   /* The true timeout in milliseconds doesn't fit into a gint. We definitely
    * don't want poll() to block forever:
    */
index 149b3af..e805ef5 100644 (file)
@@ -208,7 +208,7 @@ test_timeval_from_iso8601 (void)
   };
   GTimeVal out;
   gboolean success;
-  gint i;
+  gsize i;
 
   /* Always run in UTC so the comparisons of parsed values are valid. */
   if (!g_setenv ("TZ", "UTC", TRUE))
@@ -250,7 +250,7 @@ test_timeval_to_iso8601 (void)
     { { 657454877, 0 }, "1990-11-01T10:21:17Z" },
     { { 17, 123400 }, "1970-01-01T00:00:17.123400Z" }
   };
-  gint i;
+  gsize i;
   gchar *out;
   GTimeVal val;
   gboolean ret;
index 5bf7bd3..8811d96 100644 (file)
@@ -333,7 +333,7 @@ static void
 test_tree_traverse (void)
 {
   GTree *tree;
-  gint i;
+  gsize i;
   TraverseData orders[] = {
     { G_IN_ORDER,   -1, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" },
     { G_IN_ORDER,    1, "0" },
index b8a0c6a..2c61038 100644 (file)
@@ -32,59 +32,59 @@ typedef struct
   char *filename;
   char *hostname;
   char *expected_result;
-  GConvertError expected_error; /* If failed */
+  gint expected_error; /* If failed */
 } FileToUriTest;
 
 FileToUriTest
 file_to_uri_tests[] = {
-  { "/etc", NULL, "file:///etc"},
-  { "/etc", "", "file:///etc"},
-  { "/etc", "otherhost", "file://otherhost/etc"},
+  { "/etc", NULL, "file:///etc", 0 },
+  { "/etc", "", "file:///etc", 0 },
+  { "/etc", "otherhost", "file://otherhost/etc", 0 },
 #ifdef G_OS_WIN32
-  { "/etc", "localhost", "file:///etc"},
-  { "c:\\windows", NULL, "file:///c:/windows"},
-  { "c:\\windows", "localhost", "file:///c:/windows"},
-  { "c:\\windows", "otherhost", "file://otherhost/c:/windows"},
-  { "\\\\server\\share\\dir", NULL, "file:////server/share/dir"},
-  { "\\\\server\\share\\dir", "localhost", "file:////server/share/dir"},
+  { "/etc", "localhost", "file:///etc", 0 },
+  { "c:\\windows", NULL, "file:///c:/windows", 0 },
+  { "c:\\windows", "localhost", "file:///c:/windows", 0 },
+  { "c:\\windows", "otherhost", "file://otherhost/c:/windows", 0 },
+  { "\\\\server\\share\\dir", NULL, "file:////server/share/dir", 0 },
+  { "\\\\server\\share\\dir", "localhost", "file:////server/share/dir", 0 },
 #else
-  { "/etc", "localhost", "file://localhost/etc"},
+  { "/etc", "localhost", "file://localhost/etc", 0 },
   { "c:\\windows", NULL, NULL, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH}, /* it's important to get this error on Unix */
   { "c:\\windows", "localhost", NULL, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH},
   { "c:\\windows", "otherhost", NULL, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH},
 #endif
   { "etc", "localhost", NULL, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH},
 #ifndef G_PLATFORM_WIN32
-  { "/etc/\xE5\xE4\xF6", NULL, "file:///etc/%E5%E4%F6" },
-  { "/etc/\xC3\xB6\xC3\xA4\xC3\xA5", NULL, "file:///etc/%C3%B6%C3%A4%C3%A5"},
+  { "/etc/\xE5\xE4\xF6", NULL, "file:///etc/%E5%E4%F6", 0 },
+  { "/etc/\xC3\xB6\xC3\xA4\xC3\xA5", NULL, "file:///etc/%C3%B6%C3%A4%C3%A5", 0 },
 #endif
   { "/etc", "\xC3\xB6\xC3\xA4\xC3\xA5", NULL, G_CONVERT_ERROR_ILLEGAL_SEQUENCE},
   { "/etc", "\xE5\xE4\xF6", NULL, G_CONVERT_ERROR_ILLEGAL_SEQUENCE},
-  { "/etc/file with #%", NULL, "file:///etc/file%20with%20%23%25"},
+  { "/etc/file with #%", NULL, "file:///etc/file%20with%20%23%25", 0 },
   { "", NULL, NULL, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH},
   { "", "", NULL, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH},
   { "", "localhost", NULL, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH},
   { "", "otherhost", NULL, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH},
-  { "/0123456789", NULL, "file:///0123456789"},
-  { "/ABCDEFGHIJKLMNOPQRSTUVWXYZ", NULL, "file:///ABCDEFGHIJKLMNOPQRSTUVWXYZ"},
-  { "/abcdefghijklmnopqrstuvwxyz", NULL, "file:///abcdefghijklmnopqrstuvwxyz"},
-  { "/-_.!~*'()", NULL, "file:///-_.!~*'()"},
+  { "/0123456789", NULL, "file:///0123456789", 0 },
+  { "/ABCDEFGHIJKLMNOPQRSTUVWXYZ", NULL, "file:///ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0 },
+  { "/abcdefghijklmnopqrstuvwxyz", NULL, "file:///abcdefghijklmnopqrstuvwxyz", 0 },
+  { "/-_.!~*'()", NULL, "file:///-_.!~*'()", 0 },
 #ifdef G_OS_WIN32
   /* As '\\' is a path separator on Win32, it gets turned into '/' in the URI */
-  { "/\"#%<>[\\]^`{|}\x7F", NULL, "file:///%22%23%25%3C%3E%5B/%5D%5E%60%7B%7C%7D%7F"},
+  { "/\"#%<>[\\]^`{|}\x7F", NULL, "file:///%22%23%25%3C%3E%5B/%5D%5E%60%7B%7C%7D%7F", 0 },
 #else
   /* On Unix, '\\' is a normal character in the file name */
-  { "/\"#%<>[\\]^`{|}\x7F", NULL, "file:///%22%23%25%3C%3E%5B%5C%5D%5E%60%7B%7C%7D%7F"},
+  { "/\"#%<>[\\]^`{|}\x7F", NULL, "file:///%22%23%25%3C%3E%5B%5C%5D%5E%60%7B%7C%7D%7F", 0 },
 #endif
-  { "/;@+$,", NULL, "file:///%3B@+$,"},
+  { "/;@+$,", NULL, "file:///%3B@+$,", 0 },
   /* This and some of the following are of course as such illegal file names on Windows,
    * and would not occur in real life.
    */
-  { "/:", NULL, "file:///:"},
-  { "/?&=", NULL, "file:///%3F&="},
+  { "/:", NULL, "file:///:", 0 },
+  { "/?&=", NULL, "file:///%3F&=", 0 },
   { "/", "0123456789-", NULL, G_CONVERT_ERROR_ILLEGAL_SEQUENCE},
-  { "/", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "file://ABCDEFGHIJKLMNOPQRSTUVWXYZ/"},
-  { "/", "abcdefghijklmnopqrstuvwxyz", "file://abcdefghijklmnopqrstuvwxyz/"},
+  { "/", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "file://ABCDEFGHIJKLMNOPQRSTUVWXYZ/", 0 },
+  { "/", "abcdefghijklmnopqrstuvwxyz", "file://abcdefghijklmnopqrstuvwxyz/", 0 },
   { "/", "_.!~*'()", NULL, G_CONVERT_ERROR_ILLEGAL_SEQUENCE},
   { "/", "\"#%<>[\\]^`{|}\x7F", NULL, G_CONVERT_ERROR_ILLEGAL_SEQUENCE},
   { "/", ";?&=+$,", NULL, G_CONVERT_ERROR_ILLEGAL_SEQUENCE},
@@ -100,31 +100,32 @@ typedef struct
   char *uri;
   char *expected_filename;
   char *expected_hostname;
-  GConvertError expected_error; /* If failed */
+  gint expected_error; /* If failed */
 } FileFromUriTest;
 
 FileFromUriTest
 file_from_uri_tests[] = {
-  { "file:///etc", "/etc"},
-  { "file:/etc", "/etc"},
+  { "file:///etc", "/etc", NULL, 0 },
+  { "FILE:///etc", "/etc", NULL, 0 },
+  { "file:/etc", "/etc", NULL, 0 },
 #ifdef G_OS_WIN32
   /* On Win32 we don't return "localhost" hostames, just in case
    * it isn't recognized anyway.
    */
-  { "file://localhost/etc", "/etc", NULL},
-  { "file://localhost/etc/%23%25%20file", "/etc/#% file", NULL},
-  { "file://localhost/\xE5\xE4\xF6", "/\xe5\xe4\xf6", NULL},
-  { "file://localhost/%E5%E4%F6", "/\xe5\xe4\xf6", NULL},
+  { "file://localhost/etc", "/etc", NULL, 0 },
+  { "file://localhost/etc/%23%25%20file", "/etc/#% file", NULL, 0 },
+  { "file://localhost/\xE5\xE4\xF6", "/\xe5\xe4\xf6", NULL, 0 },
+  { "file://localhost/%E5%E4%F6", "/\xe5\xe4\xf6", NULL, 0 },
 #else
-  { "file://localhost/etc", "/etc", "localhost"},
-  { "file://localhost/etc/%23%25%20file", "/etc/#% file", "localhost"},
-  { "file://localhost/\xE5\xE4\xF6", "/\xe5\xe4\xf6", "localhost"},
-  { "file://localhost/%E5%E4%F6", "/\xe5\xe4\xf6", "localhost"},
+  { "file://localhost/etc", "/etc", "localhost", 0 },
+  { "file://localhost/etc/%23%25%20file", "/etc/#% file", "localhost", 0 },
+  { "file://localhost/\xE5\xE4\xF6", "/\xe5\xe4\xf6", "localhost", 0 },
+  { "file://localhost/%E5%E4%F6", "/\xe5\xe4\xf6", "localhost", 0 },
 #endif
-  { "file://otherhost/etc", "/etc", "otherhost"},
-  { "file://otherhost/etc/%23%25%20file", "/etc/#% file", "otherhost"},
+  { "file://otherhost/etc", "/etc", "otherhost", 0 },
+  { "file://otherhost/etc/%23%25%20file", "/etc/#% file", "otherhost", 0 },
   { "file://%C3%B6%C3%A4%C3%A5/etc", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
-  { "file:////etc/%C3%B6%C3%C3%C3%A5", "//etc/\xc3\xb6\xc3\xc3\xc3\xa5", NULL},
+  { "file:////etc/%C3%B6%C3%C3%C3%A5", "//etc/\xc3\xb6\xc3\xc3\xc3\xa5", NULL, 0 },
   { "file://\xE5\xE4\xF6/etc", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
   { "file://%E5%E4%F6/etc", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
   { "file:///some/file#bad", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
@@ -132,25 +133,25 @@ file_from_uri_tests[] = {
   { "", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
   { "file:test", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
   { "http://www.yahoo.com/", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
-  { "file:////etc", "//etc"},
-  { "file://///etc", "///etc"},
+  { "file:////etc", "//etc", NULL, 0 },
+  { "file://///etc", "///etc", NULL, 0 },
 #ifdef G_OS_WIN32
   /* URIs with backslashes come from some nonstandard application, but accept them anyhow */
-  { "file:///c:\\foo", "c:\\foo"},
-  { "file:///c:/foo\\bar", "c:\\foo\\bar"},
+  { "file:///c:\\foo", "c:\\foo", NULL, 0 },
+  { "file:///c:/foo\\bar", "c:\\foo\\bar", NULL, 0 },
   /* Accept also the old Netscape drive-letter-and-vertical bar convention */
-  { "file:///c|/foo", "c:\\foo"},
-  { "file:////server/share/dir", "\\\\server\\share\\dir"},
-  { "file://localhost//server/share/foo", "\\\\server\\share\\foo"},
-  { "file://otherhost//server/share/foo", "\\\\server\\share\\foo", "otherhost"},
+  { "file:///c|/foo", "c:\\foo", NULL, 0 },
+  { "file:////server/share/dir", "\\\\server\\share\\dir", NULL, 0 },
+  { "file://localhost//server/share/foo", "\\\\server\\share\\foo", NULL, 0 },
+  { "file://otherhost//server/share/foo", "\\\\server\\share\\foo", "otherhost", 0 },
 #else
-  { "file:///c:\\foo", "/c:\\foo"},
-  { "file:///c:/foo", "/c:/foo"},
-  { "file:////c:/foo", "//c:/foo"},
+  { "file:///c:\\foo", "/c:\\foo", NULL, 0 },
+  { "file:///c:/foo", "/c:/foo", NULL, 0 },
+  { "file:////c:/foo", "//c:/foo",  NULL, 0 },
 #endif
   { "file://0123456789/", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
-  { "file://ABCDEFGHIJKLMNOPQRSTUVWXYZ/", "/", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"},
-  { "file://abcdefghijklmnopqrstuvwxyz/", "/", "abcdefghijklmnopqrstuvwxyz"},
+  { "file://ABCDEFGHIJKLMNOPQRSTUVWXYZ/", "/", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0 },
+  { "file://abcdefghijklmnopqrstuvwxyz/", "/", "abcdefghijklmnopqrstuvwxyz", 0 },
   { "file://-_.!~*'()/", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
   { "file://\"<>[\\]^`{|}\x7F/", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
   { "file://;?&=+$,/", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
@@ -165,7 +166,7 @@ file_from_uri_tests[] = {
 static void
 run_file_to_uri_tests (void)
 {
-  int i;
+  gsize i;
   gchar *res;
   GError *error;
 
@@ -189,7 +190,7 @@ run_file_to_uri_tests (void)
 static void
 run_file_from_uri_tests (void)
 {
-  int i;
+  gsize i;
   gchar *res;
   gchar *hostname;
   GError *error;
@@ -269,7 +270,7 @@ safe_strcmp_hostname (const gchar *a, const gchar *b)
 static void
 run_file_roundtrip_tests (void)
 {
-  int i;
+  gsize i;
   gchar *uri, *hostname, *res;
   GError *error;
 
@@ -549,7 +550,7 @@ typedef struct {
   GUriFlags flags;
   /* Outputs */
   gboolean expected_success;
-  GUriError expected_error_code;  /* unused if @expected_success is true */
+  gint expected_error_code;       /* unused if @expected_success is true */
   const UriParts expected_parts;  /* unused if @expected_success is false */
 } UriAbsoluteTest;
 
@@ -757,6 +758,10 @@ static const UriAbsoluteTest absolute_tests[] = {
     { NULL, NULL, NULL, -1, NULL, NULL, NULL } },
   { "http://[fe80::dead:beef%25em1%00]/", G_URI_FLAGS_NONE, FALSE, G_URI_ERROR_BAD_HOST,
     { NULL, NULL, NULL, -1, NULL, NULL, NULL } },
+
+  /* Invalid IDN hostname */
+  { "http://xn--mixed-\xc3\xbcp/", G_URI_FLAGS_NONE, FALSE, G_URI_ERROR_BAD_HOST,
+    { NULL, NULL, NULL, -1, NULL, NULL, NULL } },
 };
 
 static void
@@ -889,7 +894,10 @@ static const UriRelativeTest relative_tests[] = {
   { "http:g", "http:g",
     { "http", NULL, NULL, -1, "g", NULL, NULL } },
   { "http://a/../..", "http://a/",
-    { "http", NULL, "a", -1, "/", NULL, NULL } }
+    { "http", NULL, "a", -1, "/", NULL, NULL } },
+  { "ScHeMe://User:P%61ss@HOST.%63om:1234/path/./from/../to%7d/item%2dobj?qu%65ry=something#fr%61gment",
+    "scheme://User:Pass@HOST.com:1234/path/to%7D/item-obj?query=something#fragment",
+    { "scheme", "User:Pass", "HOST.com", 1234, "/path/to}/item-obj", "query=something", "fragment" } },
 };
 static int num_relative_tests = G_N_ELEMENTS (relative_tests);
 
@@ -1213,6 +1221,20 @@ test_uri_split (void)
   g_assert_cmpstr (path, ==, "/%C3%89t%C3%A9%2Bhiver");
   g_free (path);
 
+  g_uri_split ("file:///path/to/some%20file",
+               G_URI_FLAGS_NONE,
+               NULL,
+               NULL,
+               NULL,
+               NULL,
+               &path,
+               NULL,
+               NULL,
+               &error);
+  g_assert_no_error (error);
+  g_assert_cmpstr (path, ==, "/path/to/some file");
+  g_free (path);
+
   g_uri_split ("http://h%01st/path#%C3%89t%C3%A9%2Bhiver",
                G_URI_FLAGS_ENCODED_FRAGMENT,
                NULL,
@@ -1369,6 +1391,47 @@ test_uri_split (void)
   g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_PASSWORD);
   g_clear_error (&error);
 
+  /* Path not started correctly */
+  g_uri_split("scheme://hostname:123path?query#fragment",
+              G_URI_FLAGS_NONE,
+              &scheme,
+              &userinfo,
+              &host,
+              &port,
+              &path,
+              &query,
+              &fragment,
+              &error);
+  g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_PORT);
+  g_clear_error (&error);
+
+  /* Brackets that don't close */
+  g_uri_split("scheme://[01:23:45:67:89:ab:cd:ef:123/path",
+              G_URI_FLAGS_NONE,
+              &scheme,
+              &userinfo,
+              &host,
+              &port,
+              &path,
+              &query,
+              &fragment,
+              &error);
+  g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_HOST);
+  g_clear_error (&error);
+
+  /* IPv6 hostname without brackets */
+  g_uri_split("scheme://01:23:45:67:89:ab:cd:ef:123/path",
+              G_URI_FLAGS_NONE,
+              &scheme,
+              &userinfo,
+              &host,
+              &port,
+              &path,
+              &query,
+              &fragment,
+              &error);
+  g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_PORT);
+  g_clear_error (&error);
 }
 
 static void
@@ -1422,6 +1485,25 @@ test_uri_is_valid (void)
   g_clear_error (&error);
 
   g_assert_true (g_uri_is_valid ("data:,Hello", G_URI_FLAGS_NONE, &error));
+
+  g_assert_true (g_uri_is_valid ("B:\\foo.txt", G_URI_FLAGS_NONE, &error));
+  g_assert_true (g_uri_is_valid ("B:/foo.txt", G_URI_FLAGS_NONE, &error));
+  g_assert_true (g_uri_is_valid ("B://foo.txt", G_URI_FLAGS_NONE, &error));
+  g_assert_true (g_uri_is_valid ("B:foo.txt", G_URI_FLAGS_NONE, &error));
+
+  g_assert_true (g_uri_is_valid ("fd://0", G_URI_FLAGS_NONE, &error));
+  g_assert_true (g_uri_is_valid ("AB:\\foo.txt", G_URI_FLAGS_NONE, &error));
+  g_assert_true (g_uri_is_valid ("AB:/foo.txt", G_URI_FLAGS_NONE, &error));
+  g_assert_true (g_uri_is_valid ("AB://foo.txt", G_URI_FLAGS_NONE, &error));
+  g_assert_true (g_uri_is_valid ("AB:foo.txt", G_URI_FLAGS_NONE, &error));
+
+  g_assert_true (g_uri_is_valid ("ABC:/foo.txt", G_URI_FLAGS_NONE, &error));
+  g_assert_true (g_uri_is_valid ("ABC://foo.txt", G_URI_FLAGS_NONE, &error));
+  g_assert_true (g_uri_is_valid ("ABC:foo.txt", G_URI_FLAGS_NONE, &error));
+
+  g_assert_true (g_uri_is_valid ("ABCD:/foo.txt", G_URI_FLAGS_NONE, &error));
+  g_assert_true (g_uri_is_valid ("ABCD://foo.txt", G_URI_FLAGS_NONE, &error));
+  g_assert_true (g_uri_is_valid ("ABCD:foo.txt", G_URI_FLAGS_NONE, &error));
 }
 
 static const struct
@@ -1474,6 +1556,9 @@ static const struct
     { "foo=bar+%26+baz&saisons=%C3%89t%C3%A9%2Bhiver", "&", G_URI_PARAMS_NONE,
       2, { "foo", "bar+&+baz", "saisons", "Été+hiver", NULL, },
       2, { "foo", "bar+&+baz", "saisons", "Été+hiver", NULL, }},
+    { "token=exp=123~acl=/QualityLevels(*~hmac=0cb", "&", G_URI_PARAMS_NONE,
+      1, { "token", "exp=123~acl=/QualityLevels(*~hmac=0cb", NULL, },
+      1, { "token", "exp=123~acl=/QualityLevels(*~hmac=0cb", NULL, }},
   };
 
 static void
@@ -1492,7 +1577,7 @@ test_uri_iter_params (gconstpointer test_data)
       g_test_message ("URI %" G_GSIZE_FORMAT ": %s", i, params_tests[i].uri);
 
       g_assert (params_tests[i].expected_n_params < 0 ||
-                params_tests[i].expected_n_params <= G_N_ELEMENTS (params_tests[i].expected_param_key_values) / 2);
+                params_tests[i].expected_n_params <= (gssize) G_N_ELEMENTS (params_tests[i].expected_param_key_values) / 2);
 
       /* The tests get run twice: once with the length unspecified, using a
        * nul-terminated string; and once with the length specified and a copy of
@@ -1559,7 +1644,7 @@ test_uri_parse_params (gconstpointer test_data)
       g_test_message ("URI %" G_GSIZE_FORMAT ": %s", i, params_tests[i].uri);
 
       g_assert (params_tests[i].expected_n_params < 0 ||
-                params_tests[i].expected_n_params <= G_N_ELEMENTS (params_tests[i].expected_param_key_values) / 2);
+                params_tests[i].expected_n_params <= (gssize) G_N_ELEMENTS (params_tests[i].expected_param_key_values) / 2);
 
       /* The tests get run twice: once with the length unspecified, using a
        * nul-terminated string; and once with the length specified and a copy of
@@ -1591,7 +1676,7 @@ test_uri_parse_params (gconstpointer test_data)
           g_assert_no_error (err);
           g_assert_cmpint (g_hash_table_size (params), ==, params_tests[i].expected_n_params);
 
-          for (j = 0; j < params_tests[i].expected_n_params; j += 2)
+          for (j = 0; j < (gsize) params_tests[i].expected_n_params; j += 2)
             g_assert_cmpstr (g_hash_table_lookup (params, params_tests[i].expected_param_key_values[j]), ==,
                              params_tests[i].expected_param_key_values[j + 1]);
         }
@@ -1708,6 +1793,222 @@ test_uri_join_split_round_trip (void)
     }
 }
 
+static const struct
+{
+  /* Inputs */
+  const gchar *base;
+  const gchar *uri;
+  GUriFlags flags;
+  /* Outputs */
+  const gchar *uri_string;
+  const gchar *path;
+  int port;
+} normalize_parse_tests[] =
+  {
+    { NULL, "http://foo/path with spaces", G_URI_FLAGS_ENCODED,
+      "http://foo/path%20with%20spaces", "/path%20with%20spaces", -1 },
+    { NULL, "http://foo/path with spaces 2", G_URI_FLAGS_ENCODED_PATH,
+      "http://foo/path%20with%20spaces%202", "/path%20with%20spaces%202", -1 },
+    { NULL, "http://foo/%aa", G_URI_FLAGS_ENCODED,
+      "http://foo/%AA", "/%AA", -1 },
+    { NULL, "http://foo/p\xc3\xa4th/", G_URI_FLAGS_ENCODED | G_URI_FLAGS_PARSE_RELAXED,
+      "http://foo/p%C3%A4th/", "/p%C3%A4th/", -1 },
+    { NULL, "http://foo", G_URI_FLAGS_NONE,
+      "http://foo", "", -1 },
+    { NULL, "http://foo", G_URI_FLAGS_SCHEME_NORMALIZE,
+      "http://foo/", "/", 80 },
+    { NULL, "nothttp://foo", G_URI_FLAGS_SCHEME_NORMALIZE,
+      "nothttp://foo", "", -1 },
+    { NULL, "http://foo:80", G_URI_FLAGS_NONE,
+      "http://foo:80", "", 80 },
+    { NULL, "http://foo:80", G_URI_FLAGS_SCHEME_NORMALIZE,
+      "http://foo/", "/", 80 },
+    { NULL, "http://foo:8080", G_URI_FLAGS_SCHEME_NORMALIZE,
+      "http://foo:8080/", "/", 8080 },
+    { NULL, "https://foo:443", G_URI_FLAGS_SCHEME_NORMALIZE,
+      "https://foo/", "/", 443 },
+    { NULL, "https://foo:943", G_URI_FLAGS_SCHEME_NORMALIZE,
+      "https://foo:943/", "/", 943 },
+    { NULL, "ws://foo", G_URI_FLAGS_SCHEME_NORMALIZE,
+      "ws://foo/", "/", 80 },
+    { NULL, "wss://foo:443", G_URI_FLAGS_SCHEME_NORMALIZE,
+      "wss://foo/", "/", 443 },
+    { NULL, "ftp://foo", G_URI_FLAGS_NONE,
+      "ftp://foo", "", -1 },
+    { NULL, "ftp://foo", G_URI_FLAGS_SCHEME_NORMALIZE,
+      "ftp://foo", "", 21 },
+    { NULL, "ftp://foo:21", G_URI_FLAGS_SCHEME_NORMALIZE,
+      "ftp://foo", "", 21 },
+    { NULL, "ftp://foo:2100", G_URI_FLAGS_SCHEME_NORMALIZE,
+      "ftp://foo:2100", "", 2100 },
+    { NULL, "nothttp://foo:80", G_URI_FLAGS_SCHEME_NORMALIZE,
+      "nothttp://foo:80", "", 80 },
+    { "http://foo", "//bar", G_URI_FLAGS_SCHEME_NORMALIZE,
+      "http://bar/", "/", 80 },
+    { "http://foo", "//bar:80", G_URI_FLAGS_SCHEME_NORMALIZE,
+      "http://bar/", "/", 80 },
+    { "nothttp://foo", "//bar:80", G_URI_FLAGS_SCHEME_NORMALIZE,
+      "nothttp://bar:80", "", 80 },
+    { "http://foo", "//bar", G_URI_FLAGS_NONE,
+      "http://bar", "", -1 },
+    { "ScHeMe://User:P%61ss@HOST.%63om:1234/path",
+      "ScHeMe://User:P%61ss@HOST.%63om:1234/path/./from/../to%7d/item%2dobj?qu%65ry=something#fr%61gment",
+      G_URI_FLAGS_SCHEME_NORMALIZE,
+      "scheme://User:Pass@HOST.com:1234/path/to%7D/item-obj?query=something#fragment",
+      "/path/to}/item-obj", 1234 },
+  };
+
+static const struct
+{
+  /* Inputs */
+  const gchar *uri;
+  GUriFlags flags;
+  /* Outputs */
+  const char *scheme;
+  const gchar *path;
+  int port;
+} normalize_split_tests[] =
+  {
+    { "HTTP://foo", G_URI_FLAGS_ENCODED,
+      "http", "", -1 },
+    { "HTTP://foo", G_URI_FLAGS_SCHEME_NORMALIZE,
+      "http", "/", 80 },
+    { "http://foo:80/", G_URI_FLAGS_SCHEME_NORMALIZE,
+      "http", "/", 80 },
+    { "http://foo:8080/bar", G_URI_FLAGS_SCHEME_NORMALIZE,
+      "http", "/bar", 8080 },
+    { "ws://foo", G_URI_FLAGS_SCHEME_NORMALIZE,
+      "ws", "/", 80 },
+    { "https://foo", G_URI_FLAGS_ENCODED,
+      "https", "", -1 },
+    { "https://foo", G_URI_FLAGS_SCHEME_NORMALIZE,
+      "https", "/", 443 },
+    { "https://foo:443/", G_URI_FLAGS_SCHEME_NORMALIZE,
+      "https", "/", 443 },
+    { "wss://foo", G_URI_FLAGS_SCHEME_NORMALIZE,
+      "wss", "/", 443 },
+    { "ftp://foo", G_URI_FLAGS_ENCODED,
+      "ftp", "", -1 },
+    { "ftp://foo", G_URI_FLAGS_SCHEME_NORMALIZE,
+      "ftp", "", 21 },
+    { "ftp://foo:21", G_URI_FLAGS_SCHEME_NORMALIZE,
+      "ftp", "", 21 },
+    { "scheme://foo", G_URI_FLAGS_SCHEME_NORMALIZE,
+      "scheme", "", -1 },
+  };
+
+static const struct
+{
+  /* Inputs */
+  GUriFlags flags;
+  const gchar *scheme;
+  const gchar *host;
+  int port;
+  const gchar *path;
+  /* Outputs */
+  const gchar *uri;
+} normalize_join_tests[] =
+  {
+    { G_URI_FLAGS_NONE, "http", "foo", -1, "",
+      "http://foo" },
+    { G_URI_FLAGS_SCHEME_NORMALIZE, "http", "foo", -1, "",
+      "http://foo/" },
+    { G_URI_FLAGS_SCHEME_NORMALIZE, "http", "foo", 80, "",
+      "http://foo/" },
+    { G_URI_FLAGS_SCHEME_NORMALIZE, "http", "foo", 8080, "",
+      "http://foo:8080/" },
+    { G_URI_FLAGS_NONE, "http", "foo", 80, "",
+      "http://foo:80" },
+    { G_URI_FLAGS_SCHEME_NORMALIZE, "ws", "foo", 80, "",
+      "ws://foo/" },
+    { G_URI_FLAGS_NONE, "https", "foo", -1, "",
+      "https://foo" },
+    { G_URI_FLAGS_SCHEME_NORMALIZE, "https", "foo", -1, "",
+      "https://foo/" },
+    { G_URI_FLAGS_SCHEME_NORMALIZE, "https", "foo", 443, "",
+      "https://foo/" },
+    { G_URI_FLAGS_SCHEME_NORMALIZE, "https", "foo", 943, "",
+      "https://foo:943/" },
+    { G_URI_FLAGS_NONE, "https", "foo", 443, "",
+      "https://foo:443" },
+    { G_URI_FLAGS_SCHEME_NORMALIZE, "wss", "foo", 443, "",
+      "wss://foo/" },
+    { G_URI_FLAGS_NONE, "ftp", "foo", -1, "",
+      "ftp://foo" },
+    { G_URI_FLAGS_SCHEME_NORMALIZE, "ftp", "foo", -1, "",
+      "ftp://foo" },
+    { G_URI_FLAGS_SCHEME_NORMALIZE, "ftp", "foo", 21, "",
+      "ftp://foo" },
+    { G_URI_FLAGS_SCHEME_NORMALIZE, "ftp", "foo", 2020, "",
+      "ftp://foo:2020" },
+    { G_URI_FLAGS_NONE, "ftp", "foo", 21, "",
+      "ftp://foo:21" },
+    { G_URI_FLAGS_SCHEME_NORMALIZE, "scheme", "foo", 80, "",
+      "scheme://foo:80" },
+  };
+
+static void
+test_uri_normalize (void)
+{
+  gsize i;
+  int port;
+  char *path;
+  char *uri_string;
+
+  for (i = 0; i < G_N_ELEMENTS (normalize_parse_tests); ++i)
+    {
+      GUri *uri, *base = NULL;
+
+      if (normalize_parse_tests[i].base)
+        base = g_uri_parse (normalize_parse_tests[i].base, normalize_parse_tests[i].flags, NULL);
+
+      uri = g_uri_parse_relative (base,
+                                  normalize_parse_tests[i].uri,
+                                  normalize_parse_tests[i].flags,
+                                  NULL);
+      uri_string = g_uri_to_string (uri);
+
+      g_assert_nonnull (uri);
+      g_assert_cmpstr (g_uri_get_path (uri), ==, normalize_parse_tests[i].path);
+      g_assert_cmpint (g_uri_get_port (uri), ==, normalize_parse_tests[i].port);
+      g_assert_cmpstr (uri_string, ==, normalize_parse_tests[i].uri_string);
+
+      g_free (uri_string);
+      g_uri_unref (uri);
+      if (base)
+        g_uri_unref (base);
+    }
+
+  for (i = 0; i < G_N_ELEMENTS (normalize_split_tests); ++i)
+    {
+      char *scheme;
+
+      /* Testing a codepath where scheme is NULL but internally we still normalize it. */
+      g_assert_true (g_uri_split (normalize_split_tests[i].uri, normalize_split_tests[i].flags,
+                                  NULL, NULL, NULL, &port, &path, NULL, NULL, NULL));
+      g_assert_cmpstr (path, ==, normalize_split_tests[i].path);
+      g_assert_cmpint (port, ==, normalize_split_tests[i].port);
+      g_free (path);
+
+      g_assert_true (g_uri_split (normalize_split_tests[i].uri, normalize_split_tests[i].flags,
+                                  &scheme, NULL, NULL, &port, &path, NULL, NULL, NULL));
+      g_assert_cmpstr (scheme, ==, normalize_split_tests[i].scheme);
+      g_assert_cmpstr (path, ==, normalize_split_tests[i].path);
+      g_assert_cmpint (port, ==, normalize_split_tests[i].port);
+      g_free (scheme);
+      g_free (path);
+    }
+
+  for (i = 0; i < G_N_ELEMENTS (normalize_join_tests); ++i)
+    {
+      uri_string = g_uri_join (normalize_join_tests[i].flags, normalize_join_tests[i].scheme, NULL,
+                               normalize_join_tests[i].host, normalize_join_tests[i].port,
+                               normalize_join_tests[i].path, NULL, NULL);
+      g_assert_cmpstr (uri_string, ==, normalize_join_tests[i].uri);
+      g_free (uri_string);
+    }
+}
+
 int
 main (int   argc,
       char *argv[])
@@ -1733,6 +2034,7 @@ main (int   argc,
   g_test_add_func ("/uri/to-string", test_uri_to_string);
   g_test_add_func ("/uri/join", test_uri_join);
   g_test_add_func ("/uri/join-split-round-trip", test_uri_join_split_round_trip);
+  g_test_add_func ("/uri/normalize", test_uri_normalize);
   g_test_add_data_func ("/uri/iter-params/nul-terminated", GINT_TO_POINTER (TRUE), test_uri_iter_params);
   g_test_add_data_func ("/uri/iter-params/length", GINT_TO_POINTER (FALSE), test_uri_iter_params);
   g_test_add_data_func ("/uri/parse-params/nul-terminated", GINT_TO_POINTER (TRUE), test_uri_parse_params);
index 159876b..f2b4f9a 100755 (executable)
@@ -4,21 +4,25 @@
 #
 #  ./update-gtranslit.py /path/to/glibc/localedata/locales > gtranslit-data.h
 
-import sys, os
+import os
+import sys
+
 
 localedir = sys.argv[1]
 
+
 # returns true if the name looks like a POSIX locale name
 def looks_like_locale(name):
-    name, _, variant = name.partition('@')
+    name, _, variant = name.partition("@")
 
-    if '_' not in name:
+    if "_" not in name:
         return False
 
-    lang, _, land = name.partition('_')
+    lang, _, land = name.partition("_")
 
     return len(lang) == 2 or len(lang) == 3 and len(land) == 2
 
+
 # handles <U1234> style escapes
 def unescape(string):
     chunks = []
@@ -27,27 +31,29 @@ def unescape(string):
     i = 0
 
     while i < n:
-        start_escape = string.find('<', i)
+        start_escape = string.find("<", i)
 
         if start_escape == -1:
             chunks.append(string[i:])
             break
 
-        assert string[start_escape:start_escape + 2] == '<U'
+        assert string[start_escape : (start_escape + 2)] == "<U"
         start_escape += 2
 
-        end_escape = string.find('>', start_escape)
+        end_escape = string.find(">", start_escape)
         assert end_escape != -1
 
         chunks.append(chr(int(string[start_escape:end_escape], 16)))
         i = end_escape + 1
 
-    return ''.join(chunks)
+    return "".join(chunks)
+
 
 # Checks if a string is ascii
 def is_ascii(string):
     return all(ord(c) < 0x80 for c in string)
 
+
 # A Mapping is a map from non-ascii strings to ascii strings.
 #
 # It corresponds to a sequence of one or more mapping lines:
@@ -62,31 +68,32 @@ class Mapping:
 
     # Scans a string like
     #
-    #   <U00C4> "<U0041><U0308>";"<U0041><U0045>" % LATIN CAPITAL LETTER A WITH DIAERESIS.
+    #   <U00C4> "<U0041><U0308>";"<U0041><U0045>" % \
+    #   LATIN CAPITAL LETTER A WITH DIAERESIS.
     #
     # and adds the first all-ascii choice (or IGNORE) to the mapping
     # dictionary, with the origin string as the key.  In the case of
     # IGNORE, stores the empty string.
     def consider_mapping_line(self, line):
-        key, value, rest = (line + ' % comment').split(maxsplit=2)
+        key, value, rest = (line + " % comment").split(maxsplit=2)
 
         key = unescape(key)
 
-        for alternative in value.split(';'):
+        for alternative in value.split(";"):
             if alternative[0] == '"' and alternative[-1] == '"':
                 unescaped = unescape(alternative[1:-1])
                 if is_ascii(unescaped):
                     self.mapping[key] = unescaped
                     break
 
-            elif alternative[0] == '<' and alternative[-1] == '>':
+            elif alternative[0] == "<" and alternative[-1] == ">":
                 unescaped = unescape(alternative)
                 if is_ascii(unescaped):
                     self.mapping[key] = unescaped
                     break
 
-            elif alternative == 'IGNORE':
-                self.mapping[key] = ''
+            elif alternative == "IGNORE":
+                self.mapping[key] = ""
                 break
 
     # Performs a normal dictionary merge, but ensures that there are no
@@ -109,6 +116,7 @@ class Mapping:
 
         return self.serialised
 
+
 # A Chain is a sequence of mappings and chains.
 #
 # A chain contains another chain whenever "copy" or "include" is
@@ -135,16 +143,16 @@ class Chain:
         in_lc_ctype = False
         in_translit = False
 
-        fp = open(filename, encoding='ascii', errors='surrogateescape')
+        fp = open(filename, encoding="ascii", errors="surrogateescape")
 
         for line in fp:
             line = line.strip()
 
             if in_lc_ctype:
-                if line == 'END LC_CTYPE':
+                if line == "END LC_CTYPE":
                     break
 
-                if line.startswith('copy') or line.startswith('include'):
+                if line.startswith("copy") or line.startswith("include"):
                     if current_mapping:
                         self.chain.append(current_mapping)
 
@@ -155,29 +163,29 @@ class Chain:
 
                     current_mapping = None
 
-                elif line == 'translit_start':
+                elif line == "translit_start":
                     in_translit = True
 
-                elif line == 'translit_end':
+                elif line == "translit_end":
                     in_translit = False
 
-                elif in_translit and line.startswith('<U'):
+                elif in_translit and line.startswith("<U"):
                     if not current_mapping:
                         current_mapping = Mapping()
 
                     current_mapping.consider_mapping_line(line)
 
-                elif line == '' or line.startswith('%'):
+                elif line == "" or line.startswith("%"):
                     pass
 
-                elif 'default_missing <U003F>':
+                elif "default_missing <U003F>":
                     pass
 
                 elif in_translit:
-                    print('unknown line:', line)
+                    print("unknown line:", line)
                     assert False
 
-            elif line == 'LC_CTYPE':
+            elif line == "LC_CTYPE":
                 in_lc_ctype = True
 
         if current_mapping:
@@ -199,7 +207,9 @@ class Chain:
 
             i = 0
             while i < len(self.chain) - 1:
-                if isinstance(self.chain[i], Mapping) and isinstance(self.chain[i + 1], Mapping):
+                if isinstance(self.chain[i], Mapping) and isinstance(
+                    self.chain[i + 1], Mapping
+                ):
                     # We have two mappings in a row.  Try to merge them.
                     self.chain[i].merge_mapping(self.chain[i + 1])
                     del self.chain[i + 1]
@@ -215,10 +225,13 @@ class Chain:
 
         return self.serialised
 
+
 # Chain cache -- allows sharing of common chains
 chains = {}
+
+
 def get_chain(name):
-    if not name in chains:
+    if name not in chains:
         chains[name] = Chain(name)
 
     return chains[name]
@@ -227,10 +240,11 @@ def get_chain(name):
 # Remove the country name from a locale, preserving variant
 # eg: 'sr_RS@latin' -> 'sr@latin'
 def remove_country(string):
-    base, at, variant = string.partition('@')
-    lang, _, land = base.partition('_')
+    base, at, variant = string.partition("@")
+    lang, _, land = base.partition("_")
     return lang + at + variant
 
+
 def encode_range(start, end):
     assert start <= end
     length = end - start
@@ -244,8 +258,10 @@ def encode_range(start, end):
 
     return result
 
+
 def c_pair_array(array):
-    return '{ ' + ', '.join ('{ %u, %u }' % pair for pair in array) + ' };'
+    return "{ " + ", ".join("{ %u, %u }" % pair for pair in array) + " };"
+
 
 class Serialiser:
     def __init__(self):
@@ -284,7 +300,9 @@ class Serialiser:
         languages = list(set(remove_country(locale) for locale in self.locales))
 
         for language in languages:
-            locales = [locale for locale in self.locales if remove_country(locale) == language]
+            locales = [
+                locale for locale in self.locales if remove_country(locale) == language
+            ]
 
             item_id = self.locales[locales[0]]
             if all(self.locales[locale] == item_id for locale in locales):
@@ -294,8 +312,8 @@ class Serialiser:
 
         # Check if a variant is the same as the non-variant form
         # eg: 'de@euro' and 'de'
-        for variant in list(locale for locale in self.locales if '@' in locale):
-            base, _, _ = variant.partition('@')
+        for variant in list(locale for locale in self.locales if "@" in locale):
+            base, _, _ = variant.partition("@")
             if base in self.locales and self.locales[base] == self.locales[variant]:
                 del self.locales[variant]
 
@@ -305,19 +323,19 @@ class Serialiser:
                 del self.locales[locale]
 
     def to_c(self):
-        src_table = ''
-        ascii_table = ''
+        src_table = ""
+        ascii_table = ""
         mappings_table = []
         mapping_ranges = []
         chains_table = []
         chain_starts = []
-        locale_names = ''
+        locale_names = ""
         locale_index = []
         max_lookup = 0
         max_localename = 0
 
         for mapping in self.mappings:
-            mapping_ranges.append ((len(mappings_table), len(mapping)))
+            mapping_ranges.append((len(mappings_table), len(mapping)))
 
             for key in sorted(mapping):
                 if len(key) == 1 and ord(key[0]) < 0x8000:
@@ -326,7 +344,7 @@ class Serialiser:
                     existing = src_table.find(key)
                     if existing == -1:
                         start = len(src_table)
-                        assert all(ord(c) <= 0x10ffff for c in key)
+                        assert all(ord(c) <= 0x10FFFF for c in key)
                         src_table += key
                         src_range = encode_range(start, len(src_table))
                         max_lookup = max(max_lookup, len(key))
@@ -346,23 +364,21 @@ class Serialiser:
                     else:
                         ascii_range = encode_range(existing, existing + len(value))
 
-                mappings_table.append ((src_range, ascii_range))
-
-            mapping_end = len(mappings_table)
+                mappings_table.append((src_range, ascii_range))
 
         for chain in self.chains:
             chain_starts.append(len(chains_table))
 
             for item_id in reversed(chain):
-                assert item_id < 0xff
+                assert item_id < 0xFF
                 chains_table.append(item_id)
-            chains_table.append(0xff)
+            chains_table.append(0xFF)
 
         for locale in sorted(self.locales):
             max_localename = max(max_localename, len(locale))
             name_offset = len(locale_names)
-            assert all(ord(c) <= 0x7f for c in locale)
-            locale_names += (locale + '\0')
+            assert all(ord(c) <= 0x7F for c in locale)
+            locale_names += locale + "\0"
 
             item_id = self.locales[locale]
 
@@ -370,30 +386,60 @@ class Serialiser:
             assert item_id < 256
             locale_index.append((name_offset, item_id))
 
-        print('/* Generated by update-gtranslit.py */')
-        print('#define MAX_KEY_SIZE', max_lookup)
-        print('#define MAX_LOCALE_NAME', max_localename)
-        print('static const gunichar src_table[] = {', ', '.join(str(ord(c)) for c in src_table), '};')
+        print("/* Generated by update-gtranslit.py */")
+        print("#define MAX_KEY_SIZE", max_lookup)
+        print("#define MAX_LOCALE_NAME", max_localename)
+        print(
+            "static const gunichar src_table[] = {",
+            ", ".join(str(ord(c)) for c in src_table),
+            "};",
+        )
         # cannot do this in plain ascii because of trigraphs... :(
-        print('static const gchar ascii_table[] = {', ', '.join(str(ord(c)) for c in ascii_table), '};')
-        print('static const struct mapping_entry mappings_table[] =', c_pair_array (mappings_table))
-        print('static const struct mapping_range mapping_ranges[] =', c_pair_array (mapping_ranges))
-        print('static const guint8 chains_table[] = {', ', '.join(str(i) for i in chains_table), '};')
-        print('static const guint8 chain_starts[] = {', ', '.join(str(i) for i in chain_starts), '};')
-        print('static const gchar locale_names[] = "' + locale_names.replace('\0', '\\0') + '";')
-        print('static const struct locale_entry locale_index[] = ', c_pair_array (locale_index))
-        print('static const guint8 default_item_id = %u;' % (self.default,))
+        print(
+            "static const gchar ascii_table[] = {",
+            ", ".join(str(ord(c)) for c in ascii_table),
+            "};",
+        )
+        print(
+            "static const struct mapping_entry mappings_table[] =",
+            c_pair_array(mappings_table),
+        )
+        print(
+            "static const struct mapping_range mapping_ranges[] =",
+            c_pair_array(mapping_ranges),
+        )
+        print(
+            "static const guint8 chains_table[] = {",
+            ", ".join(str(i) for i in chains_table),
+            "};",
+        )
+        print(
+            "static const guint8 chain_starts[] = {",
+            ", ".join(str(i) for i in chain_starts),
+            "};",
+        )
+        print(
+            'static const gchar locale_names[] = "'
+            + locale_names.replace("\0", "\\0")
+            + '";'
+        )
+        print(
+            "static const struct locale_entry locale_index[] = ",
+            c_pair_array(locale_index),
+        )
+        print("static const guint8 default_item_id = %u;" % (self.default,))
 
     def dump(self):
         print(self.mappings)
         print(self.chains)
         print(self.locales)
 
+
 locales = []
 for name in os.listdir(localedir):
     if looks_like_locale(name):
         chain = get_chain(name)
-        locales.append (chain)
+        locales.append(chain)
         chain.links += 1
 
 serialiser = Serialiser()
@@ -401,8 +447,8 @@ serialiser = Serialiser()
 for locale in locales:
     serialiser.add_locale(locale.name, locale.serialise(serialiser))
 
-i18n = get_chain('i18n').serialise(serialiser)
-combining = get_chain('translit_combining').serialise(serialiser)
+i18n = get_chain("i18n").serialise(serialiser)
+combining = get_chain("translit_combining").serialise(serialiser)
 serialiser.add_default(serialiser.add_chain([i18n, combining]))
 
 serialiser.optimise_locales()
index 0e558dd..69d7f8a 100644 (file)
@@ -43,7 +43,8 @@ cd pcre
 # the file and then distribute it with GRegex.
 echo "Generating pcre_chartables.c"
 cp -R "${PCRE}" tmp-build
-cd tmp-build
+(
+cd tmp-build || exit 1
 ./configure --enable-utf8 --enable-unicode-properties --disable-cpp > /dev/null
 make pcre_chartables.c > /dev/null
 cat > ../pcre_chartables.c << \EOF
@@ -52,7 +53,7 @@ cat > ../pcre_chartables.c << \EOF
  */
 EOF
 cat pcre_chartables.c >> ../pcre_chartables.c
-cd ..
+)
 rm -R tmp-build
 
 # Compiled C files.
index 5ebf6b8..43111e8 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "config.h"
 
+#include "../glib/gvalgrind.h"
 #include <string.h>
 
 #include "gatomicarray.h"
@@ -77,6 +78,11 @@ freelist_alloc (gsize size, gboolean reuse)
   mem = g_slice_alloc (real_size);
   mem = ((char *) mem) + sizeof (gsize);
   G_ATOMIC_ARRAY_DATA_SIZE (mem) = size;
+
+#if ENABLE_VALGRIND
+  VALGRIND_MALLOCLIKE_BLOCK (mem, real_size - sizeof (gsize), FALSE, FALSE);
+#endif
+
   return mem;
 }
 
index 9550fa3..89043c5 100644 (file)
@@ -29,7 +29,7 @@ G_BEGIN_DECLS
 
 typedef struct _GAtomicArray GAtomicArray;
 struct _GAtomicArray {
-  volatile gpointer data;               /* elements - atomic */
+  gpointer data;  /* elements - atomic */
 };
 
 void     _g_atomic_array_init   (GAtomicArray *array);
@@ -42,7 +42,7 @@ void     _g_atomic_array_update (GAtomicArray *array,
 #define  G_ATOMIC_ARRAY_GET_LOCKED(_array, _type) ((_type *)((_array)->data))
 
 #define G_ATOMIC_ARRAY_DO_TRANSACTION(_array, _type, _C_) G_STMT_START {       \
-    volatile gpointer *_datap  = &(_array)->data;                              \
+    gpointer *_datap  = &(_array)->data;                               \
     _type *transaction_data, *__check;                                         \
                                                                                \
     __check = g_atomic_pointer_get (_datap);                                   \
index 78a8830..562f339 100644 (file)
 GType
 g_binding_flags_get_type (void)
 {
-  static volatile gsize g_define_type_id__volatile = 0;
+  static gsize static_g_define_type_id = 0;
 
-  if (g_once_init_enter (&g_define_type_id__volatile))
+  if (g_once_init_enter (&static_g_define_type_id))
     {
       static const GFlagsValue values[] = {
         { G_BINDING_DEFAULT, "G_BINDING_DEFAULT", "default" },
@@ -133,10 +133,98 @@ g_binding_flags_get_type (void)
       };
       GType g_define_type_id =
         g_flags_register_static (g_intern_static_string ("GBindingFlags"), values);
-      g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
+      g_once_init_leave (&static_g_define_type_id, g_define_type_id);
     }
 
-  return g_define_type_id__volatile;
+  return static_g_define_type_id;
+}
+
+/* Reference counted helper struct that is passed to all callbacks to ensure
+ * that they never work with already freed objects without having to store
+ * strong references for them.
+ *
+ * Using strong references anywhere is not possible because of the API
+ * requirements of GBinding, specifically that the initial reference of the
+ * GBinding is owned by the source/target and the caller and can be released
+ * either by the source/target being finalized or calling g_binding_unbind().
+ *
+ * As such, the only strong reference has to be owned by both weak notifies of
+ * the source and target and the first to be called has to release it.
+ */
+typedef struct {
+  GWeakRef binding;
+  GWeakRef source;
+  GWeakRef target;
+  gboolean binding_removed;
+} BindingContext;
+
+static BindingContext *
+binding_context_ref (BindingContext *context)
+{
+  return g_atomic_rc_box_acquire (context);
+}
+
+static void
+binding_context_clear (BindingContext *context)
+{
+  g_weak_ref_clear (&context->binding);
+  g_weak_ref_clear (&context->source);
+  g_weak_ref_clear (&context->target);
+}
+
+static void
+binding_context_unref (BindingContext *context)
+{
+  g_atomic_rc_box_release_full (context, (GDestroyNotify) binding_context_clear);
+}
+
+/* Reference counting for the transform functions to ensure that they're always
+ * valid while making use of them in the property notify callbacks.
+ *
+ * The transform functions are released when unbinding but unbinding can happen
+ * while the transform functions are currently in use inside the notify callbacks.
+ */
+typedef struct {
+  GBindingTransformFunc transform_s2t;
+  GBindingTransformFunc transform_t2s;
+
+  gpointer transform_data;
+  GDestroyNotify destroy_notify;
+} TransformFunc;
+
+static TransformFunc *
+transform_func_new (GBindingTransformFunc transform_s2t,
+                    GBindingTransformFunc transform_t2s,
+                    gpointer              transform_data,
+                    GDestroyNotify        destroy_notify)
+{
+  TransformFunc *func = g_atomic_rc_box_new0 (TransformFunc);
+
+  func->transform_s2t = transform_s2t;
+  func->transform_t2s = transform_t2s;
+  func->transform_data = transform_data;
+  func->destroy_notify = destroy_notify;
+
+  return func;
+}
+
+static TransformFunc *
+transform_func_ref (TransformFunc *func)
+{
+  return g_atomic_rc_box_acquire (func);
+}
+
+static void
+transform_func_clear (TransformFunc *func)
+{
+  if (func->destroy_notify)
+    func->destroy_notify (func->transform_data);
+}
+
+static void
+transform_func_unref (TransformFunc *func)
+{
+  g_atomic_rc_box_release_full (func, (GDestroyNotify) transform_func_clear);
 }
 
 #define G_BINDING_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_BINDING, GBindingClass))
@@ -150,8 +238,14 @@ struct _GBinding
   GObject parent_instance;
 
   /* no reference is held on the objects, to avoid cycles */
-  GObject *source;
-  GObject *target;
+  BindingContext *context;
+
+  /* protects transform_func, source, target property notify and
+   * target_weak_notify_installed for unbinding */
+  GMutex unbind_lock;
+
+  /* transform functions, only NULL after unbinding */
+  TransformFunc *transform_func; /* LOCK: unbind_lock */
 
   /* the property names are interned, so they should not be freed */
   const gchar *source_property;
@@ -160,16 +254,11 @@ struct _GBinding
   GParamSpec *source_pspec;
   GParamSpec *target_pspec;
 
-  GBindingTransformFunc transform_s2t;
-  GBindingTransformFunc transform_t2s;
-
   GBindingFlags flags;
 
-  guint source_notify;
-  guint target_notify;
-
-  gpointer transform_data;
-  GDestroyNotify notify;
+  guint source_notify; /* LOCK: unbind_lock */
+  guint target_notify; /* LOCK: unbind_lock */
+  gboolean target_weak_notify_installed; /* LOCK: unbind_lock */
 
   /* a guard, to avoid loops */
   guint is_frozen : 1;
@@ -195,49 +284,136 @@ static guint gobject_notify_signal_id;
 
 G_DEFINE_TYPE (GBinding, g_binding, G_TYPE_OBJECT)
 
-/* the basic assumption is that if either the source or the target
- * goes away then the binding does not exist any more and it should
- * be reaped as well
- */
-static void
-weak_unbind (gpointer  user_data,
-             GObject  *where_the_object_was)
+static void weak_unbind (gpointer user_data, GObject *where_the_object_was);
+
+/* Must be called with the unbind lock held, context/binding != NULL and strong
+ * references to source/target or NULL.
+ * Return TRUE if the binding was actually removed and FALSE if it was already
+ * removed before. */
+static gboolean
+unbind_internal_locked (BindingContext *context, GBinding *binding, GObject *source, GObject *target)
 {
-  GBinding *binding = user_data;
+  gboolean binding_was_removed = FALSE;
+
+  g_assert (context != NULL);
+  g_assert (binding != NULL);
 
-  /* if what went away was the source, unset it so that GBinding::finalize
-   * does not try to access it; otherwise, disconnect everything and remove
-   * the GBinding instance from the object's qdata
+  /* If the target went away we still have a strong reference to the source
+   * here and can clear it from the binding. Otherwise if the source went away
+   * we can clear the target from the binding. Finalizing an object clears its
+   * signal handlers and all weak references pointing to it before calling
+   * weak notify callbacks.
+   *
+   * If both still exist we clean up everything set up by the binding.
    */
-  if (binding->source == where_the_object_was)
-    binding->source = NULL;
-  else
+  if (source)
     {
+      /* We always add/remove the source property notify and the weak notify
+       * of the source at the same time, and should only ever do that once. */
       if (binding->source_notify != 0)
-        g_signal_handler_disconnect (binding->source, binding->source_notify);
+        {
+          g_signal_handler_disconnect (source, binding->source_notify);
 
-      g_object_weak_unref (binding->source, weak_unbind, user_data);
+          g_object_weak_unref (source, weak_unbind, context);
+          binding_context_unref (context);
 
-      binding->source_notify = 0;
-      binding->source = NULL;
+          binding->source_notify = 0;
+        }
+      g_weak_ref_set (&context->source, NULL);
     }
 
-  /* as above, but with the target */
-  if (binding->target == where_the_object_was)
-    binding->target = NULL;
-  else
+  /* As above, but with the target. If source==target then no weak notify was
+   * installed for the target, which is why that is stored as a separate
+   * boolean inside the binding. */
+  if (target)
     {
+      /* There might be a target property notify without a weak notify on the
+       * target or the other way around, so these have to be handled
+       * independently here unlike for the source. */
       if (binding->target_notify != 0)
-        g_signal_handler_disconnect (binding->target, binding->target_notify);
+        {
+          g_signal_handler_disconnect (target, binding->target_notify);
+
+          binding->target_notify = 0;
+        }
+      g_weak_ref_set (&context->target, NULL);
 
-      g_object_weak_unref (binding->target, weak_unbind, user_data);
+      /* Remove the weak notify from the target, at most once */
+      if (binding->target_weak_notify_installed)
+        {
+          g_object_weak_unref (target, weak_unbind, context);
+          binding_context_unref (context);
+          binding->target_weak_notify_installed = FALSE;
+        }
+    }
+
+  /* Make sure to remove the binding only once and return to the caller that
+   * this was the call that actually removed it. */
+  if (!context->binding_removed)
+    {
+      context->binding_removed = TRUE;
+      binding_was_removed = TRUE;
+    }
+
+  return binding_was_removed;
+}
+
+/* the basic assumption is that if either the source or the target
+ * goes away then the binding does not exist any more and it should
+ * be reaped as well. Each weak notify owns a strong reference to the
+ * binding that should be dropped here. */
+static void
+weak_unbind (gpointer  user_data,
+             GObject  *where_the_object_was)
+{
+  BindingContext *context = user_data;
+  GBinding *binding;
+  GObject *source, *target;
+  gboolean binding_was_removed = FALSE;
+  TransformFunc *transform_func;
 
-      binding->target_notify = 0;
-      binding->target = NULL;
+  binding = g_weak_ref_get (&context->binding);
+  if (!binding)
+    {
+      /* The binding was already destroyed before so there's nothing to do */
+      binding_context_unref (context);
+      return;
     }
 
-  /* this will take care of the binding itself */
+  g_mutex_lock (&binding->unbind_lock);
+
+  transform_func = g_steal_pointer (&binding->transform_func);
+
+  source = g_weak_ref_get (&context->source);
+  target = g_weak_ref_get (&context->target);
+
+  /* If this is called then either the source or target or both must be in the
+   * process of being finalized and their weak reference must be reset to NULL
+   * already.
+   *
+   * If source==target then both will always be NULL here. */
+  g_assert (source == NULL || target == NULL);
+
+  binding_was_removed = unbind_internal_locked (context, binding, source, target);
+
+  g_mutex_unlock (&binding->unbind_lock);
+
+  /* Unref source, target and transform_func after the mutex is unlocked as it
+   * might release the last reference, which then accesses the mutex again */
+  g_clear_object (&target);
+  g_clear_object (&source);
+
+  g_clear_pointer (&transform_func, transform_func_unref);
+
+  /* This releases the strong reference we got from the weak ref above */
   g_object_unref (binding);
+
+  /* This will take care of the binding itself. */
+  if (binding_was_removed)
+    g_object_unref (binding);
+
+  /* Each weak notify owns a reference to the binding context. */
+  binding_context_unref (context);
 }
 
 static gboolean
@@ -299,115 +475,172 @@ default_invert_boolean_transform (GBinding     *binding,
 }
 
 static void
-on_source_notify (GObject    *gobject,
-                  GParamSpec *pspec,
-                  GBinding   *binding)
+on_source_notify (GObject          *source,
+                  GParamSpec       *pspec,
+                  BindingContext   *context)
 {
+  GBinding *binding;
+  GObject *target;
+  TransformFunc *transform_func;
   GValue from_value = G_VALUE_INIT;
   GValue to_value = G_VALUE_INIT;
   gboolean res;
 
-  if (binding->is_frozen)
+  binding = g_weak_ref_get (&context->binding);
+  if (!binding)
     return;
 
+  if (binding->is_frozen)
+    {
+      g_object_unref (binding);
+      return;
+    }
+
+  target = g_weak_ref_get (&context->target);
+  if (!target)
+    {
+      g_object_unref (binding);
+      return;
+    }
+
+  /* Get the transform function safely */
+  g_mutex_lock (&binding->unbind_lock);
+  if (!binding->transform_func)
+    {
+      /* it was released already during unbinding, nothing to do here */
+      g_mutex_unlock (&binding->unbind_lock);
+      return;
+    }
+  transform_func = transform_func_ref (binding->transform_func);
+  g_mutex_unlock (&binding->unbind_lock);
+
   g_value_init (&from_value, G_PARAM_SPEC_VALUE_TYPE (binding->source_pspec));
   g_value_init (&to_value, G_PARAM_SPEC_VALUE_TYPE (binding->target_pspec));
 
-  g_object_get_property (binding->source, binding->source_pspec->name, &from_value);
+  g_object_get_property (source, binding->source_pspec->name, &from_value);
+
+  res = transform_func->transform_s2t (binding,
+                                       &from_value,
+                                       &to_value,
+                                       transform_func->transform_data);
+
+  transform_func_unref (transform_func);
 
-  res = binding->transform_s2t (binding,
-                                &from_value,
-                                &to_value,
-                                binding->transform_data);
   if (res)
     {
       binding->is_frozen = TRUE;
 
       g_param_value_validate (binding->target_pspec, &to_value);
-      g_object_set_property (binding->target, binding->target_pspec->name, &to_value);
+      g_object_set_property (target, binding->target_pspec->name, &to_value);
 
       binding->is_frozen = FALSE;
     }
 
   g_value_unset (&from_value);
   g_value_unset (&to_value);
+
+  g_object_unref (target);
+  g_object_unref (binding);
 }
 
 static void
-on_target_notify (GObject    *gobject,
-                  GParamSpec *pspec,
-                  GBinding   *binding)
+on_target_notify (GObject          *target,
+                  GParamSpec       *pspec,
+                  BindingContext   *context)
 {
+  GBinding *binding;
+  GObject *source;
+  TransformFunc *transform_func;
   GValue from_value = G_VALUE_INIT;
   GValue to_value = G_VALUE_INIT;
   gboolean res;
 
-  if (binding->is_frozen)
+  binding = g_weak_ref_get (&context->binding);
+  if (!binding)
     return;
 
+  if (binding->is_frozen)
+    {
+      g_object_unref (binding);
+      return;
+    }
+
+  source = g_weak_ref_get (&context->source);
+  if (!source)
+    {
+      g_object_unref (binding);
+      return;
+    }
+
+  /* Get the transform function safely */
+  g_mutex_lock (&binding->unbind_lock);
+  if (!binding->transform_func)
+    {
+      /* it was released already during unbinding, nothing to do here */
+      g_mutex_unlock (&binding->unbind_lock);
+      return;
+    }
+  transform_func = transform_func_ref (binding->transform_func);
+  g_mutex_unlock (&binding->unbind_lock);
+
   g_value_init (&from_value, G_PARAM_SPEC_VALUE_TYPE (binding->target_pspec));
   g_value_init (&to_value, G_PARAM_SPEC_VALUE_TYPE (binding->source_pspec));
 
-  g_object_get_property (binding->target, binding->target_pspec->name, &from_value);
+  g_object_get_property (target, binding->target_pspec->name, &from_value);
+
+  res = transform_func->transform_t2s (binding,
+                                       &from_value,
+                                       &to_value,
+                                       transform_func->transform_data);
+  transform_func_unref (transform_func);
 
-  res = binding->transform_t2s (binding,
-                                &from_value,
-                                &to_value,
-                                binding->transform_data);
   if (res)
     {
       binding->is_frozen = TRUE;
 
       g_param_value_validate (binding->source_pspec, &to_value);
-      g_object_set_property (binding->source, binding->source_pspec->name, &to_value);
+      g_object_set_property (source, binding->source_pspec->name, &to_value);
 
       binding->is_frozen = FALSE;
     }
 
   g_value_unset (&from_value);
   g_value_unset (&to_value);
+
+  g_object_unref (source);
+  g_object_unref (binding);
 }
 
 static inline void
 g_binding_unbind_internal (GBinding *binding,
                            gboolean  unref_binding)
 {
-  gboolean source_is_target = binding->source == binding->target;
+  BindingContext *context = binding->context;
+  GObject *source, *target;
   gboolean binding_was_removed = FALSE;
+  TransformFunc *transform_func;
 
-  /* dispose of the transformation data */
-  if (binding->notify != NULL)
-    {
-      binding->notify (binding->transform_data);
+  g_mutex_lock (&binding->unbind_lock);
 
-      binding->transform_data = NULL;
-      binding->notify = NULL;
-    }
+  transform_func = g_steal_pointer (&binding->transform_func);
 
-  if (binding->source != NULL)
-    {
-      if (binding->source_notify != 0)
-        g_signal_handler_disconnect (binding->source, binding->source_notify);
+  source = g_weak_ref_get (&context->source);
+  target = g_weak_ref_get (&context->target);
 
-      g_object_weak_unref (binding->source, weak_unbind, binding);
+  /* If the binding was removed previously, source and target are both NULL.
+   * Otherwise both will not be NULL. */
+  g_assert ((source == NULL && target == NULL) || (source != NULL && target != NULL));
 
-      binding->source_notify = 0;
-      binding->source = NULL;
-      binding_was_removed = TRUE;
-    }
+  binding_was_removed = unbind_internal_locked (context, binding, source, target);
 
-  if (binding->target != NULL)
-    {
-      if (binding->target_notify != 0)
-        g_signal_handler_disconnect (binding->target, binding->target_notify);
+  g_mutex_unlock (&binding->unbind_lock);
 
-      if (!source_is_target)
-        g_object_weak_unref (binding->target, weak_unbind, binding);
+  /* Unref source, target and transform_func after the mutex is unlocked as it
+   * might release the last reference, which then accesses the mutex again */
+  g_clear_object (&target);
+  g_clear_object (&source);
 
-      binding->target_notify = 0;
-      binding->target = NULL;
-      binding_was_removed = TRUE;
-    }
+  g_clear_pointer (&transform_func, transform_func_unref);
 
   if (binding_was_removed && unref_binding)
     g_object_unref (binding);
@@ -420,6 +653,10 @@ g_binding_finalize (GObject *gobject)
 
   g_binding_unbind_internal (binding, FALSE);
 
+  binding_context_unref (binding->context);
+
+  g_mutex_clear (&binding->unbind_lock);
+
   G_OBJECT_CLASS (g_binding_parent_class)->finalize (gobject);
 }
 
@@ -481,11 +718,11 @@ g_binding_set_property (GObject      *gobject,
   switch (prop_id)
     {
     case PROP_SOURCE:
-      binding->source = g_value_get_object (value);
+      g_weak_ref_set (&binding->context->source, g_value_get_object (value));
       break;
 
     case PROP_TARGET:
-      binding->target = g_value_get_object (value);
+      g_weak_ref_set (&binding->context->target, g_value_get_object (value));
       break;
 
     case PROP_SOURCE_PROPERTY:
@@ -535,7 +772,7 @@ g_binding_get_property (GObject    *gobject,
   switch (prop_id)
     {
     case PROP_SOURCE:
-      g_value_set_object (value, binding->source);
+      g_value_take_object (value, g_weak_ref_get (&binding->context->source));
       break;
 
     case PROP_SOURCE_PROPERTY:
@@ -544,7 +781,7 @@ g_binding_get_property (GObject    *gobject,
       break;
 
     case PROP_TARGET:
-      g_value_set_object (value, binding->target);
+      g_value_take_object (value, g_weak_ref_get (&binding->context->target));
       break;
 
     case PROP_TARGET_PROPERTY:
@@ -567,12 +804,15 @@ g_binding_constructed (GObject *gobject)
 {
   GBinding *binding = G_BINDING (gobject);
   GBindingTransformFunc transform_func = default_transform;
+  GObject *source, *target;
   GQuark source_property_detail;
   GClosure *source_notify_closure;
 
   /* assert that we were constructed correctly */
-  g_assert (binding->source != NULL);
-  g_assert (binding->target != NULL);
+  source = g_weak_ref_get (&binding->context->source);
+  target = g_weak_ref_get (&binding->context->target);
+  g_assert (source != NULL);
+  g_assert (target != NULL);
   g_assert (binding->source_property != NULL);
   g_assert (binding->target_property != NULL);
 
@@ -580,8 +820,8 @@ g_binding_constructed (GObject *gobject)
    * g_object_bind_property_full() does it; we cannot fail construction
    * anyway, so it would be hard for use to properly warn here
    */
-  binding->source_pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (binding->source), binding->source_property);
-  binding->target_pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (binding->target), binding->target_property);
+  binding->source_pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (source), binding->source_property);
+  binding->target_pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (target), binding->target_property);
   g_assert (binding->source_pspec != NULL);
   g_assert (binding->target_pspec != NULL);
 
@@ -590,22 +830,19 @@ g_binding_constructed (GObject *gobject)
     transform_func = default_invert_boolean_transform;
 
   /* set the default transformation functions here */
-  binding->transform_s2t = transform_func;
-  binding->transform_t2s = transform_func;
-
-  binding->transform_data = NULL;
-  binding->notify = NULL;
+  binding->transform_func = transform_func_new (transform_func, transform_func, NULL, NULL);
 
   source_property_detail = g_quark_from_string (binding->source_property);
   source_notify_closure = g_cclosure_new (G_CALLBACK (on_source_notify),
-                                          binding, NULL);
-  binding->source_notify = g_signal_connect_closure_by_id (binding->source,
+                                          binding_context_ref (binding->context),
+                                          (GClosureNotify) binding_context_unref);
+  binding->source_notify = g_signal_connect_closure_by_id (source,
                                                            gobject_notify_signal_id,
                                                            source_property_detail,
                                                            source_notify_closure,
                                                            FALSE);
 
-  g_object_weak_ref (binding->source, weak_unbind, binding);
+  g_object_weak_ref (source, weak_unbind, binding_context_ref (binding->context));
 
   if (binding->flags & G_BINDING_BIDIRECTIONAL)
     {
@@ -614,16 +851,27 @@ g_binding_constructed (GObject *gobject)
 
       target_property_detail = g_quark_from_string (binding->target_property);
       target_notify_closure = g_cclosure_new (G_CALLBACK (on_target_notify),
-                                              binding, NULL);
-      binding->target_notify = g_signal_connect_closure_by_id (binding->target,
+                                              binding_context_ref (binding->context),
+                                              (GClosureNotify) binding_context_unref);
+      binding->target_notify = g_signal_connect_closure_by_id (target,
                                                                gobject_notify_signal_id,
                                                                target_property_detail,
                                                                target_notify_closure,
                                                                FALSE);
     }
 
-  if (binding->target != binding->source)
-    g_object_weak_ref (binding->target, weak_unbind, binding);
+  if (target != source)
+    {
+      g_object_weak_ref (target, weak_unbind, binding_context_ref (binding->context));
+
+      /* Need to remember separately if a target weak notify was installed as
+       * unlike for the source it can exist independently of the property
+       * notification callback */
+      binding->target_weak_notify_installed = TRUE;
+    }
+
+  g_object_unref (source);
+  g_object_unref (target);
 }
 
 static void
@@ -728,6 +976,12 @@ g_binding_class_init (GBindingClass *klass)
 static void
 g_binding_init (GBinding *binding)
 {
+  g_mutex_init (&binding->unbind_lock);
+
+  binding->context = g_atomic_rc_box_new0 (BindingContext);
+  g_weak_ref_init (&binding->context->binding, binding);
+  g_weak_ref_init (&binding->context->source, NULL);
+  g_weak_ref_init (&binding->context->target, NULL);
 }
 
 /**
@@ -758,17 +1012,55 @@ g_binding_get_flags (GBinding *binding)
  * strong reference to the source. If the source is destroyed before the
  * binding then this function will return %NULL.
  *
+ * Use g_binding_dup_source() if the source or binding are used from different
+ * threads as otherwise the pointer returned from this function might become
+ * invalid if the source is finalized from another thread in the meantime.
+ *
  * Returns: (transfer none) (nullable): the source #GObject, or %NULL if the
  *     source does not exist any more.
  *
+ * Deprecated: 2.68: Use g_binding_dup_source() for a safer version of this
+ * function.
+ *
  * Since: 2.26
  */
 GObject *
 g_binding_get_source (GBinding *binding)
 {
+  GObject *source;
+
+  g_return_val_if_fail (G_IS_BINDING (binding), NULL);
+
+  source = g_weak_ref_get (&binding->context->source);
+  /* Unref here, this API is not thread-safe
+   * FIXME: Remove this API when we next break API */
+  if (source)
+    g_object_unref (source);
+
+  return source;
+}
+
+/**
+ * g_binding_dup_source:
+ * @binding: a #GBinding
+ *
+ * Retrieves the #GObject instance used as the source of the binding.
+ *
+ * A #GBinding can outlive the source #GObject as the binding does not hold a
+ * strong reference to the source. If the source is destroyed before the
+ * binding then this function will return %NULL.
+ *
+ * Returns: (transfer full) (nullable): the source #GObject, or %NULL if the
+ *     source does not exist any more.
+ *
+ * Since: 2.68
+ */
+GObject *
+g_binding_dup_source (GBinding *binding)
+{
   g_return_val_if_fail (G_IS_BINDING (binding), NULL);
 
-  return binding->source;
+  return g_weak_ref_get (&binding->context->source);
 }
 
 /**
@@ -781,17 +1073,55 @@ g_binding_get_source (GBinding *binding)
  * strong reference to the target. If the target is destroyed before the
  * binding then this function will return %NULL.
  *
+ * Use g_binding_dup_target() if the target or binding are used from different
+ * threads as otherwise the pointer returned from this function might become
+ * invalid if the target is finalized from another thread in the meantime.
+ *
  * Returns: (transfer none) (nullable): the target #GObject, or %NULL if the
  *     target does not exist any more.
  *
+ * Deprecated: 2.68: Use g_binding_dup_target() for a safer version of this
+ * function.
+ *
  * Since: 2.26
  */
 GObject *
 g_binding_get_target (GBinding *binding)
 {
+  GObject *target;
+
+  g_return_val_if_fail (G_IS_BINDING (binding), NULL);
+
+  target = g_weak_ref_get (&binding->context->target);
+  /* Unref here, this API is not thread-safe
+   * FIXME: Remove this API when we next break API */
+  if (target)
+    g_object_unref (target);
+
+  return target;
+}
+
+/**
+ * g_binding_dup_target:
+ * @binding: a #GBinding
+ *
+ * Retrieves the #GObject instance used as the target of the binding.
+ *
+ * A #GBinding can outlive the target #GObject as the binding does not hold a
+ * strong reference to the target. If the target is destroyed before the
+ * binding then this function will return %NULL.
+ *
+ * Returns: (transfer full) (nullable): the target #GObject, or %NULL if the
+ *     target does not exist any more.
+ *
+ * Since: 2.68
+ */
+GObject *
+g_binding_dup_target (GBinding *binding)
+{
   g_return_val_if_fail (G_IS_BINDING (binding), NULL);
 
-  return binding->target;
+  return g_weak_ref_get (&binding->context->target);
 }
 
 /**
@@ -840,9 +1170,13 @@ g_binding_get_target_property (GBinding *binding)
  * property expressed by @binding.
  *
  * This function will release the reference that is being held on
- * the @binding instance; if you want to hold on to the #GBinding instance
- * after calling g_binding_unbind(), you will need to hold a reference
- * to it.
+ * the @binding instance if the binding is still bound; if you want to hold on
+ * to the #GBinding instance after calling g_binding_unbind(), you will need
+ * to hold a reference to it.
+ *
+ * Note however that this function does not take ownership of @binding, it
+ * only unrefs the reference that was initially created by
+ * g_object_bind_property() and is owned by the binding.
  *
  * Since: 2.38
  */
@@ -1028,14 +1362,17 @@ g_object_bind_property_full (gpointer               source,
                           "flags", flags,
                           NULL);
 
-  if (transform_to != NULL)
-    binding->transform_s2t = transform_to;
+  g_assert (binding->transform_func != NULL);
 
-  if (transform_from != NULL)
-    binding->transform_t2s = transform_from;
+  /* Use default functions if not provided here */
+  if (transform_to == NULL)
+    transform_to = binding->transform_func->transform_s2t;
+
+  if (transform_from == NULL)
+    transform_from = binding->transform_func->transform_t2s;
 
-  binding->transform_data = user_data;
-  binding->notify = notify;
+  g_clear_pointer (&binding->transform_func, transform_func_unref);
+  binding->transform_func = transform_func_new (transform_to, transform_from, user_data, notify);
 
   /* synchronize the target with the source by faking an emission of
    * the ::notify signal for the source property; this will also take
@@ -1043,7 +1380,7 @@ g_object_bind_property_full (gpointer               source,
    * will emit a notification on the target
    */
   if (flags & G_BINDING_SYNC_CREATE)
-    on_source_notify (binding->source, binding->source_pspec, binding);
+    on_source_notify (source, binding->source_pspec, binding->context);
 
   return binding;
 }
@@ -1077,6 +1414,13 @@ g_object_bind_property_full (gpointer               source,
  * @source and the @target you can just call g_object_unref() on the returned
  * #GBinding instance.
  *
+ * Removing the binding by calling g_object_unref() on it must only be done if
+ * the binding, @source and @target are only used from a single thread and it
+ * is clear that both @source and @target outlive the binding. Especially it
+ * is not safe to rely on this if the binding, @source or @target can be
+ * finalized from different threads. Keep another reference to the binding and
+ * use g_binding_unbind() instead to be on the safe side.
+ *
  * A #GObject can have multiple bindings.
  *
  * Returns: (transfer none): the #GBinding instance representing the
index b4eb233..84dad7f 100644 (file)
@@ -108,10 +108,14 @@ GType                 g_binding_get_type            (void) G_GNUC_CONST;
 
 GLIB_AVAILABLE_IN_ALL
 GBindingFlags         g_binding_get_flags           (GBinding *binding);
-GLIB_AVAILABLE_IN_ALL
+GLIB_DEPRECATED_IN_2_68_FOR(g_binding_dup_source)
 GObject *             g_binding_get_source          (GBinding *binding);
-GLIB_AVAILABLE_IN_ALL
+GLIB_AVAILABLE_IN_2_68
+GObject *             g_binding_dup_source          (GBinding *binding);
+GLIB_DEPRECATED_IN_2_68_FOR(g_binding_dup_target)
 GObject *             g_binding_get_target          (GBinding *binding);
+GLIB_AVAILABLE_IN_2_68
+GObject *             g_binding_dup_target          (GBinding *binding);
 GLIB_AVAILABLE_IN_ALL
 const gchar *         g_binding_get_source_property (GBinding *binding);
 GLIB_AVAILABLE_IN_ALL
index 30ba4e7..1942513 100644 (file)
@@ -180,19 +180,19 @@ G_DEFINE_BOXED_TYPE (GOptionGroup, g_option_group, g_option_group_ref, g_option_
 GType
 g_strv_get_type (void)
 {
-  static volatile gsize g_define_type_id__volatile = 0;
+  static gsize static_g_define_type_id = 0;
 
-  if (g_once_init_enter (&g_define_type_id__volatile))
+  if (g_once_init_enter (&static_g_define_type_id))
     {
       GType g_define_type_id =
         g_boxed_type_register_static (g_intern_static_string ("GStrv"),
                                       (GBoxedCopyFunc) g_strdupv,
                                       (GBoxedFreeFunc) g_strfreev);
 
-      g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
+      g_once_init_leave (&static_g_define_type_id, g_define_type_id);
     }
 
-  return g_define_type_id__volatile;
+  return static_g_define_type_id;
 }
 
 GType
index 7caf9c4..6d41e6d 100644 (file)
@@ -98,7 +98,7 @@
 
 typedef union {
   GClosure closure;
-  volatile gint vint;
+  gint vint;
 } ClosureInt;
 
 #define CHANGE_FIELD(_closure, _field, _OP, _value, _must_set, _SET_OLD, _SET_NEW)      \
@@ -1258,8 +1258,12 @@ static void
 value_from_ffi_type (GValue *gvalue, gpointer *value)
 {
   ffi_arg *int_val = (ffi_arg*) value;
+  GType type;
 
-  switch (g_type_fundamental (G_VALUE_TYPE (gvalue)))
+  type = G_VALUE_TYPE (gvalue);
+
+restart:
+  switch (g_type_fundamental (type))
     {
     case G_TYPE_INT:
       g_value_set_int (gvalue, (gint) *int_val);
@@ -1318,9 +1322,15 @@ value_from_ffi_type (GValue *gvalue, gpointer *value)
     case G_TYPE_VARIANT:
       g_value_take_variant (gvalue, *(gpointer*)value);
       break;
+    case G_TYPE_INTERFACE:
+      type = g_type_interface_instantiatable_prerequisite (type);
+      if (type)
+        goto restart;
+      G_GNUC_FALLTHROUGH;
     default:
-      g_warning ("value_from_ffi_type: Unsupported fundamental type: %s",
-                g_type_name (g_type_fundamental (G_VALUE_TYPE (gvalue))));
+      g_warning ("value_from_ffi_type: Unsupported fundamental type %s for type %s",
+                 g_type_name (g_type_fundamental (G_VALUE_TYPE (gvalue))),
+                 g_type_name (G_VALUE_TYPE (gvalue)));
     }
 }
 
index a0f91f5..884e403 100644 (file)
@@ -175,20 +175,20 @@ struct _GClosureNotifyData
 struct _GClosure
 {
   /*< private >*/
-  volatile             guint    ref_count : 15;
+  guint ref_count : 15;  /* (atomic) */
   /* meta_marshal is not used anymore but must be zero for historical reasons
      as it was exposed in the G_CLOSURE_N_NOTIFIERS macro */
-  volatile             guint    meta_marshal_nouse : 1;
-  volatile             guint    n_guards : 1;
-  volatile             guint    n_fnotifiers : 2;      /* finalization notifiers */
-  volatile             guint    n_inotifiers : 8;      /* invalidation notifiers */
-  volatile             guint    in_inotify : 1;
-  volatile             guint    floating : 1;
+  guint meta_marshal_nouse : 1;  /* (atomic) */
+  guint n_guards : 1;  /* (atomic) */
+  guint n_fnotifiers : 2;  /* finalization notifiers (atomic) */
+  guint n_inotifiers : 8;  /* invalidation notifiers (atomic) */
+  guint in_inotify : 1;  /* (atomic) */
+  guint floating : 1;  /* (atomic) */
   /*< protected >*/
-  volatile             guint    derivative_flag : 1;
+  guint derivative_flag : 1;  /* (atomic) */
   /*< public >*/
-  volatile             guint    in_marshal : 1;
-  volatile             guint    is_invalid : 1;
+  guint in_marshal : 1;  /* (atomic) */
+  guint is_invalid : 1;  /* (atomic) */
 
   /*< private >*/      void   (*marshal)  (GClosure       *closure,
                                            GValue /*out*/ *return_value,
index b7d3672..1800ca8 100644 (file)
@@ -13,9 +13,9 @@
 GType
 @enum_name@_get_type (void)
 {
-  static volatile gsize g_define_type_id__volatile = 0;
+  static gsize static_g_define_type_id = 0;
 
-  if (g_once_init_enter (&g_define_type_id__volatile))
+  if (g_once_init_enter (&static_g_define_type_id))
     {
       static const G@Type@Value values[] = {
 /*** END value-header ***/
@@ -29,10 +29,10 @@ GType
       };
       GType g_define_type_id =
         g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
-      g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
+      g_once_init_leave (&static_g_define_type_id, g_define_type_id);
     }
 
-  return g_define_type_id__volatile;
+  return static_g_define_type_id;
 }
 
 /*** END value-tail ***/
index d8a31a3..863d5b6 100644 (file)
@@ -48,8 +48,8 @@
  * For a tutorial on implementing a new GObject class, see [How to define and
  * implement a new GObject][howto-gobject]. For a list of naming conventions for
  * GObjects and their methods, see the [GType conventions][gtype-conventions].
- * For the high-level concepts behind GObject, read [Instantiable classed types:
- * Objects][gtype-instantiable-classed].
+ * For the high-level concepts behind GObject, read [Instantiatable classed types:
+ * Objects][gtype-instantiatable-classed].
  *
  * ## Floating references # {#floating-ref}
  *
@@ -174,9 +174,9 @@ typedef struct
   GTypeInstance  g_type_instance;
 
   /*< private >*/
-  volatile guint ref_count;
+  guint          ref_count;  /* (atomic) */
 #ifdef HAVE_OPTIONAL_FLAGS
-  volatile guint optional_flags;
+  guint          optional_flags;  /* (atomic) */
 #endif
   GData         *qdata;
 } GObjectReal;
@@ -749,7 +749,7 @@ g_object_class_install_properties (GObjectClass  *oclass,
                                    GParamSpec   **pspecs)
 {
   GType oclass_type, parent_type;
-  gint i;
+  guint i;
 
   g_return_if_fail (G_IS_OBJECT_CLASS (oclass));
   g_return_if_fail (n_pspecs > 1);
@@ -1798,7 +1798,7 @@ g_object_new_with_custom_constructor (GObjectClass          *class,
   gint n_cparams;
   gint cvals_used;
   GSList *node;
-  gint i;
+  guint i;
 
   /* If we have ->constructed() then we have to do a lot more work.
    * It's possible that this is a singleton and it's also possible
@@ -1828,7 +1828,7 @@ g_object_new_with_custom_constructor (GObjectClass          *class,
     {
       GParamSpec *pspec;
       GValue *value;
-      gint j;
+      guint j;
 
       pspec = node->data;
       value = NULL; /* to silence gcc... */
@@ -1954,7 +1954,7 @@ g_object_new_internal (GObjectClass          *class,
         {
           const GValue *value;
           GParamSpec *pspec;
-          gint j;
+          guint j;
 
           pspec = node->data;
           value = NULL; /* to silence gcc... */
@@ -1980,7 +1980,7 @@ g_object_new_internal (GObjectClass          *class,
 
   if (nqueue)
     {
-      gint i;
+      guint i;
 
       /* Set remaining properties.  The construct properties will
        * already have been taken, so set only the non-construct
@@ -2005,9 +2005,10 @@ g_object_new_is_valid_property (GType                  object_type,
                                 GParamSpec            *pspec,
                                 const char            *name,
                                 GObjectConstructParam *params,
-                                int                    n_params)
+                                guint                  n_params)
 {
-  gint i;
+  guint i;
+
   if (G_UNLIKELY (pspec == NULL))
     {
       g_critical ("%s: object class '%s' has no property named '%s'",
@@ -2217,13 +2218,15 @@ g_object_new_valist (GType        object_type,
 
   if (first_property_name)
     {
-      GObjectConstructParam stack_params[16];
-      GObjectConstructParam *params;
+      GObjectConstructParam params_stack[16];
+      GValue values_stack[G_N_ELEMENTS (params_stack)];
       const gchar *name;
-      gint n_params = 0;
+      GObjectConstructParam *params = params_stack;
+      GValue *values = values_stack;
+      guint n_params = 0;
+      guint n_params_alloc = G_N_ELEMENTS (params_stack);
 
       name = first_property_name;
-      params = stack_params;
 
       do
         {
@@ -2235,24 +2238,39 @@ g_object_new_valist (GType        object_type,
           if (!g_object_new_is_valid_property (object_type, pspec, name, params, n_params))
             break;
 
-          if (n_params == 16)
+          if (G_UNLIKELY (n_params == n_params_alloc))
             {
-              params = g_new (GObjectConstructParam, n_params + 1);
-              memcpy (params, stack_params, sizeof stack_params);
+              guint i;
+
+              if (n_params_alloc == G_N_ELEMENTS (params_stack))
+                {
+                  n_params_alloc = G_N_ELEMENTS (params_stack) * 2u;
+                  params = g_new (GObjectConstructParam, n_params_alloc);
+                  values = g_new (GValue, n_params_alloc);
+                  memcpy (params, params_stack, sizeof (GObjectConstructParam) * n_params);
+                  memcpy (values, values_stack, sizeof (GValue) * n_params);
+                }
+              else
+                {
+                  n_params_alloc *= 2u;
+                  params = g_realloc (params, sizeof (GObjectConstructParam) * n_params_alloc);
+                  values = g_realloc (values, sizeof (GValue) * n_params_alloc);
+                }
+
+              for (i = 0; i < n_params; i++)
+                params[i].value = &values[i];
             }
-          else if (n_params > 16)
-            params = g_renew (GObjectConstructParam, params, n_params + 1);
 
           params[n_params].pspec = pspec;
-          params[n_params].value = g_newa (GValue, 1);
-          memset (params[n_params].value, 0, sizeof (GValue));
+          params[n_params].value = &values[n_params];
+          memset (&values[n_params], 0, sizeof (GValue));
 
-          G_VALUE_COLLECT_INIT (params[n_params].value, pspec->value_type, var_args, 0, &error);
+          G_VALUE_COLLECT_INIT (&values[n_params], pspec->value_type, var_args, 0, &error);
 
           if (error)
             {
               g_critical ("%s: %s", G_STRFUNC, error);
-              g_value_unset (params[n_params].value);
+              g_value_unset (&values[n_params]);
               g_free (error);
               break;
             }
@@ -2266,8 +2284,11 @@ g_object_new_valist (GType        object_type,
       while (n_params--)
         g_value_unset (params[n_params].value);
 
-      if (params != stack_params)
-        g_free (params);
+      if (G_UNLIKELY (n_params_alloc != G_N_ELEMENTS (params_stack)))
+        {
+          g_free (params);
+          g_free (values);
+        }
     }
   else
     /* Fast case: no properties passed in. */
index bf5496c..a84c183 100644 (file)
@@ -247,7 +247,7 @@ struct  _GObject
   GTypeInstance  g_type_instance;
   
   /*< private >*/
-  volatile guint ref_count;
+  guint          ref_count;  /* (atomic) */
   GData         *qdata;
 };
 /**
@@ -679,16 +679,16 @@ void    g_clear_object (GObject **object_ptr);
 
 /**
  * g_set_object: (skip)
- * @object_ptr: a pointer to a #GObject reference
+ * @object_ptr: (inout) (not optional) (nullable): a pointer to a #GObject reference
  * @new_object: (nullable) (transfer none): a pointer to the new #GObject to
- *   assign to it, or %NULL to clear the pointer
+ *   assign to @object_ptr, or %NULL to clear the pointer
  *
  * Updates a #GObject pointer to refer to @new_object. It increments the
  * reference count of @new_object (if non-%NULL), decrements the reference
  * count of the current value of @object_ptr (if non-%NULL), and assigns
  * @new_object to @object_ptr. The assignment is not atomic.
  *
- * @object_ptr must not be %NULL.
+ * @object_ptr must not be %NULL, but can point to a %NULL value.
  *
  * A macro is also included that allows this function to be used without
  * pointer casts. The function itself is static inline, so its address may vary
index 263ac78..ac9fd4e 100644 (file)
@@ -1,4 +1,3 @@
-import os.path
 import gdb
 import glib_gdb
 import sys
@@ -7,25 +6,29 @@ if sys.version_info[0] >= 3:
     long = int
 else:
     import itertools
+
     map = itertools.imap
 
 # FrameDecorator is new in gdb 7.7, so we adapt to its absence.
 try:
     import gdb.FrameDecorator
+
     HAVE_GDB_FRAMEDECORATOR = True
     FrameDecorator = gdb.FrameDecorator.FrameDecorator
 except ImportError:
     HAVE_GDB_FRAMEDECORATOR = False
 
+
 # This is not quite right, as local vars may override symname
-def read_global_var (symname):
+def read_global_var(symname):
     return gdb.selected_frame().read_var(symname)
 
-def g_type_to_typenode (gtype):
-    def lookup_fundamental_type (typenode):
+
+def g_type_to_typenode(gtype):
+    def lookup_fundamental_type(typenode):
         if typenode == 0:
             return None
-        val = read_global_var ("static_fundamental_type_nodes")
+        val = read_global_var("static_fundamental_type_nodes")
         if val is None:
             return None
         return val[typenode >> 2].address
@@ -33,19 +36,21 @@ def g_type_to_typenode (gtype):
     gtype = long(gtype)
     typenode = gtype - gtype % 4
     if typenode > (255 << 2):
-        typenode = gdb.Value(typenode).cast (gdb.lookup_type("TypeNode").pointer())
+        typenode = gdb.Value(typenode).cast(gdb.lookup_type("TypeNode").pointer())
     else:
-        typenode = lookup_fundamental_type (typenode)
+        typenode = lookup_fundamental_type(typenode)
     return typenode
 
-def g_type_to_name (gtype):
+
+def g_type_to_name(gtype):
     typenode = g_type_to_typenode(gtype)
-    if typenode != None:
-        return glib_gdb.g_quark_to_string (typenode["qname"])
+    if typenode is not None:
+        return glib_gdb.g_quark_to_string(typenode["qname"])
     return None
 
-def is_g_type_instance (val):
-    def is_g_type_instance_helper (type):
+
+def is_g_type_instance(val):
+    def is_g_type_instance_helper(type):
         if str(type) == "GTypeInstance":
             return True
 
@@ -56,7 +61,7 @@ def is_g_type_instance (val):
             return False
 
         fields = type.fields()
-        if len (fields) < 1:
+        if len(fields) < 1:
             return False
 
         first_field = fields[0]
@@ -66,51 +71,55 @@ def is_g_type_instance (val):
     if type.code != gdb.TYPE_CODE_PTR:
         return False
     type = type.target()
-    return is_g_type_instance_helper (type)
+    return is_g_type_instance_helper(type)
+
 
-def g_type_name_from_instance (instance):
+def g_type_name_from_instance(instance):
     if long(instance) != 0:
         try:
-            inst = instance.cast (gdb.lookup_type("GTypeInstance").pointer())
+            inst = instance.cast(gdb.lookup_type("GTypeInstance").pointer())
             klass = inst["g_class"]
             gtype = klass["g_type"]
-            name = g_type_to_name (gtype)
+            name = g_type_to_name(gtype)
             return name
         except RuntimeError:
             pass
     return None
 
+
 class GTypePrettyPrinter:
     "Prints a GType instance pointer"
 
-    def __init__ (self, val):
+    def __init__(self, val):
         self.val = val
 
-    def to_string (self):
-        name = g_type_name_from_instance (self.val)
+    def to_string(self):
+        name = g_type_name_from_instance(self.val)
         if name:
-            return ("0x%x [%s]")% (long(self.val), name)
-        return  ("0x%x") % (long(self.val))
+            return ("0x%x [%s]") % (long(self.val), name)
+        return ("0x%x") % (long(self.val))
 
-def is_g_type_class_instance (val):
+
+def is_g_type_class_instance(val):
     type = val.type
     if type.code != gdb.TYPE_CODE_PTR:
         return False
     return str(type.target()) == "GTypeClass"
 
+
 class GTypeHandlePrettyPrinter:
     "Prints a GType instance"
 
-    def __init__ (self, val, hint = ""):
+    def __init__(self, val, hint=""):
         self.val = val
         self.hint = hint
 
-    def to_string (self):
+    def to_string(self):
         typenode = g_type_to_typenode(self.val)
-        if typenode != None:
-            name = glib_gdb.g_quark_to_string (typenode["qname"])
-            s = ("0x%x [%s%s")% (long(self.val), self.hint, name)
-            for i in range (1, int(typenode["n_supers"])):
+        if typenode is not None:
+            name = glib_gdb.g_quark_to_string(typenode["qname"])
+            s = ("0x%x [%s%s") % (long(self.val), self.hint, name)
+            for i in range(1, int(typenode["n_supers"])):
                 node = g_type_to_typenode(typenode["supers"][i])
                 if node:
                     name = glib_gdb.g_quark_to_string(node["qname"])
@@ -119,163 +128,170 @@ class GTypeHandlePrettyPrinter:
                 s += "/" + name
             return s + "]"
         else:
-            return  ("0x%x") % (long(self.val))
+            return ("0x%x") % (long(self.val))
 
-def pretty_printer_lookup (val):
-    if is_g_type_instance (val):
-        return GTypePrettyPrinter (val)
+
+def pretty_printer_lookup(val):
+    if is_g_type_instance(val):
+        return GTypePrettyPrinter(val)
     if str(val.type) == "GType":
-        return GTypeHandlePrettyPrinter (val)
-    if is_g_type_class_instance (val):
-        return GTypeHandlePrettyPrinter (val["g_type"], "g_type: ")
+        return GTypeHandlePrettyPrinter(val)
+    if is_g_type_class_instance(val):
+        return GTypeHandlePrettyPrinter(val["g_type"], "g_type: ")
 
     return None
 
-def get_signal_name (id):
+
+def get_signal_name(id):
     if id is None:
         return None
     id = long(id)
     if id == 0:
         return None
-    val = read_global_var ("g_signal_nodes")
-    max_s = read_global_var ("g_n_signal_nodes")
+    val = read_global_var("g_signal_nodes")
+    max_s = read_global_var("g_n_signal_nodes")
     max_s = long(max_s)
     if id < max_s:
         return val[id]["name"].string()
     return None
 
+
 def frame_name(frame):
     return str(frame.function())
 
+
 def frame_var(frame, var):
     return frame.inferior_frame().read_var(var)
 
 
 class SignalFrame(FrameDecorator):
-    def __init__ (self, frames):
+    def __init__(self, frames):
         FrameDecorator.__init__(self, frames[-1])
         self.frame = frames[-1]
         self.frames = frames
 
-    def name (self):
+    def name(self):
         return "signal-emission"
 
-    def read_var (self, frame, name, array = None):
+    def read_var(self, frame, name, array=None):
         try:
-            v = frame_var (frame, name)
+            v = frame_var(frame, name)
             if v is None or v.is_optimized_out:
                 return None
-            if array != None:
-                array.append (v)
+            if array is not None:
+                array.append(v)
             return v
         except ValueError:
             return None
 
-    def read_object (self, frame, name, array = None):
+    def read_object(self, frame, name, array=None):
         try:
-            v = frame_var (frame, name)
+            v = frame_var(frame, name)
             if v is None or v.is_optimized_out:
                 return None
-            v = v.cast (gdb.lookup_type("GObject").pointer())
+            v = v.cast(gdb.lookup_type("GObject").pointer())
             # Ensure this is a somewhat correct object pointer
-            if v != None and g_type_name_from_instance (v):
-                if array != None:
-                    array.append (v)
+            if v is not None and g_type_name_from_instance(v):
+                if array is not None:
+                    array.append(v)
                 return v
             return None
         except ValueError:
             return None
 
-    def append (self, array, obj):
-        if obj != None:
-            array.append (obj)
+    def append(self, array, obj):
+        if obj is not None:
+            array.append(obj)
 
-    def or_join_array (self, array):
+    def or_join_array(self, array):
         if len(array) == 0:
             return "???"
         else:
-            return ' or '.join(set(map(str, array)))
+            return " or ".join(set(map(str, array)))
 
     def get_detailed_signal_from_frame(self, frame, signal):
-        detail = self.read_var (frame, "detail")
-        detail = glib_gdb.g_quark_to_string (detail)
+        detail = self.read_var(frame, "detail")
+        detail = glib_gdb.g_quark_to_string(detail)
         if detail is not None:
             return signal + ":" + detail
         else:
             return detail
 
-    def function (self):
+    def function(self):
         instances = []
         signals = []
 
         for frame in self.frames:
             name = frame_name(frame)
             if name == "signal_emit_unlocked_R":
-                self.read_object (frame, "instance", instances)
-                node = self.read_var (frame, "node")
+                self.read_object(frame, "instance", instances)
+                node = self.read_var(frame, "node")
                 if node:
                     signal = node["name"].string()
                     signal = self.get_detailed_signal_from_frame(frame, signal)
                     self.append(signals, signal)
 
             if name == "g_signal_emitv":
-                instance_and_params = self.read_var (frame, "instance_and_params")
+                instance_and_params = self.read_var(frame, "instance_and_params")
                 if instance_and_params:
-                    instance = instance_and_params[0]["v_pointer"].cast (gdb.Type("GObject").pointer())
-                    self.append (instances, instance)
-                id = self.read_var (frame, "signal_id")
-                signal = get_signal_name (id)
+                    instance = instance_and_params[0]["v_pointer"].cast(
+                        gdb.Type("GObject").pointer()
+                    )
+                    self.append(instances, instance)
+                id = self.read_var(frame, "signal_id")
+                signal = get_signal_name(id)
                 if signal:
                     signal = self.get_detailed_signal_from_frame(frame, signal)
-                    self.append (signals, signal)
+                    self.append(signals, signal)
 
             if name == "g_signal_emit_valist" or name == "g_signal_emit":
-                self.read_object (frame, "instance", instances)
-                id = self.read_var (frame, "signal_id")
-                signal = get_signal_name (id)
+                self.read_object(frame, "instance", instances)
+                id = self.read_var(frame, "signal_id")
+                signal = get_signal_name(id)
                 if signal:
                     signal = self.get_detailed_signal_from_frame(frame, signal)
-                    self.append (signals, signal)
+                    self.append(signals, signal)
 
             if name == "g_signal_emit_by_name":
-                self.read_object (frame, "instance", instances)
-                self.read_var (frame, "detailed_signal", signals)
+                self.read_object(frame, "instance", instances)
+                self.read_var(frame, "detailed_signal", signals)
                 break
 
-        instance = self.or_join_array (instances)
-        signal = self.or_join_array (signals)
+        instance = self.or_join_array(instances)
+        signal = self.or_join_array(signals)
 
-        return "<emit signal %s on instance %s>" %  (signal, instance)
+        return "<emit signal %s on instance %s>" % (signal, instance)
 
-    def elided (self):
+    def elided(self):
         return self.frames[0:-1]
 
-    def describe (self, stream, full):
-        stream.write (" " + self.function () + "\n")
+    def describe(self, stream, full):
+        stream.write(" " + self.function() + "\n")
+
 
 class GFrameDecorator:
-    def __init__ (self, iter):
+    def __init__(self, iter):
         self.queue = []
         self.iter = iter
 
-    def __iter__ (self):
+    def __iter__(self):
         return self
 
-    def fill (self):
+    def fill(self):
         while len(self.queue) <= 8:
             try:
                 f = next(self.iter)
-                self.queue.append (f)
+                self.queue.append(f)
             except StopIteration:
                 return
 
-    def find_signal_emission (self):
-        for i in range (min (len(self.queue), 3)):
+    def find_signal_emission(self):
+        for i in range(min(len(self.queue), 3)):
             if frame_name(self.queue[i]) == "signal_emit_unlocked_R":
                 return i
         return -1
 
-    def next (self):
+    def next(self):
         # Ensure we have enough frames for a full signal emission
         self.fill()
 
@@ -283,24 +299,26 @@ class GFrameDecorator:
         if len(self.queue) == 0:
             raise StopIteration
 
-        emission = self.find_signal_emission ()
+        emission = self.find_signal_emission()
         if emission > 0:
             start = emission
             while True:
                 if start == 0:
                     break
-                prev_name = frame_name(self.queue[start-1])
+                prev_name = frame_name(self.queue[start - 1])
                 if prev_name.find("_marshal_") >= 0 or prev_name == "g_closure_invoke":
                     start = start - 1
                 else:
                     break
             end = emission + 1
             while end < len(self.queue):
-                if frame_name(self.queue[end]) in ["g_signal_emitv",
-                                                   "g_signal_emit_valist",
-                                                   "g_signal_emit",
-                                                   "g_signal_emit_by_name",
-                                                   "_g_closure_invoke_va"]:
+                if frame_name(self.queue[end]) in [
+                    "g_signal_emitv",
+                    "g_signal_emit_valist",
+                    "g_signal_emit",
+                    "g_signal_emit_by_name",
+                    "_g_closure_invoke_va",
+                ]:
                     end = end + 1
                 else:
                     break
@@ -311,18 +329,20 @@ class GFrameDecorator:
 
         return self.queue.pop(0)
 
-    def __next__ (self):
+    def __next__(self):
         return self.next()
 
+
 class GFrameFilter(object):
-    name = 'glib'
+    name = "glib"
     enabled = True
     priority = 100
 
     def filter(self, iterator):
         return GFrameDecorator(iterator)
 
-def register (obj):
+
+def register(obj):
     if obj is None:
         obj = gdb
 
index 0d0d2e8..d1b1ee4 100644 (file)
@@ -32,7 +32,7 @@ G_DEFINE_BOXED_TYPE (GIOChannel, g_io_channel, g_io_channel_ref, g_io_channel_un
 GType
 g_io_condition_get_type (void)
 {
-  static volatile GType etype = 0;
+  static GType etype = 0;
 
   if (g_once_init_enter (&etype))
     {
index 723675d..f83c1ca 100644 (file)
@@ -221,9 +221,9 @@ typedef enum
 /* --- structures --- */
 struct _TypeNode
 {
-  guint volatile ref_count;
+  guint        ref_count;  /* (atomic) */
 #ifdef G_ENABLE_DEBUG
-  guint volatile instance_count;
+  guint        instance_count;  /* (atomic) */
 #endif
   GTypePlugin *plugin;
   guint        n_children; /* writable with lock */
@@ -233,7 +233,7 @@ struct _TypeNode
   guint        is_instantiatable : 1;
   guint        mutatable_check_cache : 1;      /* combines some common path checks */
   GType       *children; /* writable with lock */
-  TypeData * volatile data;
+  TypeData    *data;
   GQuark       qname;
   GData       *global_gdata;
   union {
@@ -322,7 +322,7 @@ struct _ClassData
   CommonData         common;
   guint16            class_size;
   guint16            class_private_size;
-  int volatile       init_state; /* atomic - g_type_class_ref reads it unlocked */
+  int                init_state;  /* (atomic) - g_type_class_ref reads it unlocked */
   GBaseInitFunc      class_init_base;
   GBaseFinalizeFunc  class_finalize_base;
   GClassInitFunc     class_init;
@@ -336,7 +336,7 @@ struct _InstanceData
   CommonData         common;
   guint16            class_size;
   guint16            class_private_size;
-  int volatile       init_state; /* atomic - g_type_class_ref reads it unlocked */
+  int                init_state;  /* (atomic) - g_type_class_ref reads it unlocked */
   GBaseInitFunc      class_init_base;
   GBaseFinalizeFunc  class_finalize_base;
   GClassInitFunc     class_init;
@@ -442,6 +442,10 @@ type_node_any_new_W (TypeNode             *pnode,
       node = G_STRUCT_MEMBER_P (node, SIZEOF_FUNDAMENTAL_INFO);
       static_fundamental_type_nodes[ftype >> G_TYPE_FUNDAMENTAL_SHIFT] = node;
       type = ftype;
+
+#if ENABLE_VALGRIND
+      VALGRIND_MALLOCLIKE_BLOCK (node, node_size - SIZEOF_FUNDAMENTAL_INFO, FALSE, TRUE);
+#endif
     }
   else
     type = (GType) node;
@@ -569,13 +573,13 @@ type_node_new_W (TypeNode    *pnode,
 }
 
 static inline IFaceEntry*
-lookup_iface_entry_I (volatile IFaceEntries *entries,
-                     TypeNode *iface_node)
+lookup_iface_entry_I (IFaceEntries *entries,
+                      TypeNode     *iface_node)
 {
   guint8 *offsets;
   guint offset_index;
   IFaceEntry *check;
-  int index;
+  gsize index;
   IFaceEntry *entry;
 
   if (entries == NULL)
@@ -1365,7 +1369,7 @@ type_node_add_iface_entry_W (TypeNode   *node,
   IFaceEntry *entry;
   TypeNode *iface_node;
   guint i, j;
-  int num_entries;
+  guint num_entries;
 
   g_assert (node->is_instantiatable);
 
@@ -1415,7 +1419,7 @@ type_node_add_iface_entry_W (TypeNode   *node,
 
   if (parent_entry)
     {
-      if (node->data && node->data->class.init_state >= BASE_IFACE_INIT)
+      if (node->data && g_atomic_int_get (&node->data->class.init_state) >= BASE_IFACE_INIT)
         {
           entries->entry[i].init_state = INITIALIZED;
           entries->entry[i].vtable = parent_entry->vtable;
@@ -1481,7 +1485,7 @@ type_add_interface_Wm (TypeNode             *node,
    */
   if (node->data)
     {
-      InitState class_state = node->data->class.init_state;
+      InitState class_state = g_atomic_int_get (&node->data->class.init_state);
       
       if (class_state >= BASE_IFACE_INIT)
         type_iface_vtable_base_init_Wm (iface, node);
@@ -1604,7 +1608,7 @@ g_type_interface_add_prerequisite (GType interface_type,
            }
        }
       
-      for (i = 0; i < prerequisite_node->n_supers + 1; i++)
+      for (i = 0; i < prerequisite_node->n_supers + 1u; i++)
        type_iface_add_prerequisite_W (iface, lookup_type_node_I (prerequisite_node->supers[i]));
       G_WRITE_UNLOCK (&type_rw_lock);
     }
@@ -1689,6 +1693,54 @@ g_type_interface_prerequisites (GType  interface_type,
     }
 }
 
+/**
+ * g_type_interface_instantiatable_prerequisite:
+ * @interface_type: an interface type
+ *
+ * Returns the most specific instantiatable prerequisite of an
+ * interface type. If the interface type has no instantiatable
+ * prerequisite, %G_TYPE_INVALID is returned.
+ *
+ * See g_type_interface_add_prerequisite() for more information
+ * about prerequisites.
+ *
+ * Returns: the instantiatable prerequisite type or %G_TYPE_INVALID if none
+ *
+ * Since: 2.68
+ **/
+GType
+g_type_interface_instantiatable_prerequisite (GType interface_type)
+{
+  TypeNode *inode = NULL;
+  TypeNode *iface;
+  guint i;
+
+  g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface_type), G_TYPE_INVALID);
+
+  iface = lookup_type_node_I (interface_type);
+  if (iface == NULL)
+    return G_TYPE_INVALID;
+
+  G_READ_LOCK (&type_rw_lock);
+
+  for (i = 0; i < IFACE_NODE_N_PREREQUISITES (iface); i++)
+    {
+      GType prerequisite = IFACE_NODE_PREREQUISITES (iface)[i];
+      TypeNode *node = lookup_type_node_I (prerequisite);
+      if (node->is_instantiatable)
+        {
+          if (!inode || type_node_is_a_L (node, inode))
+            inode = node;
+        }
+    }
+
+  G_READ_UNLOCK (&type_rw_lock);
+
+  if (inode)
+    return NODE_TYPE (inode);
+  else
+    return G_TYPE_INVALID;
+}
 
 static IFaceHolder*
 type_iface_peek_holder_L (TypeNode *iface,
@@ -2121,13 +2173,13 @@ type_class_init_Wm (TypeNode   *node,
   TypeNode *bnode, *pnode;
   guint i;
   
-  /* Accessing data->class will work for instantiable types
+  /* Accessing data->class will work for instantiatable types
    * too because ClassData is a subset of InstanceData
    */
   g_assert (node->is_classed && node->data &&
            node->data->class.class_size &&
            !node->data->class.class &&
-           node->data->class.init_state == UNINITIALIZED);
+           g_atomic_int_get (&node->data->class.init_state) == UNINITIALIZED);
   if (node->data->class.class_private_size)
     class = g_malloc0 (ALIGN_STRUCT (node->data->class.class_size) + node->data->class.class_private_size);
   else
@@ -2242,7 +2294,7 @@ type_class_init_Wm (TypeNode   *node,
    * inherited interfaces are already init_state == INITIALIZED, because
    * they either got setup in the above base_init loop, or during
    * class_init from within type_add_interface_Wm() for this or
-   * an anchestor type.
+   * an ancestor type.
    */
   i = 0;
   while ((entries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (node)) != NULL)
@@ -2820,12 +2872,12 @@ g_type_register_dynamic (GType        parent_type,
 
 /**
  * g_type_add_interface_static:
- * @instance_type: #GType value of an instantiable type
+ * @instance_type: #GType value of an instantiatable type
  * @interface_type: #GType value of an interface type
  * @info: #GInterfaceInfo structure for this
  *        (@instance_type, @interface_type) combination
  *
- * Adds @interface_type to the static @instantiable_type.
+ * Adds @interface_type to the static @instance_type.
  * The information contained in the #GInterfaceInfo structure
  * pointed to by @info is used to manage the relationship.
  */
@@ -2857,11 +2909,11 @@ g_type_add_interface_static (GType                 instance_type,
 
 /**
  * g_type_add_interface_dynamic:
- * @instance_type: #GType value of an instantiable type
+ * @instance_type: #GType value of an instantiatable type
  * @interface_type: #GType value of an interface type
  * @plugin: #GTypePlugin structure to retrieve the #GInterfaceInfo from
  *
- * Adds @interface_type to the dynamic @instantiable_type. The information
+ * Adds @interface_type to the dynamic @instance_type. The information
  * contained in the #GTypePlugin structure pointed to by @plugin
  * is used to manage the relationship.
  */
@@ -3407,14 +3459,14 @@ g_type_depth (GType type)
  * @root_type: immediate parent of the returned type
  *
  * Given a @leaf_type and a @root_type which is contained in its
- * anchestry, return the type that @root_type is the immediate parent
+ * ancestry, return the type that @root_type is the immediate parent
  * of. In other words, this function determines the type that is
  * derived directly from @root_type which is also a base class of
  * @leaf_type.  Given a root type and a leaf type, this function can
  * be used to determine the types and order in which the leaf type is
  * descended from the root type.
  *
- * Returns: immediate child of @root_type and anchestor of @leaf_type
+ * Returns: immediate child of @root_type and ancestor of @leaf_type
  */
 GType
 g_type_next_base (GType type,
@@ -3501,8 +3553,8 @@ type_node_conforms_to_U (TypeNode *node,
 
 /**
  * g_type_is_a:
- * @type: type to check anchestry for
- * @is_a_type: possible anchestor of @type or interface that @type
+ * @type: type to check ancestry for
+ * @is_a_type: possible ancestor of @type or interface that @type
  *     could conform to
  *
  * If @is_a_type is a derivable type, check whether @type is a
index 8917841..666fadb 100644 (file)
@@ -981,7 +981,7 @@ typedef void     (*GTypeInterfaceCheckFunc)  (gpointer             check_data,
 /**
  * GTypeFundamentalFlags:
  * @G_TYPE_FLAG_CLASSED: Indicates a classed type
- * @G_TYPE_FLAG_INSTANTIATABLE: Indicates an instantiable type (implies classed)
+ * @G_TYPE_FLAG_INSTANTIATABLE: Indicates an instantiatable type (implies classed)
  * @G_TYPE_FLAG_DERIVABLE: Indicates a flat derivable type
  * @G_TYPE_FLAG_DEEP_DERIVABLE: Indicates a deep derivable type (implies derivable)
  * 
@@ -1300,6 +1300,9 @@ void  g_type_interface_add_prerequisite (GType                         interface_type,
 GLIB_AVAILABLE_IN_ALL
 GType*g_type_interface_prerequisites    (GType                       interface_type,
                                         guint                      *n_prerequisites);
+GLIB_AVAILABLE_IN_2_68
+GType g_type_interface_instantiatable_prerequisite
+                                        (GType                       interface_type);
 GLIB_DEPRECATED_IN_2_58
 void     g_type_class_add_private       (gpointer                    g_class,
                                          gsize                       private_size);
@@ -1724,8 +1727,8 @@ guint     g_type_get_type_registration_serial (void);
  * GType
  * gtk_gadget_get_type (void)
  * {
- *   static volatile gsize g_define_type_id__volatile = 0;
- *   if (g_once_init_enter (&g_define_type_id__volatile))
+ *   static gsize static_g_define_type_id = 0;
+ *   if (g_once_init_enter (&static_g_define_type_id))
  *     {
  *       GType g_define_type_id =
  *         g_type_register_static_simple (GTK_TYPE_WIDGET,
@@ -1745,9 +1748,9 @@ guint     g_type_get_type_registration_serial (void);
  *         };
  *         g_type_add_interface_static (g_define_type_id, TYPE_GIZMO, &g_implement_interface_info);
  *       }
- *       g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
+ *       g_once_init_leave (&static_g_define_type_id, g_define_type_id);
  *     }
- *   return g_define_type_id__volatile;
+ *   return static_g_define_type_id;
  * }
  * ]|
  * The only pieces which have to be manually provided are the definitions of
@@ -1992,17 +1995,17 @@ type_name##_get_instance_private (TypeName *self) \
 GType \
 type_name##_get_type (void) \
 { \
-  static volatile gsize g_define_type_id__volatile = 0;
+  static gsize static_g_define_type_id = 0;
   /* Prelude goes here */
 
 /* Added for _G_DEFINE_TYPE_EXTENDED_WITH_PRELUDE */
 #define _G_DEFINE_TYPE_EXTENDED_BEGIN_REGISTER(TypeName, type_name, TYPE_PARENT, flags) \
-  if (g_once_init_enter (&g_define_type_id__volatile))  \
+  if (g_once_init_enter (&static_g_define_type_id)) \
     { \
       GType g_define_type_id = type_name##_get_type_once (); \
-      g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); \
+      g_once_init_leave (&static_g_define_type_id, g_define_type_id); \
     }                                  \
-  return g_define_type_id__volatile;   \
+  return static_g_define_type_id; \
 } /* closes type_name##_get_type() */ \
 \
 G_GNUC_NO_INLINE \
@@ -2038,8 +2041,8 @@ static void     type_name##_default_init        (TypeName##Interface *klass); \
 GType \
 type_name##_get_type (void) \
 { \
-  static volatile gsize g_define_type_id__volatile = 0; \
-  if (g_once_init_enter (&g_define_type_id__volatile))  \
+  static gsize static_g_define_type_id = 0; \
+  if (g_once_init_enter (&static_g_define_type_id)) \
     { \
       GType g_define_type_id = \
         g_type_register_static_simple (G_TYPE_INTERFACE, \
@@ -2055,9 +2058,9 @@ type_name##_get_type (void) \
 #define _G_DEFINE_INTERFACE_EXTENDED_END()     \
         /* following custom code */            \
       }                                                \
-      g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); \
+      g_once_init_leave (&static_g_define_type_id, g_define_type_id); \
     }                                          \
-  return g_define_type_id__volatile;                   \
+  return static_g_define_type_id; \
 } /* closes type_name##_get_type() */
 
 /**
@@ -2112,13 +2115,13 @@ static GType type_name##_get_type_once (void); \
 GType \
 type_name##_get_type (void) \
 { \
-  static volatile gsize g_define_type_id__volatile = 0; \
-  if (g_once_init_enter (&g_define_type_id__volatile))  \
+  static gsize static_g_define_type_id = 0; \
+  if (g_once_init_enter (&static_g_define_type_id)) \
     { \
       GType g_define_type_id = type_name##_get_type_once (); \
-      g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); \
+      g_once_init_leave (&static_g_define_type_id, g_define_type_id); \
     } \
-  return g_define_type_id__volatile; \
+  return static_g_define_type_id; \
 } \
 \
 G_GNUC_NO_INLINE \
@@ -2149,13 +2152,13 @@ static GType type_name##_get_type_once (void); \
 GType \
 type_name##_get_type (void) \
 { \
-  static volatile gsize g_define_type_id__volatile = 0; \
-  if (g_once_init_enter (&g_define_type_id__volatile))  \
+  static gsize static_g_define_type_id = 0; \
+  if (g_once_init_enter (&static_g_define_type_id)) \
     { \
       GType g_define_type_id = type_name##_get_type_once (); \
-      g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); \
+      g_once_init_leave (&static_g_define_type_id, g_define_type_id); \
     } \
-  return g_define_type_id__volatile; \
+  return static_g_define_type_id; \
 } \
 \
 G_GNUC_NO_INLINE \
@@ -2202,13 +2205,13 @@ static GType type_name##_get_type_once (void); \
 GType \
 type_name##_get_type (void) \
 { \
-  static volatile gsize g_define_type_id__volatile = 0; \
-  if (g_once_init_enter (&g_define_type_id__volatile))  \
+  static gsize static_g_define_type_id = 0; \
+  if (g_once_init_enter (&static_g_define_type_id)) \
     { \
       GType g_define_type_id = type_name##_get_type_once (); \
-      g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); \
+      g_once_init_leave (&static_g_define_type_id, g_define_type_id); \
     } \
-  return g_define_type_id__volatile; \
+  return static_g_define_type_id; \
 } \
 \
 G_GNUC_NO_INLINE \
index 9068b05..d5007f1 100644 (file)
@@ -167,7 +167,7 @@ g_type_plugin_complete_type_info (GTypePlugin     *plugin,
 /**
  * g_type_plugin_complete_interface_info:
  * @plugin: the #GTypePlugin
- * @instance_type: the #GType of an instantiable type to which the interface
+ * @instance_type: the #GType of an instantiatable type to which the interface
  *  is added
  * @interface_type: the #GType of the interface whose info is completed
  * @info: the #GInterfaceInfo to fill in
index 482f55c..de114fe 100644 (file)
@@ -67,7 +67,7 @@ typedef void  (*GTypePluginCompleteTypeInfo)    (GTypePlugin     *plugin,
 /**
  * GTypePluginCompleteInterfaceInfo:
  * @plugin: the #GTypePlugin
- * @instance_type: the #GType of an instantiable type to which the interface
+ * @instance_type: the #GType of an instantiatable type to which the interface
  *  is added
  * @interface_type: the #GType of the interface whose info is completed
  * @info: the #GInterfaceInfo to fill in
index 468da2e..9c6c90d 100644 (file)
@@ -448,6 +448,15 @@ g_value_init_from_instance (GValue  *value,
     }
 }
 
+static GType
+transform_lookup_get_parent_type (GType type)
+{
+  if (g_type_fundamental (type) == G_TYPE_INTERFACE)
+    return g_type_interface_instantiatable_prerequisite (type);
+
+  return g_type_parent (type);
+}
+
 static GValueTransform
 transform_func_lookup (GType src_type,
                       GType dest_type)
@@ -470,11 +479,11 @@ transform_func_lookup (GType src_type,
                  g_type_value_table_peek (entry.src_type) == g_type_value_table_peek (src_type))
                return e->func;
            }
-         entry.dest_type = g_type_parent (entry.dest_type);
+         entry.dest_type = transform_lookup_get_parent_type (entry.dest_type);
        }
       while (entry.dest_type);
       
-      entry.src_type = g_type_parent (entry.src_type);
+      entry.src_type = transform_lookup_get_parent_type (entry.src_type);
     }
   while (entry.src_type);
 
index 1d3ead4..61002f4 100644 (file)
@@ -2,6 +2,47 @@
 #include <gstdio.h>
 #include <glib-object.h>
 
+typedef struct {
+  GTypeInterface g_iface;
+} FooInterface;
+
+GType foo_get_type (void);
+
+G_DEFINE_INTERFACE (Foo, foo, G_TYPE_OBJECT)
+
+static void
+foo_default_init (FooInterface *iface)
+{
+}
+
+typedef struct {
+  GObject parent;
+} Baa;
+
+typedef struct {
+  GObjectClass parent_class;
+} BaaClass;
+
+static void
+baa_init_foo (FooInterface *iface)
+{
+}
+
+GType baa_get_type (void);
+
+G_DEFINE_TYPE_WITH_CODE (Baa, baa, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (foo_get_type (), baa_init_foo))
+
+static void
+baa_init (Baa *baa)
+{
+}
+
+static void
+baa_class_init (BaaClass *class)
+{
+}
+
 typedef struct _BindingSource
 {
   GObject parent_instance;
@@ -10,6 +51,7 @@ typedef struct _BindingSource
   gint bar;
   gdouble double_value;
   gboolean toggle;
+  gpointer item;
 } BindingSource;
 
 typedef struct _BindingSourceClass
@@ -24,7 +66,8 @@ enum
   PROP_SOURCE_FOO,
   PROP_SOURCE_BAR,
   PROP_SOURCE_DOUBLE_VALUE,
-  PROP_SOURCE_TOGGLE
+  PROP_SOURCE_TOGGLE,
+  PROP_SOURCE_OBJECT
 };
 
 static GType binding_source_get_type (void);
@@ -56,6 +99,10 @@ binding_source_set_property (GObject      *gobject,
       source->toggle = g_value_get_boolean (value);
       break;
 
+    case PROP_SOURCE_OBJECT:
+      source->item = g_value_get_object (value);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
     }
@@ -87,6 +134,10 @@ binding_source_get_property (GObject    *gobject,
       g_value_set_boolean (value, source->toggle);
       break;
 
+    case PROP_SOURCE_OBJECT:
+      g_value_set_object (value, source->item);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
     }
@@ -119,6 +170,10 @@ binding_source_class_init (BindingSourceClass *klass)
                                    g_param_spec_boolean ("toggle", "Toggle", "Toggle",
                                                          FALSE,
                                                          G_PARAM_READWRITE));
+  g_object_class_install_property (gobject_class, PROP_SOURCE_OBJECT,
+                                   g_param_spec_object ("object", "Object", "Object",
+                                                        G_TYPE_OBJECT,
+                                                        G_PARAM_READWRITE));
 }
 
 static void
@@ -133,6 +188,7 @@ typedef struct _BindingTarget
   gint bar;
   gdouble double_value;
   gboolean toggle;
+  gpointer foo;
 } BindingTarget;
 
 typedef struct _BindingTargetClass
@@ -146,7 +202,8 @@ enum
 
   PROP_TARGET_BAR,
   PROP_TARGET_DOUBLE_VALUE,
-  PROP_TARGET_TOGGLE
+  PROP_TARGET_TOGGLE,
+  PROP_TARGET_FOO
 };
 
 static GType binding_target_get_type (void);
@@ -174,6 +231,10 @@ binding_target_set_property (GObject      *gobject,
       target->toggle = g_value_get_boolean (value);
       break;
 
+    case PROP_TARGET_FOO:
+      target->foo = g_value_get_object (value);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
     }
@@ -201,6 +262,10 @@ binding_target_get_property (GObject    *gobject,
       g_value_set_boolean (value, target->toggle);
       break;
 
+    case PROP_TARGET_FOO:
+      g_value_set_object (value, target->foo);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
     }
@@ -228,6 +293,10 @@ binding_target_class_init (BindingTargetClass *klass)
                                    g_param_spec_boolean ("toggle", "Toggle", "Toggle",
                                                          FALSE,
                                                          G_PARAM_READWRITE));
+  g_object_class_install_property (gobject_class, PROP_TARGET_FOO,
+                                   g_param_spec_object ("foo", "Foo", "Foo",
+                                                        foo_get_type (),
+                                                        G_PARAM_READWRITE));
 }
 
 static void
@@ -284,6 +353,7 @@ binding_default (void)
 {
   BindingSource *source = g_object_new (binding_source_get_type (), NULL);
   BindingTarget *target = g_object_new (binding_target_get_type (), NULL);
+  GObject *tmp;
   GBinding *binding;
 
   binding = g_object_bind_property (source, "foo",
@@ -291,8 +361,14 @@ binding_default (void)
                                     G_BINDING_DEFAULT);
 
   g_object_add_weak_pointer (G_OBJECT (binding), (gpointer *) &binding);
-  g_assert_true ((BindingSource *) g_binding_get_source (binding) == source);
-  g_assert_true ((BindingTarget *) g_binding_get_target (binding) == target);
+  tmp = g_binding_dup_source (binding);
+  g_assert_nonnull (tmp);
+  g_assert_true ((BindingSource *) tmp == source);
+  g_object_unref (tmp);
+  tmp = g_binding_dup_target (binding);
+  g_assert_nonnull (tmp);
+  g_assert_true ((BindingTarget *) tmp == target);
+  g_object_unref (tmp);
   g_assert_cmpstr (g_binding_get_source_property (binding), ==, "foo");
   g_assert_cmpstr (g_binding_get_target_property (binding), ==, "bar");
   g_assert_cmpint (g_binding_get_flags (binding), ==, G_BINDING_DEFAULT);
@@ -319,6 +395,7 @@ binding_canonicalisation (void)
   BindingSource *source = g_object_new (binding_source_get_type (), NULL);
   BindingTarget *target = g_object_new (binding_target_get_type (), NULL);
   GBinding *binding;
+  GObject *tmp;
 
   g_test_summary ("Test that bindings set up with non-canonical property names work");
 
@@ -327,8 +404,14 @@ binding_canonicalisation (void)
                                     G_BINDING_DEFAULT);
 
   g_object_add_weak_pointer (G_OBJECT (binding), (gpointer *) &binding);
-  g_assert_true ((BindingSource *) g_binding_get_source (binding) == source);
-  g_assert_true ((BindingTarget *) g_binding_get_target (binding) == target);
+  tmp = g_binding_dup_source (binding);
+  g_assert_nonnull (tmp);
+  g_assert_true ((BindingSource *) tmp == source);
+  g_object_unref (tmp);
+  tmp = g_binding_dup_target (binding);
+  g_assert_nonnull (tmp);
+  g_assert_true ((BindingTarget *) tmp == target);
+  g_object_unref (tmp);
   g_assert_cmpstr (g_binding_get_source_property (binding), ==, "double-value");
   g_assert_cmpstr (g_binding_get_target_property (binding), ==, "double-value");
   g_assert_cmpint (g_binding_get_flags (binding), ==, G_BINDING_DEFAULT);
@@ -757,6 +840,242 @@ binding_fail (void)
   g_assert_null (binding);
 }
 
+static gboolean
+transform_to_func (GBinding     *binding,
+                   const GValue *value_a,
+                   GValue       *value_b,
+                   gpointer      user_data)
+{
+  if (g_value_type_compatible (G_VALUE_TYPE (value_a), G_VALUE_TYPE (value_b)))
+    {
+      g_value_copy (value_a, value_b);
+      return TRUE;
+    }
+
+  if (g_value_type_transformable (G_VALUE_TYPE (value_a), G_VALUE_TYPE (value_b)))
+    {
+      if (g_value_transform (value_a, value_b))
+        return TRUE;
+    }
+
+  return FALSE;
+}
+
+static void
+binding_interface (void)
+{
+  BindingSource *source = g_object_new (binding_source_get_type (), NULL);
+  BindingTarget *target = g_object_new (binding_target_get_type (), NULL);
+  GObject *baa;
+  GBinding *binding;
+  GClosure *transform_to;
+
+  /* binding a generic object property to an interface-valued one */
+  binding = g_object_bind_property (source, "object",
+                                    target, "foo",
+                                    G_BINDING_DEFAULT);
+
+  baa = g_object_new (baa_get_type (), NULL);
+  g_object_set (source, "object", baa, NULL);
+  g_object_unref (baa);
+
+  g_binding_unbind (binding);
+
+  /* the same, with a generic marshaller */
+  transform_to = g_cclosure_new (G_CALLBACK (transform_to_func), NULL, NULL);
+  g_closure_set_marshal (transform_to, g_cclosure_marshal_generic);
+  binding = g_object_bind_property_with_closures (source, "object",
+                                                  target, "foo",
+                                                  G_BINDING_DEFAULT,
+                                                  transform_to,
+                                                  NULL);
+
+  baa = g_object_new (baa_get_type (), NULL);
+  g_object_set (source, "object", baa, NULL);
+  g_object_unref (baa);
+
+  g_binding_unbind (binding);
+
+  g_object_unref (source);
+  g_object_unref (target);
+}
+
+typedef struct {
+  GThread *thread;
+  GBinding *binding;
+  GMutex *lock;
+  GCond *cond;
+  gboolean *wait;
+  gint *count; /* (atomic) */
+} ConcurrentUnbindData;
+
+static gpointer
+concurrent_unbind_func (gpointer data)
+{
+  ConcurrentUnbindData *unbind_data = data;
+
+  g_mutex_lock (unbind_data->lock);
+  g_atomic_int_inc (unbind_data->count);
+  while (*unbind_data->wait)
+    g_cond_wait (unbind_data->cond, unbind_data->lock);
+  g_mutex_unlock (unbind_data->lock);
+  g_binding_unbind (unbind_data->binding);
+  g_object_unref (unbind_data->binding);
+
+  return NULL;
+}
+
+static void
+binding_concurrent_unbind (void)
+{
+  guint i, j;
+
+  g_test_summary ("Test that unbinding from multiple threads concurrently works correctly");
+
+  for (i = 0; i < 50; i++)
+    {
+      BindingSource *source = g_object_new (binding_source_get_type (), NULL);
+      BindingTarget *target = g_object_new (binding_target_get_type (), NULL);
+      GBinding *binding;
+      GQueue threads = G_QUEUE_INIT;
+      GMutex lock;
+      GCond cond;
+      gboolean wait = TRUE;
+      gint count = 0; /* (atomic) */
+      ConcurrentUnbindData *data;
+
+      g_mutex_init (&lock);
+      g_cond_init (&cond);
+
+      binding = g_object_bind_property (source, "foo",
+                                        target, "bar",
+                                        G_BINDING_BIDIRECTIONAL);
+      g_object_ref (binding);
+
+      for (j = 0; j < 10; j++)
+        {
+          data = g_new0 (ConcurrentUnbindData, 1);
+
+          data->binding = g_object_ref (binding);
+          data->lock = &lock;
+          data->cond = &cond;
+          data->wait = &wait;
+          data->count = &count;
+
+          data->thread = g_thread_new ("binding-concurrent", concurrent_unbind_func, data);
+          g_queue_push_tail (&threads, data);
+        }
+
+      /* wait until all threads are started */
+      while (g_atomic_int_get (&count) < 10)
+        g_thread_yield ();
+
+      g_mutex_lock (&lock);
+      wait = FALSE;
+      g_cond_broadcast (&cond);
+      g_mutex_unlock (&lock);
+
+      while ((data = g_queue_pop_head (&threads)))
+        {
+          g_thread_join (data->thread);
+          g_free (data);
+        }
+
+      g_mutex_clear (&lock);
+      g_cond_clear (&cond);
+
+      g_object_unref (binding);
+      g_object_unref (source);
+      g_object_unref (target);
+    }
+}
+
+typedef struct {
+  GObject *object;
+  GMutex *lock;
+  GCond *cond;
+  gint *count; /* (atomic) */
+  gboolean *wait;
+} ConcurrentFinalizeData;
+
+static gpointer
+concurrent_finalize_func (gpointer data)
+{
+  ConcurrentFinalizeData *finalize_data = data;
+
+  g_mutex_lock (finalize_data->lock);
+  g_atomic_int_inc (finalize_data->count);
+  while (*finalize_data->wait)
+    g_cond_wait (finalize_data->cond, finalize_data->lock);
+  g_mutex_unlock (finalize_data->lock);
+  g_object_unref (finalize_data->object);
+  g_free (finalize_data);
+
+  return NULL;
+}
+
+static void
+binding_concurrent_finalizing (void)
+{
+  guint i;
+
+  g_test_summary ("Test that finalizing source/target from multiple threads concurrently works correctly");
+
+  for (i = 0; i < 50; i++)
+    {
+      BindingSource *source = g_object_new (binding_source_get_type (), NULL);
+      BindingTarget *target = g_object_new (binding_target_get_type (), NULL);
+      GBinding *binding;
+      GMutex lock;
+      GCond cond;
+      gboolean wait = TRUE;
+      ConcurrentFinalizeData *data;
+      GThread *source_thread, *target_thread;
+      gint count = 0; /* (atomic) */
+
+      g_mutex_init (&lock);
+      g_cond_init (&cond);
+
+      binding = g_object_bind_property (source, "foo",
+                                        target, "bar",
+                                        G_BINDING_BIDIRECTIONAL);
+      g_object_ref (binding);
+
+      data = g_new0 (ConcurrentFinalizeData, 1);
+      data->object = (GObject *) source;
+      data->wait = &wait;
+      data->lock = &lock;
+      data->cond = &cond;
+      data->count = &count;
+      source_thread = g_thread_new ("binding-concurrent", concurrent_finalize_func, data);
+
+      data = g_new0 (ConcurrentFinalizeData, 1);
+      data->object = (GObject *) target;
+      data->wait = &wait;
+      data->lock = &lock;
+      data->cond = &cond;
+      data->count = &count;
+      target_thread = g_thread_new ("binding-concurrent", concurrent_finalize_func, data);
+
+      /* wait until all threads are started */
+      while (g_atomic_int_get (&count) < 2)
+        g_thread_yield ();
+
+      g_mutex_lock (&lock);
+      wait = FALSE;
+      g_cond_broadcast (&cond);
+      g_mutex_unlock (&lock);
+
+      g_thread_join (source_thread);
+      g_thread_join (target_thread);
+
+      g_mutex_clear (&lock);
+      g_cond_clear (&cond);
+
+      g_object_unref (binding);
+    }
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -778,6 +1097,9 @@ main (int argc, char *argv[])
   g_test_add_func ("/binding/unbind-weak", binding_unbind_weak);
   g_test_add_func ("/binding/unbind-multiple", binding_unbind_multiple);
   g_test_add_func ("/binding/fail", binding_fail);
+  g_test_add_func ("/binding/interface", binding_interface);
+  g_test_add_func ("/binding/concurrent-unbind", binding_concurrent_unbind);
+  g_test_add_func ("/binding/concurrent-finalizing", binding_concurrent_finalizing);
 
   return g_test_run ();
 }
index 46d9063..5323cfb 100644 (file)
@@ -32,7 +32,11 @@ import unittest
 import taptestrunner
 
 
-Result = collections.namedtuple('Result', ('info', 'out', 'err', 'subs'))
+# Disable line length warnings as wrapping the C code templates would be hard
+# flake8: noqa: E501
+
+
+Result = collections.namedtuple("Result", ("info", "out", "err", "subs"))
 
 
 class TestGenmarshal(unittest.TestCase):
@@ -47,22 +51,23 @@ class TestGenmarshal(unittest.TestCase):
     parsing and generation code out into a library and unit test that, and
     convert this test to just check command line behaviour.
     """
+
     # Track the cwd, we want to back out to that to clean up our tempdir
-    cwd = ''
+    cwd = ""
 
     def setUp(self):
         self.timeout_seconds = 10  # seconds per test
         self.tmpdir = tempfile.TemporaryDirectory()
         self.cwd = os.getcwd()
         os.chdir(self.tmpdir.name)
-        print('tmpdir:', self.tmpdir.name)
-        if 'G_TEST_BUILDDIR' in os.environ:
-            self.__genmarshal = \
-                os.path.join(os.environ['G_TEST_BUILDDIR'], '..',
-                             'glib-genmarshal')
+        print("tmpdir:", self.tmpdir.name)
+        if "G_TEST_BUILDDIR" in os.environ:
+            self.__genmarshal = os.path.join(
+                os.environ["G_TEST_BUILDDIR"], "..", "glib-genmarshal"
+            )
         else:
-            self.__genmarshal = shutil.which('glib-genmarshal')
-        print('genmarshal:', self.__genmarshal)
+            self.__genmarshal = shutil.which("glib-genmarshal")
+        print("genmarshal:", self.__genmarshal)
 
     def tearDown(self):
         os.chdir(self.cwd)
@@ -73,48 +78,53 @@ class TestGenmarshal(unittest.TestCase):
 
         # shebang lines are not supported on native
         # Windows consoles
-        if os.name == 'nt':
+        if os.name == "nt":
             argv.insert(0, sys.executable)
 
         argv.extend(args)
-        print('Running:', argv)
+        print("Running:", argv)
 
         env = os.environ.copy()
-        env['LC_ALL'] = 'C.UTF-8'
-        print('Environment:', env)
+        env["LC_ALL"] = "C.UTF-8"
+        print("Environment:", env)
 
         # We want to ensure consistent line endings...
-        info = subprocess.run(argv, timeout=self.timeout_seconds,
-                              stdout=subprocess.PIPE,
-                              stderr=subprocess.PIPE,
-                              env=env,
-                              universal_newlines=True)
+        info = subprocess.run(
+            argv,
+            timeout=self.timeout_seconds,
+            stdout=subprocess.PIPE,
+            stderr=subprocess.PIPE,
+            env=env,
+            universal_newlines=True,
+        )
         info.check_returncode()
         out = info.stdout.strip()
         err = info.stderr.strip()
 
         # Known substitutions for standard boilerplate
         subs = {
-            'standard_top_comment':
-                'This file is generated by glib-genmarshal, do not modify '
-                'it. This code is licensed under the same license as the '
-                'containing project. Note that it links to GLib, so must '
-                'comply with the LGPL linking clauses.',
-            'standard_top_pragma': dedent(
-                '''
+            "standard_top_comment": "This file is generated by glib-genmarshal, do not modify "
+            "it. This code is licensed under the same license as the "
+            "containing project. Note that it links to GLib, so must "
+            "comply with the LGPL linking clauses.",
+            "standard_top_pragma": dedent(
+                """
                 #ifndef __G_CCLOSURE_USER_MARSHAL_MARSHAL_H__
                 #define __G_CCLOSURE_USER_MARSHAL_MARSHAL_H__
-                ''').strip(),
-            'standard_bottom_pragma': dedent(
-                '''
+                """
+            ).strip(),
+            "standard_bottom_pragma": dedent(
+                """
                 #endif /* __G_CCLOSURE_USER_MARSHAL_MARSHAL_H__ */
-                ''').strip(),
-            'standard_includes': dedent(
-                '''
+                """
+            ).strip(),
+            "standard_includes": dedent(
+                """
                 #include <glib-object.h>
-                ''').strip(),
-            'standard_marshal_peek_defines': dedent(
-                '''
+                """
+            ).strip(),
+            "standard_marshal_peek_defines": dedent(
+                """
                 #ifdef G_ENABLE_DEBUG
                 #define g_marshal_value_peek_boolean(v)  g_value_get_boolean (v)
                 #define g_marshal_value_peek_char(v)     g_value_get_schar (v)
@@ -160,54 +170,53 @@ class TestGenmarshal(unittest.TestCase):
                 #define g_marshal_value_peek_object(v)   (v)->data[0].v_pointer
                 #define g_marshal_value_peek_variant(v)  (v)->data[0].v_pointer
                 #endif /* !G_ENABLE_DEBUG */
-                ''').strip(),
+                """
+            ).strip(),
         }
 
         result = Result(info, out, err, subs)
 
-        print('Output:', result.out)
+        print("Output:", result.out)
         return result
 
     def runGenmarshalWithList(self, list_contents, *args):
-        with tempfile.NamedTemporaryFile(dir=self.tmpdir.name,
-                                         suffix='.list',
-                                         delete=False) as list_file:
+        with tempfile.NamedTemporaryFile(
+            dir=self.tmpdir.name, suffix=".list", delete=False
+        ) as list_file:
             # Write out the list.
-            list_file.write(list_contents.encode('utf-8'))
-            print(list_file.name + ':', list_contents)
+            list_file.write(list_contents.encode("utf-8"))
+            print(list_file.name + ":", list_contents)
             list_file.flush()
 
-            header_result = self.runGenmarshal(list_file.name,
-                                               '--header', *args)
-            body_result = self.runGenmarshal(list_file.name,
-                                             '--body', *args)
+            header_result = self.runGenmarshal(list_file.name, "--header", *args)
+            body_result = self.runGenmarshal(list_file.name, "--body", *args)
 
-            header_result.subs['list_path'] = list_file.name
-            body_result.subs['list_path'] = list_file.name
+            header_result.subs["list_path"] = list_file.name
+            body_result.subs["list_path"] = list_file.name
 
             return (header_result, body_result)
 
     def test_help(self):
         """Test the --help argument."""
-        result = self.runGenmarshal('--help')
-        self.assertIn('usage: glib-genmarshal', result.out)
+        result = self.runGenmarshal("--help")
+        self.assertIn("usage: glib-genmarshal", result.out)
 
     def test_no_args(self):
         """Test running with no arguments at all."""
         result = self.runGenmarshal()
-        self.assertEqual('', result.err)
-        self.assertEqual('', result.out)
+        self.assertEqual("", result.err)
+        self.assertEqual("", result.out)
 
     def test_empty_list(self):
         """Test running with an empty list."""
-        (header_result, body_result) = \
-            self.runGenmarshalWithList('', '--quiet')
+        (header_result, body_result) = self.runGenmarshalWithList("", "--quiet")
 
-        self.assertEqual('', header_result.err)
-        self.assertEqual('', body_result.err)
+        self.assertEqual("", header_result.err)
+        self.assertEqual("", body_result.err)
 
-        self.assertEqual(dedent(
-            '''
+        self.assertEqual(
+            dedent(
+                """
             /* {standard_top_comment} */
             {standard_top_pragma}
 
@@ -219,28 +228,39 @@ class TestGenmarshal(unittest.TestCase):
             G_END_DECLS
 
             {standard_bottom_pragma}
-            ''').strip().format(**header_result.subs),
-            header_result.out.strip())
-
-        self.assertEqual(dedent(
-            '''
+            """
+            )
+            .strip()
+            .format(**header_result.subs),
+            header_result.out.strip(),
+        )
+
+        self.assertEqual(
+            dedent(
+                """
             /* {standard_top_comment} */
             {standard_includes}
 
             {standard_marshal_peek_defines}
-            ''').strip().format(**body_result.subs),
-            body_result.out.strip())
+            """
+            )
+            .strip()
+            .format(**body_result.subs),
+            body_result.out.strip(),
+        )
 
     def test_void_boolean(self):
         """Test running with a basic VOID:BOOLEAN list."""
-        (header_result, body_result) = \
-            self.runGenmarshalWithList('VOID:BOOLEAN', '--quiet')
+        (header_result, body_result) = self.runGenmarshalWithList(
+            "VOID:BOOLEAN", "--quiet"
+        )
 
-        self.assertEqual('', header_result.err)
-        self.assertEqual('', body_result.err)
+        self.assertEqual("", header_result.err)
+        self.assertEqual("", body_result.err)
 
-        self.assertEqual(dedent(
-            '''
+        self.assertEqual(
+            dedent(
+                """
             /* {standard_top_comment} */
             {standard_top_pragma}
 
@@ -255,28 +275,39 @@ class TestGenmarshal(unittest.TestCase):
             G_END_DECLS
 
             {standard_bottom_pragma}
-            ''').strip().format(**header_result.subs),
-            header_result.out.strip())
-
-        self.assertEqual(dedent(
-            '''
+            """
+            )
+            .strip()
+            .format(**header_result.subs),
+            header_result.out.strip(),
+        )
+
+        self.assertEqual(
+            dedent(
+                """
             /* {standard_top_comment} */
             {standard_includes}
 
             {standard_marshal_peek_defines}
-            ''').strip().format(**body_result.subs),
-            body_result.out.strip())
+            """
+            )
+            .strip()
+            .format(**body_result.subs),
+            body_result.out.strip(),
+        )
 
     def test_void_boolean_int64(self):
         """Test running with a non-trivial VOID:BOOLEAN,INT64 list."""
-        (header_result, body_result) = \
-            self.runGenmarshalWithList('VOID:BOOLEAN,INT64', '--quiet')
+        (header_result, body_result) = self.runGenmarshalWithList(
+            "VOID:BOOLEAN,INT64", "--quiet"
+        )
 
-        self.assertEqual('', header_result.err)
-        self.assertEqual('', body_result.err)
+        self.assertEqual("", header_result.err)
+        self.assertEqual("", body_result.err)
 
-        self.assertEqual(dedent(
-            '''
+        self.assertEqual(
+            dedent(
+                """
             /* {standard_top_comment} */
             {standard_top_pragma}
 
@@ -297,11 +328,16 @@ class TestGenmarshal(unittest.TestCase):
             G_END_DECLS
 
             {standard_bottom_pragma}
-            ''').strip().format(**header_result.subs),
-            header_result.out.strip())
-
-        self.assertEqual(dedent(
-            '''
+            """
+            )
+            .strip()
+            .format(**header_result.subs),
+            header_result.out.strip(),
+        )
+
+        self.assertEqual(
+            dedent(
+                """
             /* {standard_top_comment} */
             {standard_includes}
 
@@ -343,8 +379,12 @@ class TestGenmarshal(unittest.TestCase):
                         g_marshal_value_peek_int64 (param_values + 2),
                         data2);
             }}
-            ''').strip().format(**body_result.subs),
-            body_result.out.strip())
+            """
+            )
+            .strip()
+            .format(**body_result.subs),
+            body_result.out.strip(),
+        )
 
     def test_void_variant_nostdinc_valist_marshaller(self):
         """Test running with a basic VOID:VARIANT list, but without the
@@ -353,15 +393,16 @@ class TestGenmarshal(unittest.TestCase):
 
         See issue #1793.
         """
-        (header_result, body_result) = \
-            self.runGenmarshalWithList('VOID:VARIANT', '--quiet', '--nostdinc',
-                                       '--valist-marshaller')
+        (header_result, body_result) = self.runGenmarshalWithList(
+            "VOID:VARIANT", "--quiet", "--nostdinc", "--valist-marshaller"
+        )
 
-        self.assertEqual('', header_result.err)
-        self.assertEqual('', body_result.err)
+        self.assertEqual("", header_result.err)
+        self.assertEqual("", body_result.err)
 
-        self.assertEqual(dedent(
-            '''
+        self.assertEqual(
+            dedent(
+                """
             /* {standard_top_comment} */
             {standard_top_pragma}
 
@@ -388,11 +429,16 @@ class TestGenmarshal(unittest.TestCase):
             G_END_DECLS
 
             {standard_bottom_pragma}
-            ''').strip().format(**header_result.subs),
-            header_result.out.strip())
-
-        self.assertEqual(dedent(
-            '''
+            """
+            )
+            .strip()
+            .format(**header_result.subs),
+            header_result.out.strip(),
+        )
+
+        self.assertEqual(
+            dedent(
+                """
             /* {standard_top_comment} */
             {standard_marshal_peek_defines}
 
@@ -474,8 +520,12 @@ class TestGenmarshal(unittest.TestCase):
               if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL)
                 g_variant_unref (arg0);
             }}
-            ''').strip().format(**body_result.subs),
-            body_result.out.strip())
+            """
+            )
+            .strip()
+            .format(**body_result.subs),
+            body_result.out.strip(),
+        )
 
     def test_void_string_nostdinc(self):
         """Test running with a basic VOID:STRING list, but without the
@@ -485,15 +535,16 @@ class TestGenmarshal(unittest.TestCase):
 
         See issue #1792.
         """
-        (header_result, body_result) = \
-            self.runGenmarshalWithList('VOID:STRING', '--quiet', '--nostdinc',
-                                       '--valist-marshaller')
+        (header_result, body_result) = self.runGenmarshalWithList(
+            "VOID:STRING", "--quiet", "--nostdinc", "--valist-marshaller"
+        )
 
-        self.assertEqual('', header_result.err)
-        self.assertEqual('', body_result.err)
+        self.assertEqual("", header_result.err)
+        self.assertEqual("", body_result.err)
 
-        self.assertEqual(dedent(
-            '''
+        self.assertEqual(
+            dedent(
+                """
             /* {standard_top_comment} */
             {standard_top_pragma}
 
@@ -520,11 +571,16 @@ class TestGenmarshal(unittest.TestCase):
             G_END_DECLS
 
             {standard_bottom_pragma}
-            ''').strip().format(**header_result.subs),
-            header_result.out.strip())
-
-        self.assertEqual(dedent(
-            '''
+            """
+            )
+            .strip()
+            .format(**header_result.subs),
+            header_result.out.strip(),
+        )
+
+        self.assertEqual(
+            dedent(
+                """
             /* {standard_top_comment} */
             {standard_marshal_peek_defines}
 
@@ -606,8 +662,12 @@ class TestGenmarshal(unittest.TestCase):
               if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL)
                 g_free (arg0);
             }}
-            ''').strip().format(**body_result.subs),
-            body_result.out.strip())
+            """
+            )
+            .strip()
+            .format(**body_result.subs),
+            body_result.out.strip(),
+        )
 
     def test_void_param_nostdinc(self):
         """Test running with a basic VOID:PARAM list, but without the
@@ -618,15 +678,16 @@ class TestGenmarshal(unittest.TestCase):
         See issue #1792.
         """
         self.maxDiff = None  # TODO
-        (header_result, body_result) = \
-            self.runGenmarshalWithList('VOID:PARAM', '--quiet', '--nostdinc',
-                                       '--valist-marshaller')
+        (header_result, body_result) = self.runGenmarshalWithList(
+            "VOID:PARAM", "--quiet", "--nostdinc", "--valist-marshaller"
+        )
 
-        self.assertEqual('', header_result.err)
-        self.assertEqual('', body_result.err)
+        self.assertEqual("", header_result.err)
+        self.assertEqual("", body_result.err)
 
-        self.assertEqual(dedent(
-            '''
+        self.assertEqual(
+            dedent(
+                """
             /* {standard_top_comment} */
             {standard_top_pragma}
 
@@ -653,11 +714,16 @@ class TestGenmarshal(unittest.TestCase):
             G_END_DECLS
 
             {standard_bottom_pragma}
-            ''').strip().format(**header_result.subs),
-            header_result.out.strip())
-
-        self.assertEqual(dedent(
-            '''
+            """
+            )
+            .strip()
+            .format(**header_result.subs),
+            header_result.out.strip(),
+        )
+
+        self.assertEqual(
+            dedent(
+                """
             /* {standard_top_comment} */
             {standard_marshal_peek_defines}
 
@@ -739,9 +805,13 @@ class TestGenmarshal(unittest.TestCase):
               if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL)
                 g_param_spec_unref (arg0);
             }}
-            ''').strip().format(**body_result.subs),
-            body_result.out.strip())
+            """
+            )
+            .strip()
+            .format(**body_result.subs),
+            body_result.out.strip(),
+        )
 
 
-if __name__ == '__main__':
+if __name__ == "__main__":
     unittest.main(testRunner=taptestrunner.TAPTestRunner())
index 22a1005..ae0c683 100644 (file)
@@ -32,7 +32,7 @@ import unittest
 import taptestrunner
 
 
-Result = collections.namedtuple('Result', ('info', 'out', 'err', 'subs'))
+Result = collections.namedtuple("Result", ("info", "out", "err", "subs"))
 
 
 class TestMkenums(unittest.TestCase):
@@ -47,8 +47,9 @@ class TestMkenums(unittest.TestCase):
     parsing and generation code out into a library and unit test that, and
     convert this test to just check command line behaviour.
     """
+
     # Track the cwd, we want to back out to that to clean up our tempdir
-    cwd = ''
+    cwd = ""
     rspfile = False
 
     def setUp(self):
@@ -56,14 +57,14 @@ class TestMkenums(unittest.TestCase):
         self.tmpdir = tempfile.TemporaryDirectory()
         self.cwd = os.getcwd()
         os.chdir(self.tmpdir.name)
-        print('tmpdir:', self.tmpdir.name)
-        if 'G_TEST_BUILDDIR' in os.environ:
-            self.__mkenums = \
-                os.path.join(os.environ['G_TEST_BUILDDIR'], '..',
-                             'glib-mkenums')
+        print("tmpdir:", self.tmpdir.name)
+        if "G_TEST_BUILDDIR" in os.environ:
+            self.__mkenums = os.path.join(
+                os.environ["G_TEST_BUILDDIR"], "..", "glib-mkenums"
+            )
         else:
-            self.__mkenums = shutil.which('glib-mkenums')
-        print('rspfile: {}, mkenums:'.format(self.rspfile), self.__mkenums)
+            self.__mkenums = shutil.which("glib-mkenums")
+        print("rspfile: {}, mkenums:".format(self.rspfile), self.__mkenums)
 
     def tearDown(self):
         os.chdir(self.cwd)
@@ -71,10 +72,12 @@ class TestMkenums(unittest.TestCase):
 
     def _write_rspfile(self, argv):
         import shlex
-        with tempfile.NamedTemporaryFile(dir=self.tmpdir.name, mode='w',
-                                         delete=False) as f:
-            contents = ' '.join([shlex.quote(arg) for arg in argv])
-            print('Response file contains:', contents)
+
+        with tempfile.NamedTemporaryFile(
+            dir=self.tmpdir.name, mode="w", delete=False
+        ) as f:
+            contents = " ".join([shlex.quote(arg) for arg in argv])
+            print("Response file contains:", contents)
             f.write(contents)
             f.flush()
             return f.name
@@ -82,60 +85,62 @@ class TestMkenums(unittest.TestCase):
     def runMkenums(self, *args):
         if self.rspfile:
             rspfile = self._write_rspfile(args)
-            args = ['@' + rspfile]
+            args = ["@" + rspfile]
         argv = [self.__mkenums]
 
         # shebang lines are not supported on native
         # Windows consoles
-        if os.name == 'nt':
+        if os.name == "nt":
             argv.insert(0, sys.executable)
 
         argv.extend(args)
-        print('Running:', argv)
+        print("Running:", argv)
 
         env = os.environ.copy()
-        env['LC_ALL'] = 'C.UTF-8'
-        print('Environment:', env)
+        env["LC_ALL"] = "C.UTF-8"
+        print("Environment:", env)
 
         # We want to ensure consistent line endings...
-        info = subprocess.run(argv, timeout=self.timeout_seconds,
-                              stdout=subprocess.PIPE,
-                              stderr=subprocess.PIPE,
-                              env=env,
-                              universal_newlines=True)
+        info = subprocess.run(
+            argv,
+            timeout=self.timeout_seconds,
+            stdout=subprocess.PIPE,
+            stderr=subprocess.PIPE,
+            env=env,
+            universal_newlines=True,
+        )
         info.check_returncode()
         out = info.stdout.strip()
         err = info.stderr.strip()
 
         # Known substitutions for standard boilerplate
         subs = {
-            'standard_top_comment':
-                'This file is generated by glib-mkenums, do not modify '
-                'it. This code is licensed under the same license as the '
-                'containing project. Note that it links to GLib, so must '
-                'comply with the LGPL linking clauses.',
-            'standard_bottom_comment': 'Generated data ends here'
+            "standard_top_comment": "This file is generated by glib-mkenums, do not modify "
+            "it. This code is licensed under the same license as the "
+            "containing project. Note that it links to GLib, so must "
+            "comply with the LGPL linking clauses.",
+            "standard_bottom_comment": "Generated data ends here",
         }
 
         result = Result(info, out, err, subs)
 
-        print('Output:', result.out)
+        print("Output:", result.out)
         return result
 
     def runMkenumsWithTemplate(self, template_contents, *args):
-        with tempfile.NamedTemporaryFile(dir=self.tmpdir.name,
-                                         suffix='.template',
-                                         delete=False) as template_file:
+        with tempfile.NamedTemporaryFile(
+            dir=self.tmpdir.name, suffix=".template", delete=False
+        ) as template_file:
             # Write out the template.
-            template_file.write(template_contents.encode('utf-8'))
-            print(template_file.name + ':', template_contents)
+            template_file.write(template_contents.encode("utf-8"))
+            print(template_file.name + ":", template_contents)
             template_file.flush()
 
-            return self.runMkenums('--template', template_file.name, *args)
+            return self.runMkenums("--template", template_file.name, *args)
 
     def runMkenumsWithAllSubstitutions(self, *args):
-        '''Run glib-mkenums with a template which outputs all substitutions.'''
-        template_contents = '''
+        """Run glib-mkenums with a template which outputs all substitutions."""
+        template_contents = """
 /*** BEGIN file-header ***/
 file-header
 /*** END file-header ***/
@@ -203,51 +208,66 @@ comment: @comment@
 /*** BEGIN file-tail ***/
 file-tail
 /*** END file-tail ***/
-'''
+"""
         return self.runMkenumsWithTemplate(template_contents, *args)
 
-    def runMkenumsWithHeader(self, h_contents, encoding='utf-8'):
-        with tempfile.NamedTemporaryFile(dir=self.tmpdir.name,
-                                         suffix='.h',
-                                         delete=False) as h_file:
+    def runMkenumsWithHeader(self, h_contents, encoding="utf-8"):
+        with tempfile.NamedTemporaryFile(
+            dir=self.tmpdir.name, suffix=".h", delete=False
+        ) as h_file:
             # Write out the header to be scanned.
             h_file.write(h_contents.encode(encoding))
-            print(h_file.name + ':', h_contents)
+            print(h_file.name + ":", h_contents)
             h_file.flush()
 
             # Run glib-mkenums with a template which outputs all substitutions.
             result = self.runMkenumsWithAllSubstitutions(h_file.name)
 
             # Known substitutions for generated filenames.
-            result.subs.update({
-                'filename': h_file.name,
-                'basename': os.path.basename(h_file.name),
-            })
+            result.subs.update(
+                {"filename": h_file.name, "basename": os.path.basename(h_file.name),}
+            )
 
             return result
 
-    def assertSingleEnum(self, result, enum_name_camel, enum_name_lower,
-                         enum_name_upper, enum_name_short, enum_prefix,
-                         enum_since, type_lower, type_camel, type_upper,
-                         value_name, value_nick, value_num):
+    def assertSingleEnum(
+        self,
+        result,
+        enum_name_camel,
+        enum_name_lower,
+        enum_name_upper,
+        enum_name_short,
+        enum_prefix,
+        enum_since,
+        type_lower,
+        type_camel,
+        type_upper,
+        value_name,
+        value_nick,
+        value_num,
+    ):
         """Assert that out (from runMkenumsWithHeader()) contains a single
            enum and value matching the given arguments."""
-        subs = dict({
-            'enum_name_camel': enum_name_camel,
-            'enum_name_lower': enum_name_lower,
-            'enum_name_upper': enum_name_upper,
-            'enum_name_short': enum_name_short,
-            'enum_prefix': enum_prefix,
-            'enum_since': enum_since,
-            'type_lower': type_lower,
-            'type_camel': type_camel,
-            'type_upper': type_upper,
-            'value_name': value_name,
-            'value_nick': value_nick,
-            'value_num': value_num,
-        }, **result.subs)
-
-        self.assertEqual('''
+        subs = dict(
+            {
+                "enum_name_camel": enum_name_camel,
+                "enum_name_lower": enum_name_lower,
+                "enum_name_upper": enum_name_upper,
+                "enum_name_short": enum_name_short,
+                "enum_prefix": enum_prefix,
+                "enum_since": enum_since,
+                "type_lower": type_lower,
+                "type_camel": type_camel,
+                "type_upper": type_upper,
+                "value_name": value_name,
+                "value_nick": value_nick,
+                "value_num": value_num,
+            },
+            **result.subs
+        )
+
+        self.assertEqual(
+            """
 comment
 comment: {standard_top_comment}
 
@@ -297,38 +317,51 @@ file-tail
 
 comment
 comment: {standard_bottom_comment}
-'''.format(**subs).strip(), result.out)
+""".format(
+                **subs
+            ).strip(),
+            result.out,
+        )
 
     def test_help(self):
         """Test the --help argument."""
-        result = self.runMkenums('--help')
-        self.assertIn('usage: glib-mkenums', result.out)
+        result = self.runMkenums("--help")
+        self.assertIn("usage: glib-mkenums", result.out)
 
     def test_no_args(self):
         """Test running with no arguments at all."""
         result = self.runMkenums()
-        self.assertEqual('', result.err)
-        self.assertEqual('''/* {standard_top_comment} */
+        self.assertEqual("", result.err)
+        self.assertEqual(
+            """/* {standard_top_comment} */
 
 
-/* {standard_bottom_comment} */'''.format(**result.subs),
-                          result.out.strip())
+/* {standard_bottom_comment} */""".format(
+                **result.subs
+            ),
+            result.out.strip(),
+        )
 
     def test_empty_template(self):
         """Test running with an empty template and no header files."""
-        result = self.runMkenumsWithTemplate('')
-        self.assertEqual('', result.err)
-        self.assertEqual('''/* {standard_top_comment} */
+        result = self.runMkenumsWithTemplate("")
+        self.assertEqual("", result.err)
+        self.assertEqual(
+            """/* {standard_top_comment} */
 
 
-/* {standard_bottom_comment} */'''.format(**result.subs),
-                          result.out.strip())
+/* {standard_bottom_comment} */""".format(
+                **result.subs
+            ),
+            result.out.strip(),
+        )
 
     def test_no_headers(self):
         """Test running with a complete template, but no header files."""
         result = self.runMkenumsWithAllSubstitutions()
-        self.assertEqual('', result.err)
-        self.assertEqual('''
+        self.assertEqual("", result.err)
+        self.assertEqual(
+            """
 comment
 comment: {standard_top_comment}
 
@@ -338,13 +371,18 @@ file-tail
 
 comment
 comment: {standard_bottom_comment}
-'''.format(**result.subs).strip(), result.out)
+""".format(
+                **result.subs
+            ).strip(),
+            result.out,
+        )
 
     def test_empty_header(self):
         """Test an empty header."""
-        result = self.runMkenumsWithHeader('')
-        self.assertEqual('', result.err)
-        self.assertEqual('''
+        result = self.runMkenumsWithHeader("")
+        self.assertEqual("", result.err)
+        self.assertEqual(
+            """
 comment
 comment: {standard_top_comment}
 
@@ -354,94 +392,134 @@ file-tail
 
 comment
 comment: {standard_bottom_comment}
-'''.format(**result.subs).strip(), result.out)
+""".format(
+                **result.subs
+            ).strip(),
+            result.out,
+        )
 
     def test_enum_name(self):
         """Test typedefs with an enum and a typedef name. Bug #794506."""
-        h_contents = '''
+        h_contents = """
         typedef enum _SomeEnumIdentifier {
           ENUM_VALUE
         } SomeEnumIdentifier;
-        '''
+        """
         result = self.runMkenumsWithHeader(h_contents)
-        self.assertEqual('', result.err)
-        self.assertSingleEnum(result, 'SomeEnumIdentifier',
-                              'some_enum_identifier', 'SOME_ENUM_IDENTIFIER',
-                              'ENUM_IDENTIFIER', 'SOME', '', 'enum', 'Enum',
-                              'ENUM', 'ENUM_VALUE', 'value', '0')
+        self.assertEqual("", result.err)
+        self.assertSingleEnum(
+            result,
+            "SomeEnumIdentifier",
+            "some_enum_identifier",
+            "SOME_ENUM_IDENTIFIER",
+            "ENUM_IDENTIFIER",
+            "SOME",
+            "",
+            "enum",
+            "Enum",
+            "ENUM",
+            "ENUM_VALUE",
+            "value",
+            "0",
+        )
 
     def test_non_utf8_encoding(self):
         """Test source files with non-UTF-8 encoding. Bug #785113."""
-        h_contents = '''
+        h_contents = """
         /* Copyright © La Peña */
         typedef enum {
           ENUM_VALUE
         } SomeEnumIdentifier;
-        '''
-        result = self.runMkenumsWithHeader(h_contents, encoding='iso-8859-1')
-        self.assertIn('WARNING: UnicodeWarning: ', result.err)
-        self.assertSingleEnum(result, 'SomeEnumIdentifier',
-                              'some_enum_identifier', 'SOME_ENUM_IDENTIFIER',
-                              'ENUM_IDENTIFIER', 'SOME', '', 'enum', 'Enum',
-                              'ENUM', 'ENUM_VALUE', 'value', '0')
+        """
+        result = self.runMkenumsWithHeader(h_contents, encoding="iso-8859-1")
+        self.assertIn("WARNING: UnicodeWarning: ", result.err)
+        self.assertSingleEnum(
+            result,
+            "SomeEnumIdentifier",
+            "some_enum_identifier",
+            "SOME_ENUM_IDENTIFIER",
+            "ENUM_IDENTIFIER",
+            "SOME",
+            "",
+            "enum",
+            "Enum",
+            "ENUM",
+            "ENUM_VALUE",
+            "value",
+            "0",
+        )
 
     def test_reproducible(self):
         """Test builds are reproducible regardless of file ordering.
         Bug #691436."""
-        template_contents = 'template'
+        template_contents = "template"
 
-        h_contents1 = '''
+        h_contents1 = """
         typedef enum {
           FIRST,
         } Header1;
-        '''
+        """
 
-        h_contents2 = '''
+        h_contents2 = """
         typedef enum {
           SECOND,
         } Header2;
-        '''
+        """
 
-        with tempfile.NamedTemporaryFile(dir=self.tmpdir.name,
-                                         suffix='1.h', delete=False) as h_file1, \
-                tempfile.NamedTemporaryFile(dir=self.tmpdir.name,
-                                            suffix='2.h', delete=False) as h_file2:
+        with tempfile.NamedTemporaryFile(
+            dir=self.tmpdir.name, suffix="1.h", delete=False
+        ) as h_file1, tempfile.NamedTemporaryFile(
+            dir=self.tmpdir.name, suffix="2.h", delete=False
+        ) as h_file2:
             # Write out the headers.
-            h_file1.write(h_contents1.encode('utf-8'))
-            h_file2.write(h_contents2.encode('utf-8'))
+            h_file1.write(h_contents1.encode("utf-8"))
+            h_file2.write(h_contents2.encode("utf-8"))
 
             h_file1.flush()
             h_file2.flush()
 
             # Run glib-mkenums with the headers in one order, and then again
             # in another order.
-            result1 = self.runMkenumsWithTemplate(template_contents,
-                                                  h_file1.name, h_file2.name)
-            self.assertEqual('', result1.err)
+            result1 = self.runMkenumsWithTemplate(
+                template_contents, h_file1.name, h_file2.name
+            )
+            self.assertEqual("", result1.err)
 
-            result2 = self.runMkenumsWithTemplate(template_contents,
-                                                  h_file2.name, h_file1.name)
-            self.assertEqual('', result2.err)
+            result2 = self.runMkenumsWithTemplate(
+                template_contents, h_file2.name, h_file1.name
+            )
+            self.assertEqual("", result2.err)
 
             # The output should be the same.
             self.assertEqual(result1.out, result2.out)
 
     def test_no_nick(self):
         """Test trigraphs with a desc but no nick. Issue #1360."""
-        h_contents = '''
+        h_contents = """
         typedef enum {
           GEGL_SAMPLER_NEAREST = 0,   /*< desc="nearest"      >*/
         } GeglSamplerType;
-        '''
+        """
         result = self.runMkenumsWithHeader(h_contents)
-        self.assertEqual('', result.err)
-        self.assertSingleEnum(result, 'GeglSamplerType',
-                              'gegl_sampler_type', 'GEGL_SAMPLER_TYPE',
-                              'SAMPLER_TYPE', 'GEGL', '', 'enum', 'Enum',
-                              'ENUM', 'GEGL_SAMPLER_NEAREST', 'nearest', '0')
+        self.assertEqual("", result.err)
+        self.assertSingleEnum(
+            result,
+            "GeglSamplerType",
+            "gegl_sampler_type",
+            "GEGL_SAMPLER_TYPE",
+            "SAMPLER_TYPE",
+            "GEGL",
+            "",
+            "enum",
+            "Enum",
+            "ENUM",
+            "GEGL_SAMPLER_NEAREST",
+            "nearest",
+            "0",
+        )
 
     def test_filename_basename_in_fhead_ftail(self):
-        template_contents = '''
+        template_contents = """
 /*** BEGIN file-header ***/
 file-header
 filename: @filename@
@@ -457,18 +535,21 @@ comment: @comment@
 file-tail
 filename: @filename@
 basename: @basename@
-/*** END file-tail ***/'''
+/*** END file-tail ***/"""
         result = self.runMkenumsWithTemplate(template_contents)
         self.assertEqual(
             textwrap.dedent(
-                '''
+                """
                 WARNING: @filename@ used in file-header section.
                 WARNING: @basename@ used in file-header section.
                 WARNING: @filename@ used in file-tail section.
                 WARNING: @basename@ used in file-tail section.
-                ''').strip(),
-            result.err)
-        self.assertEqual('''
+                """
+            ).strip(),
+            result.err,
+        )
+        self.assertEqual(
+            """
 comment
 comment: {standard_top_comment}
 
@@ -482,27 +563,44 @@ basename: @basename@
 
 comment
 comment: {standard_bottom_comment}
-'''.format(**result.subs).strip(), result.out)
+""".format(
+                **result.subs
+            ).strip(),
+            result.out,
+        )
 
     def test_since(self):
         """Test user-provided 'since' version handling
         https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1492"""
-        h_contents = '''
+        h_contents = """
         typedef enum { /*< since=1.0 >*/
             QMI_WMS_MESSAGE_PROTOCOL_CDMA = 0,
         } QmiWmsMessageProtocol;
-        '''
+        """
         result = self.runMkenumsWithHeader(h_contents)
-        self.assertEqual('', result.err)
-        self.assertSingleEnum(result, 'QmiWmsMessageProtocol',
-                              'qmi_wms_message_protocol', 'QMI_WMS_MESSAGE_PROTOCOL',
-                              'WMS_MESSAGE_PROTOCOL', 'QMI', '1.0', 'enum', 'Enum',
-                              'ENUM', 'QMI_WMS_MESSAGE_PROTOCOL_CDMA', 'cdma', '0')
+        self.assertEqual("", result.err)
+        self.assertSingleEnum(
+            result,
+            "QmiWmsMessageProtocol",
+            "qmi_wms_message_protocol",
+            "QMI_WMS_MESSAGE_PROTOCOL",
+            "WMS_MESSAGE_PROTOCOL",
+            "QMI",
+            "1.0",
+            "enum",
+            "Enum",
+            "ENUM",
+            "QMI_WMS_MESSAGE_PROTOCOL_CDMA",
+            "cdma",
+            "0",
+        )
+
 
 class TestRspMkenums(TestMkenums):
-    '''Run all tests again in @rspfile mode'''
+    """Run all tests again in @rspfile mode"""
+
     rspfile = True
 
 
-if __name__ == '__main__':
+if __name__ == "__main__":
     unittest.main(testRunner=taptestrunner.TAPTestRunner())
index 528bdc6..7d46efb 100644 (file)
@@ -17,7 +17,7 @@ gboolean fail;
 #define ROUNDS 10000
 
 GObject *object;
-volatile gint bucket[THREADS];
+gint bucket[THREADS];  /* accessed from multiple threads, but should never be contested due to the sequence of thread operations */
 
 static gpointer
 thread_func (gpointer data)
index 08b54d0..ac0ce51 100644 (file)
@@ -66,9 +66,9 @@ custom_marshal_VOID__INVOCATIONHINT (GClosure     *closure,
 static GType
 test_enum_get_type (void)
 {
-  static volatile gsize g_define_type_id__volatile = 0;
+  static gsize static_g_define_type_id = 0;
 
-  if (g_once_init_enter (&g_define_type_id__volatile))
+  if (g_once_init_enter (&static_g_define_type_id))
     {
       static const GEnumValue values[] = {
         { TEST_ENUM_NEGATIVE, "TEST_ENUM_NEGATIVE", "negative" },
@@ -79,18 +79,18 @@ test_enum_get_type (void)
       };
       GType g_define_type_id =
         g_enum_register_static (g_intern_static_string ("TestEnum"), values);
-      g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
+      g_once_init_leave (&static_g_define_type_id, g_define_type_id);
     }
 
-  return g_define_type_id__volatile;
+  return static_g_define_type_id;
 }
 
 static GType
 test_unsigned_enum_get_type (void)
 {
-  static volatile gsize g_define_type_id__volatile = 0;
+  static gsize static_g_define_type_id = 0;
 
-  if (g_once_init_enter (&g_define_type_id__volatile))
+  if (g_once_init_enter (&static_g_define_type_id))
     {
       static const GEnumValue values[] = {
         { TEST_UNSIGNED_ENUM_FOO, "TEST_UNSIGNED_ENUM_FOO", "foo" },
@@ -99,10 +99,10 @@ test_unsigned_enum_get_type (void)
       };
       GType g_define_type_id =
         g_enum_register_static (g_intern_static_string ("TestUnsignedEnum"), values);
-      g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
+      g_once_init_leave (&static_g_define_type_id, g_define_type_id);
     }
 
-  return g_define_type_id__volatile;
+  return static_g_define_type_id;
 }
 
 typedef enum {
@@ -135,6 +135,47 @@ static GType flags_type;
 static guint simple_id;
 static guint simple2_id;
 
+typedef struct {
+  GTypeInterface g_iface;
+} FooInterface;
+
+GType foo_get_type (void);
+
+G_DEFINE_INTERFACE (Foo, foo, G_TYPE_OBJECT)
+
+static void
+foo_default_init (FooInterface *iface)
+{
+}
+
+typedef struct {
+  GObject parent;
+} Baa;
+
+typedef struct {
+  GObjectClass parent_class;
+} BaaClass;
+
+static void
+baa_init_foo (FooInterface *iface)
+{
+}
+
+GType baa_get_type (void);
+
+G_DEFINE_TYPE_WITH_CODE (Baa, baa, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (foo_get_type (), baa_init_foo))
+
+static void
+baa_init (Baa *baa)
+{
+}
+
+static void
+baa_class_init (BaaClass *class)
+{
+}
+
 typedef struct _Test Test;
 typedef struct _TestClass TestClass;
 
@@ -257,6 +298,14 @@ test_class_init (TestClass *klass)
                 NULL,
                 G_TYPE_UINT,
                 0);
+  g_signal_new ("generic-marshaller-interface-return",
+                G_TYPE_FROM_CLASS (klass),
+                G_SIGNAL_RUN_LAST,
+                0,
+                NULL, NULL,
+                NULL,
+                foo_get_type (),
+                0);
   s = g_signal_new ("va-marshaller-uint-return",
                 G_TYPE_FROM_CLASS (klass),
                 G_SIGNAL_RUN_LAST,
@@ -754,6 +803,35 @@ test_generic_marshaller_signal_uint_return (void)
   g_object_unref (test);
 }
 
+static gpointer
+on_generic_marshaller_interface_return (Test *test)
+{
+  return g_object_new (baa_get_type (), NULL);
+}
+
+static void
+test_generic_marshaller_signal_interface_return (void)
+{
+  Test *test;
+  guint id;
+  gpointer retval;
+
+  test = g_object_new (test_get_type (), NULL);
+
+  /* Test return value -30 */
+  id = g_signal_connect (test,
+                         "generic-marshaller-interface-return",
+                         G_CALLBACK (on_generic_marshaller_interface_return),
+                         NULL);
+  g_signal_emit_by_name (test, "generic-marshaller-interface-return", &retval);
+  g_assert_true (g_type_check_instance_is_a ((GTypeInstance*)retval, foo_get_type ()));
+  g_object_unref (retval);
+
+  g_signal_handler_disconnect (test, id);
+
+  g_object_unref (test);
+}
+
 static const GSignalInvocationHint dont_use_this = { 0, };
 
 static void
@@ -1082,6 +1160,7 @@ test_introspection (void)
     "generic-marshaller-int-return",
     "va-marshaller-int-return",
     "generic-marshaller-uint-return",
+    "generic-marshaller-interface-return",
     "va-marshaller-uint-return",
     "variant-changed-no-slot",
     "variant-changed",
@@ -1495,6 +1574,7 @@ main (int argc,
   g_test_add_func ("/gobject/signals/generic-marshaller-enum-return-unsigned", test_generic_marshaller_signal_enum_return_unsigned);
   g_test_add_func ("/gobject/signals/generic-marshaller-int-return", test_generic_marshaller_signal_int_return);
   g_test_add_func ("/gobject/signals/generic-marshaller-uint-return", test_generic_marshaller_signal_uint_return);
+  g_test_add_func ("/gobject/signals/generic-marshaller-interface-return", test_generic_marshaller_signal_interface_return);
   g_test_add_func ("/gobject/signals/custom-marshaller", test_custom_marshaller);
   g_test_add_func ("/gobject/signals/connect", test_connect);
   g_test_add_func ("/gobject/signals/emission-hook", test_emission_hook);
index 2614961..9ce3b43 100644 (file)
@@ -30,147 +30,157 @@ import sys
 import base64
 from io import StringIO
 
+
 # Log modes
-class LogMode(object) :
-  LogToError, LogToDiagnostics, LogToYAML, LogToAttachment = range(4)
+class LogMode(object):
+    LogToError, LogToDiagnostics, LogToYAML, LogToAttachment = range(4)
 
 
 class TAPTestResult(unittest.TestResult):
-  def __init__(self, output_stream, error_stream, message_log, test_output_log):
-    super(TAPTestResult, self).__init__(self, output_stream)
-    self.output_stream = output_stream
-    self.error_stream = error_stream
-    self.orig_stdout = None
-    self.orig_stderr = None
-    self.message = None
-    self.test_output = None
-    self.message_log = message_log
-    self.test_output_log = test_output_log
-    self.output_stream.write("TAP version 13\n")
-    self._set_streams()
-
-  def printErrors(self):
-    self.print_raw("1..%d\n" % self.testsRun)
-    self._reset_streams()
-
-  def _set_streams(self):
-    self.orig_stdout = sys.stdout
-    self.orig_stderr = sys.stderr
-    if self.message_log == LogMode.LogToError:
-      self.message = self.error_stream
-    else:
-      self.message = StringIO()
-    if self.test_output_log == LogMode.LogToError:
-      self.test_output = self.error_stream
-    else:
-      self.test_output = StringIO()
-
-    if self.message_log == self.test_output_log:
-      self.test_output = self.message
-    sys.stdout = sys.stderr = self.test_output
-
-  def _reset_streams(self):
-    sys.stdout = self.orig_stdout
-    sys.stderr = self.orig_stderr
-
-
-  def print_raw(self, text):
-    self.output_stream.write(text)
-    self.output_stream.flush()
-
-  def print_result(self, result, test, directive = None):
-    self.output_stream.write("%s %d %s" % (result, self.testsRun, test.id()))
-    if directive:
-      self.output_stream.write(" # " + directive)
-    self.output_stream.write("\n")
-    self.output_stream.flush()
-
-  def ok(self, test, directive = None):
-    self.print_result("ok", test, directive)
-
-  def not_ok(self, test):
-    self.print_result("not ok", test)
-
-  def startTest(self, test):
-    super(TAPTestResult, self).startTest(test)
-
-  def stopTest(self, test):
-    super(TAPTestResult, self).stopTest(test)
-    if self.message_log == self.test_output_log:
-      logs = [(self.message_log, self.message, "output")]
-    else:
-      logs = [
-          (self.test_output_log, self.test_output, "test_output"),
-          (self.message_log, self.message, "message")
-      ]
-    for log_mode, log, log_name in logs:
-      if log_mode != LogMode.LogToError:
-        output = log.getvalue()
-        if len(output):
-          if log_mode == LogMode.LogToYAML:
-            self.print_raw("  ---\n")
-            self.print_raw("    " + log_name + ": |\n")
-            self.print_raw("      " + output.rstrip().replace("\n", "\n      ") + "\n")
-            self.print_raw("  ...\n")
-          elif log_mode == LogMode.LogToAttachment:
-            self.print_raw("  ---\n")
-            self.print_raw("    " + log_name + ":\n")
-            self.print_raw("      File-Name: " + log_name + ".txt\n")
-            self.print_raw("      File-Type: text/plain\n")
-            self.print_raw("      File-Content: " + base64.b64encode(output) + "\n")
-            self.print_raw("  ...\n")
-          else:
-            self.print_raw("# " + output.rstrip().replace("\n", "\n# ") + "\n")
-        # Truncate doesn't change the current stream position.
-        # Seek to the beginning to avoid extensions on subsequent writes.
-        log.seek(0)
-        log.truncate(0)
-
-  def addSuccess(self, test):
-    super(TAPTestResult, self).addSuccess(test)
-    self.ok(test)
-
-  def addError(self, test, err):
-    super(TAPTestResult, self).addError(test, err)
-    self.message.write(self.errors[-1][1] + "\n")
-    self.not_ok(test)
-
-  def addFailure(self, test, err):
-    super(TAPTestResult, self).addFailure(test, err)
-    self.message.write(self.failures[-1][1] + "\n")
-    self.not_ok(test)
-
-  def addSkip(self, test, reason):
-    super(TAPTestResult, self).addSkip(test, reason)
-    self.ok(test, "SKIP " + reason)
-
-  def addExpectedFailure(self, test, err):
-    super(TAPTestResult, self).addExpectedFailure(test, err)
-    self.ok(test)
-
-  def addUnexpectedSuccess(self, test):
-    super(TAPTestResult, self).addUnexpectedSuccess(test)
-    self.message.write("Unexpected success" + "\n")
-    self.not_ok(test)
+    def __init__(self, output_stream, error_stream, message_log, test_output_log):
+        super(TAPTestResult, self).__init__(self, output_stream)
+        self.output_stream = output_stream
+        self.error_stream = error_stream
+        self.orig_stdout = None
+        self.orig_stderr = None
+        self.message = None
+        self.test_output = None
+        self.message_log = message_log
+        self.test_output_log = test_output_log
+        self.output_stream.write("TAP version 13\n")
+        self._set_streams()
+
+    def printErrors(self):
+        self.print_raw("1..%d\n" % self.testsRun)
+        self._reset_streams()
+
+    def _set_streams(self):
+        self.orig_stdout = sys.stdout
+        self.orig_stderr = sys.stderr
+        if self.message_log == LogMode.LogToError:
+            self.message = self.error_stream
+        else:
+            self.message = StringIO()
+        if self.test_output_log == LogMode.LogToError:
+            self.test_output = self.error_stream
+        else:
+            self.test_output = StringIO()
+
+        if self.message_log == self.test_output_log:
+            self.test_output = self.message
+        sys.stdout = sys.stderr = self.test_output
+
+    def _reset_streams(self):
+        sys.stdout = self.orig_stdout
+        sys.stderr = self.orig_stderr
+
+    def print_raw(self, text):
+        self.output_stream.write(text)
+        self.output_stream.flush()
+
+    def print_result(self, result, test, directive=None):
+        self.output_stream.write("%s %d %s" % (result, self.testsRun, test.id()))
+        if directive:
+            self.output_stream.write(" # " + directive)
+        self.output_stream.write("\n")
+        self.output_stream.flush()
+
+    def ok(self, test, directive=None):
+        self.print_result("ok", test, directive)
+
+    def not_ok(self, test):
+        self.print_result("not ok", test)
+
+    def startTest(self, test):
+        super(TAPTestResult, self).startTest(test)
+
+    def stopTest(self, test):
+        super(TAPTestResult, self).stopTest(test)
+        if self.message_log == self.test_output_log:
+            logs = [(self.message_log, self.message, "output")]
+        else:
+            logs = [
+                (self.test_output_log, self.test_output, "test_output"),
+                (self.message_log, self.message, "message"),
+            ]
+        for log_mode, log, log_name in logs:
+            if log_mode != LogMode.LogToError:
+                output = log.getvalue()
+                if len(output):
+                    if log_mode == LogMode.LogToYAML:
+                        self.print_raw("  ---\n")
+                        self.print_raw("    " + log_name + ": |\n")
+                        self.print_raw(
+                            "      " + output.rstrip().replace("\n", "\n      ") + "\n"
+                        )
+                        self.print_raw("  ...\n")
+                    elif log_mode == LogMode.LogToAttachment:
+                        self.print_raw("  ---\n")
+                        self.print_raw("    " + log_name + ":\n")
+                        self.print_raw("      File-Name: " + log_name + ".txt\n")
+                        self.print_raw("      File-Type: text/plain\n")
+                        self.print_raw(
+                            "      File-Content: " + base64.b64encode(output) + "\n"
+                        )
+                        self.print_raw("  ...\n")
+                    else:
+                        self.print_raw(
+                            "# " + output.rstrip().replace("\n", "\n# ") + "\n"
+                        )
+                # Truncate doesn't change the current stream position.
+                # Seek to the beginning to avoid extensions on subsequent writes.
+                log.seek(0)
+                log.truncate(0)
+
+    def addSuccess(self, test):
+        super(TAPTestResult, self).addSuccess(test)
+        self.ok(test)
+
+    def addError(self, test, err):
+        super(TAPTestResult, self).addError(test, err)
+        self.message.write(self.errors[-1][1] + "\n")
+        self.not_ok(test)
+
+    def addFailure(self, test, err):
+        super(TAPTestResult, self).addFailure(test, err)
+        self.message.write(self.failures[-1][1] + "\n")
+        self.not_ok(test)
+
+    def addSkip(self, test, reason):
+        super(TAPTestResult, self).addSkip(test, reason)
+        self.ok(test, "SKIP " + reason)
+
+    def addExpectedFailure(self, test, err):
+        super(TAPTestResult, self).addExpectedFailure(test, err)
+        self.ok(test)
+
+    def addUnexpectedSuccess(self, test):
+        super(TAPTestResult, self).addUnexpectedSuccess(test)
+        self.message.write("Unexpected success" + "\n")
+        self.not_ok(test)
 
 
 class TAPTestRunner(object):
-  def __init__(self,
-      message_log = LogMode.LogToYAML,
-      test_output_log = LogMode.LogToDiagnostics,
-      output_stream = sys.stdout, error_stream = sys.stderr):
-    self.output_stream = output_stream
-    self.error_stream = error_stream
-    self.message_log = message_log
-    self.test_output_log = test_output_log
-
-  def run(self, test):
-    result = TAPTestResult(
-        self.output_stream,
-        self.error_stream,
-        self.message_log,
-        self.test_output_log)
-    test(result)
-    result.printErrors()
-
-    return result
+    def __init__(
+        self,
+        message_log=LogMode.LogToYAML,
+        test_output_log=LogMode.LogToDiagnostics,
+        output_stream=sys.stdout,
+        error_stream=sys.stderr,
+    ):
+        self.output_stream = output_stream
+        self.error_stream = error_stream
+        self.message_log = message_log
+        self.test_output_log = test_output_log
+
+    def run(self, test):
+        result = TAPTestResult(
+            self.output_stream,
+            self.error_stream,
+            self.message_log,
+            self.test_output_log,
+        )
+        test(result)
+        result.printErrors()
+
+        return result
index 4cba720..b6f9e17 100644 (file)
@@ -27,8 +27,8 @@
 #include <glib.h>
 #include <glib-object.h>
 
-static volatile int mtsafe_call_counter = 0; /* multi thread safe call counter */
-static int          unsafe_call_counter = 0; /* single-threaded call counter */
+static int mtsafe_call_counter = 0; /* multi thread safe call counter, must be accessed atomically */
+static int unsafe_call_counter = 0; /* single-threaded call counter */
 static GCond sync_cond;
 static GMutex sync_mutex;
 
@@ -159,7 +159,7 @@ static void
 prop_tester_init (PropTester* t)
 {
   if (t->name == NULL)
-    ; /* neds unit test framework initialization: g_test_bug ("race initializing properties"); */
+    { } /* needs unit test framework initialization: g_test_bug ("race initializing properties"); */
 }
 static void
 prop_tester_set_property (GObject        *object,
index c5db7e9..30e138a 100644 (file)
@@ -40,6 +40,63 @@ foo_default_init (FooInterface *iface)
 {
 }
 
+typedef struct {
+  GTypeInterface g_iface;
+} BaaInterface;
+
+GType baa_get_type (void);
+
+G_DEFINE_INTERFACE (Baa, baa, G_TYPE_INVALID)
+
+static void
+baa_default_init (BaaInterface *iface)
+{
+}
+
+typedef struct {
+  GTypeInterface g_iface;
+} BooInterface;
+
+GType boo_get_type (void);
+
+G_DEFINE_INTERFACE_WITH_CODE (Boo, boo, G_TYPE_INVALID,
+                              g_type_interface_add_prerequisite (g_define_type_id, baa_get_type ()))
+
+static void
+boo_default_init (BooInterface *iface)
+{
+}
+
+typedef struct {
+  GTypeInterface g_iface;
+} BibiInterface;
+
+GType bibi_get_type (void);
+
+G_DEFINE_INTERFACE (Bibi, bibi, G_TYPE_INITIALLY_UNOWNED)
+
+static void
+bibi_default_init (BibiInterface *iface)
+{
+}
+
+typedef struct {
+  GTypeInterface g_iface;
+} BozoInterface;
+
+GType bozo_get_type (void);
+
+G_DEFINE_INTERFACE_WITH_CODE (Bozo, bozo, G_TYPE_INVALID,
+                              g_type_interface_add_prerequisite (g_define_type_id, foo_get_type ());
+                              g_type_interface_add_prerequisite (g_define_type_id, bibi_get_type ()))
+
+static void
+bozo_default_init (BozoInterface *iface)
+{
+}
+
+
+
 static void
 test_interface_prerequisite (void)
 {
@@ -52,6 +109,7 @@ test_interface_prerequisite (void)
   g_assert_cmpint (n_prereqs, ==, 2);
   g_assert (prereqs[0] == bar_get_type ());
   g_assert (prereqs[1] == G_TYPE_OBJECT);
+  g_assert (g_type_interface_instantiatable_prerequisite (foo_get_type ()) == G_TYPE_OBJECT);
 
   iface = g_type_default_interface_ref (foo_get_type ());
   parent = g_type_interface_peek_parent (iface);
@@ -59,6 +117,11 @@ test_interface_prerequisite (void)
   g_type_default_interface_unref (iface);
 
   g_free (prereqs);
+
+  g_assert_cmpint (g_type_interface_instantiatable_prerequisite (baa_get_type ()), ==, G_TYPE_INVALID);
+  g_assert_cmpint (g_type_interface_instantiatable_prerequisite (boo_get_type ()), ==, G_TYPE_INVALID);
+
+  g_assert_cmpint (g_type_interface_instantiatable_prerequisite (bozo_get_type ()), ==, G_TYPE_INITIALLY_UNOWNED);
 }
 
 typedef struct {
index e21b234..b3ea223 100644 (file)
@@ -261,6 +261,99 @@ test_valuearray_basic (void)
   g_value_array_free (a2);
 }
 
+/* We create some dummy objects with this relationship:
+ *
+ *               GObject           TestInterface
+ *              /       \         /  /
+ *     TestObjectA     TestObjectB  /
+ *      /       \                  /
+ * TestObjectA1 TestObjectA2-------   
+ *
+ * ie: TestObjectA1 and TestObjectA2 are subclasses of TestObjectA
+ * and TestObjectB is related to neither. TestObjectA2 and TestObjectB
+ * implement TestInterface
+ */
+
+typedef GTypeInterface TestInterfaceInterface;
+static GType test_interface_get_type (void);
+G_DEFINE_INTERFACE (TestInterface, test_interface, G_TYPE_OBJECT)
+static void test_interface_default_init (TestInterfaceInterface *iface) { }
+
+static GType test_object_a_get_type (void);
+typedef GObject TestObjectA; typedef GObjectClass TestObjectAClass;
+G_DEFINE_TYPE (TestObjectA, test_object_a, G_TYPE_OBJECT)
+static void test_object_a_class_init (TestObjectAClass *class) { }
+static void test_object_a_init (TestObjectA *a) { }
+
+static GType test_object_b_get_type (void);
+typedef GObject TestObjectB; typedef GObjectClass TestObjectBClass;
+static void test_object_b_iface_init (TestInterfaceInterface *iface) { }
+G_DEFINE_TYPE_WITH_CODE (TestObjectB, test_object_b, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (test_interface_get_type (), test_object_b_iface_init))
+static void test_object_b_class_init (TestObjectBClass *class) { }
+static void test_object_b_init (TestObjectB *b) { }
+
+static GType test_object_a1_get_type (void);
+typedef GObject TestObjectA1; typedef GObjectClass TestObjectA1Class;
+G_DEFINE_TYPE (TestObjectA1, test_object_a1, test_object_a_get_type ())
+static void test_object_a1_class_init (TestObjectA1Class *class) { }
+static void test_object_a1_init (TestObjectA1 *c) { }
+
+static GType test_object_a2_get_type (void);
+typedef GObject TestObjectA2; typedef GObjectClass TestObjectA2Class;
+static void test_object_a2_iface_init (TestInterfaceInterface *iface) { }
+G_DEFINE_TYPE_WITH_CODE (TestObjectA2, test_object_a2, test_object_a_get_type (),
+                         G_IMPLEMENT_INTERFACE (test_interface_get_type (), test_object_a2_iface_init))
+static void test_object_a2_class_init (TestObjectA2Class *class) { }
+static void test_object_a2_init (TestObjectA2 *b) { }
+
+static void
+test_value_transform_object (void)
+{
+  GValue src = G_VALUE_INIT;
+  GValue dest = G_VALUE_INIT;
+  GObject *object;
+  guint i, s, d;
+  GType types[] = {
+    G_TYPE_OBJECT,
+    test_interface_get_type (),
+    test_object_a_get_type (),
+    test_object_b_get_type (),
+    test_object_a1_get_type (),
+    test_object_a2_get_type ()
+  };
+
+  for (i = 0; i < G_N_ELEMENTS (types); i++)
+    {
+      if (!G_TYPE_IS_CLASSED (types[i]))
+        continue;
+
+      object = g_object_new (types[i], NULL);
+
+      for (s = 0; s < G_N_ELEMENTS (types); s++)
+        {
+          if (!G_TYPE_CHECK_INSTANCE_TYPE (object, types[s]))
+            continue;
+
+          g_value_init (&src, types[s]);
+          g_value_set_object (&src, object);
+
+          for (d = 0; d < G_N_ELEMENTS (types); d++)
+            {
+              g_test_message ("Next: %s object in GValue of %s to GValue of %s", g_type_name (types[i]), g_type_name (types[s]), g_type_name (types[d]));
+              g_assert_true (g_value_type_transformable (types[s], types[d]));
+              g_value_init (&dest, types[d]);
+              g_assert_true (g_value_transform (&src, &dest));
+              g_assert_cmpint (g_value_get_object (&dest) != NULL, ==, G_TYPE_CHECK_INSTANCE_TYPE (object, types[d]));
+              g_value_unset (&dest);
+            }
+          g_value_unset (&src);
+        }
+
+      g_object_unref (object);
+    }
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -269,6 +362,7 @@ main (int argc, char *argv[])
   g_test_add_func ("/value/basic", test_value_basic);
   g_test_add_func ("/value/string", test_value_string);
   g_test_add_func ("/value/array/basic", test_valuearray_basic);
+  g_test_add_func ("/value/transform-object", test_value_transform_object);
 
   return g_test_run ();
 }
index e0b308a..7e9f89b 100644 (file)
@@ -1,5 +1,5 @@
 project('glib', 'c', 'cpp',
-  version : '2.67.0',
+  version : '2.67.1',
   # NOTE: We keep this pinned at 0.49 because that's what Debian 10 ships
   meson_version : '>= 0.49.2',
   default_options : [
@@ -1773,7 +1773,7 @@ endforeach
 # that then to silently fall back on emulated atomic ops just because
 # the user had the wrong build environment.
 atomictest = '''int main() {
-  volatile int atomic = 2;
+  int atomic = 2;
   __sync_bool_compare_and_swap (&atomic, 2, 3);
   return 0;
 }
@@ -1883,6 +1883,7 @@ endif
 
 # FIXME: we should make it print the result and always return 0, so that
 # the output in meson shows up as green
+# volatile is needed here to avoid optimisations in the test
 stack_grows_check_prog = '''
   volatile int *a = 0, *b = 0;
   void f (int i) {
@@ -2062,7 +2063,7 @@ endif
 
 selinux_dep = []
 if host_system == 'linux'
-  selinux_dep = dependency('libselinux', required: get_option('selinux'))
+  selinux_dep = dependency('libselinux', version: '>=2.2', required: get_option('selinux'))
 
   glib_conf.set('HAVE_SELINUX', selinux_dep.found())
 endif
index c0eb1d5..e706987 100644 (file)
 #pragma warning(disable:4101) /* unreferenced local variable */
 #pragma warning(error:4150)
 
+/* G_NORETURN */
+#pragma warning(error:4646) /* function declared with __declspec(noreturn) has non-void return type */
+#pragma warning(error:4715) /* 'function': not all control paths return a value */
+#pragma warning(error:4098) /* 'void' function returning a value */
+
 #pragma warning(disable:4244)  /* No possible loss of data warnings */
 #pragma warning(disable:4305)   /* No truncation from int to char warnings */
 
index e58a447..81c1ec2 100644 (file)
--- a/po/cs.po
+++ b/po/cs.po
@@ -15,8 +15,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: glib\n"
 "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n"
-"POT-Creation-Date: 2020-08-22 13:31+0000\n"
-"PO-Revision-Date: 2020-08-28 19:47+0200\n"
+"POT-Creation-Date: 2020-11-06 17:19+0000\n"
+"PO-Revision-Date: 2020-11-28 16:16+0100\n"
 "Last-Translator: Marek Černocký <marek@manet.cz>\n"
 "Language-Team: čeština <gnome-cs-list@gnome.org>\n"
 "Language: cs\n"
@@ -110,7 +110,7 @@ msgstr "Vypsat statické akce svázané s aplikací (ze souboru .desktop)"
 msgid "APPID"
 msgstr "IDAPLIKACE"
 
-#: gio/gapplication-tool.c:70 gio/gapplication-tool.c:133 gio/gdbus-tool.c:102
+#: gio/gapplication-tool.c:70 gio/gapplication-tool.c:133 gio/gdbus-tool.c:106
 #: gio/gio-tool.c:224
 msgid "COMMAND"
 msgstr "PŘÍKAZ"
@@ -288,7 +288,7 @@ msgstr "Proud je již uzavřen"
 msgid "Truncate not supported on base stream"
 msgstr "Zkrácování není v proudu podporováno"
 
-#: gio/gcancellable.c:319 gio/gdbusconnection.c:1862 gio/gdbusprivate.c:1413
+#: gio/gcancellable.c:319 gio/gdbusconnection.c:1862 gio/gdbusprivate.c:1416
 #: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897
 #, c-format
 msgid "Operation was cancelled"
@@ -510,7 +510,7 @@ msgstr "Chyba při spouštění příkazového řádku „%s“: "
 msgid "Cannot determine session bus address (not implemented for this OS)"
 msgstr "Nelze určit adresu sběrnice sezení (v tomto OS neimplementováno)"
 
-#: gio/gdbusaddress.c:1357 gio/gdbusconnection.c:7192
+#: gio/gdbusaddress.c:1357 gio/gdbusconnection.c:7217
 #, c-format
 msgid ""
 "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable "
@@ -519,7 +519,7 @@ msgstr ""
 "Nelze určit adresu sběrnice z proměnné prostředí DBUS_STARTER_BUS_TYPE – "
 "neznámá hodnota „%s“"
 
-#: gio/gdbusaddress.c:1366 gio/gdbusconnection.c:7201
+#: gio/gdbusaddress.c:1366 gio/gdbusconnection.c:7226
 msgid ""
 "Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment "
 "variable is not set"
@@ -551,76 +551,76 @@ msgstr ""
 msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer"
 msgstr "Zrušeno přes GDBusAuthObserver::authorize-authenticated-peer"
 
-#: gio/gdbusauthmechanismsha1.c:265
+#: gio/gdbusauthmechanismsha1.c:296
 #, c-format
 msgid "Error when getting information for directory “%s”: %s"
 msgstr "Chyba při získávání informací pro složku „%s“: %s"
 
-#: gio/gdbusauthmechanismsha1.c:280
+#: gio/gdbusauthmechanismsha1.c:311
 #, c-format
 msgid ""
 "Permissions on directory “%s” are malformed. Expected mode 0700, got 0%o"
 msgstr ""
 "Oprávnění složky „%s“ mají chybný formát. Očekáván režim 0700, obdržen 0%o"
 
-#: gio/gdbusauthmechanismsha1.c:310
+#: gio/gdbusauthmechanismsha1.c:341
 #, c-format
 msgid "Error creating directory “%s”: %s"
 msgstr "Chyba při vytváření složky %s: %s"
 
-#: gio/gdbusauthmechanismsha1.c:355
+#: gio/gdbusauthmechanismsha1.c:386
 #, c-format
 msgid "Error opening keyring “%s” for reading: "
 msgstr "Chyba při otevírání klíčenky „%s“ ke čtení: "
 
-#: gio/gdbusauthmechanismsha1.c:378 gio/gdbusauthmechanismsha1.c:700
+#: gio/gdbusauthmechanismsha1.c:409 gio/gdbusauthmechanismsha1.c:731
 #, c-format
 msgid "Line %d of the keyring at “%s” with content “%s” is malformed"
 msgstr "Řádek %d klíčenky na „%s“ s obsahem „%s“ má chybný formát"
 
-#: gio/gdbusauthmechanismsha1.c:392 gio/gdbusauthmechanismsha1.c:714
+#: gio/gdbusauthmechanismsha1.c:423 gio/gdbusauthmechanismsha1.c:745
 #, c-format
 msgid ""
 "First token of line %d of the keyring at “%s” with content “%s” is malformed"
 msgstr "První symbol řádku %d klíčenky na „%s“ s obsahem „%s“ má chybný formát"
 
-#: gio/gdbusauthmechanismsha1.c:406 gio/gdbusauthmechanismsha1.c:728
+#: gio/gdbusauthmechanismsha1.c:437 gio/gdbusauthmechanismsha1.c:759
 #, c-format
 msgid ""
 "Second token of line %d of the keyring at “%s” with content “%s” is malformed"
 msgstr "Druhý symbol řádku %d klíčenky na „%s“ s obsahem „%s“ má chybný formát"
 
-#: gio/gdbusauthmechanismsha1.c:430
+#: gio/gdbusauthmechanismsha1.c:461
 #, c-format
 msgid "Didn’t find cookie with id %d in the keyring at “%s”"
 msgstr "Nenalezena cookie s id %d v klíčence na „%s“"
 
-#: gio/gdbusauthmechanismsha1.c:476
+#: gio/gdbusauthmechanismsha1.c:507
 #, c-format
 msgid "Error creating lock file “%s”: %s"
 msgstr "Chyba při vytváření zamykacího souboru „%s“: %s"
 
-#: gio/gdbusauthmechanismsha1.c:540
+#: gio/gdbusauthmechanismsha1.c:571
 #, c-format
 msgid "Error deleting stale lock file “%s”: %s"
 msgstr "Chyba při mazání zastaralého zamykacího souboru „%s“: %s"
 
-#: gio/gdbusauthmechanismsha1.c:579
+#: gio/gdbusauthmechanismsha1.c:610
 #, c-format
 msgid "Error closing (unlinked) lock file “%s”: %s"
 msgstr "Chyba při zavírání (neodkazovaného) zamykacího souboru „%s“: %s"
 
-#: gio/gdbusauthmechanismsha1.c:590
+#: gio/gdbusauthmechanismsha1.c:621
 #, c-format
 msgid "Error unlinking lock file “%s”: %s"
 msgstr "Chyba mazámí zamykacího souboru „%s“: %s"
 
-#: gio/gdbusauthmechanismsha1.c:667
+#: gio/gdbusauthmechanismsha1.c:698
 #, c-format
 msgid "Error opening keyring “%s” for writing: "
 msgstr "Chyba při otevírání klíčenky „%s“ k zápisu: "
 
-#: gio/gdbusauthmechanismsha1.c:865
+#: gio/gdbusauthmechanismsha1.c:892
 #, c-format
 msgid "(Additionally, releasing the lock for “%s” also failed: %s) "
 msgstr "(Navíc selhalo také uvolnění zámku pro „%s“: %s) "
@@ -668,12 +668,12 @@ msgstr ""
 "Chyba při nastavování vlastnosti „%s“: Očekáván typ „%s“, ale obdržen „%s“"
 
 #: gio/gdbusconnection.c:4453 gio/gdbusconnection.c:4661
-#: gio/gdbusconnection.c:6632
+#: gio/gdbusconnection.c:6657
 #, c-format
 msgid "No such interface “%s”"
 msgstr "Rozhraní „%s“ neexistuje"
 
-#: gio/gdbusconnection.c:4879 gio/gdbusconnection.c:7141
+#: gio/gdbusconnection.c:4879 gio/gdbusconnection.c:7166
 #, c-format
 msgid "No such interface “%s” on object at path %s"
 msgstr "Rozhraní „%s“na objektu na cestě %s neexistuje"
@@ -708,37 +708,37 @@ msgstr "Nelze nastavit vlastnost %s.%s"
 msgid "Method “%s” returned type “%s”, but expected “%s”"
 msgstr "Metoda „%s“ vrátila typ „%s“, ale očekáván byl „%s“"
 
-#: gio/gdbusconnection.c:6743
+#: gio/gdbusconnection.c:6768
 #, c-format
 msgid "Method “%s” on interface “%s” with signature “%s” does not exist"
 msgstr "Metoda „%s“ na rozhraní „%s“ s podpisem „%s“ neexistuje"
 
-#: gio/gdbusconnection.c:6864
+#: gio/gdbusconnection.c:6889
 #, c-format
 msgid "A subtree is already exported for %s"
 msgstr "Podstrom je již exportován pro %s"
 
-#: gio/gdbusmessage.c:1255
+#: gio/gdbusmessage.c:1266
 msgid "type is INVALID"
 msgstr "typ je INVALID"
 
-#: gio/gdbusmessage.c:1266
+#: gio/gdbusmessage.c:1277
 msgid "METHOD_CALL message: PATH or MEMBER header field is missing"
 msgstr "Zpráva METHOD_CALL: pole se záhlavím PATH nebo MEMBER schází"
 
-#: gio/gdbusmessage.c:1277
+#: gio/gdbusmessage.c:1288
 msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing"
 msgstr "Zpráva METHOD_RETURN: pole se záhlavím REPLY_SERIAL schází"
 
-#: gio/gdbusmessage.c:1289
+#: gio/gdbusmessage.c:1300
 msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing"
 msgstr "Zpráva ERROR: pole se záhlavím REPLY_SERIAL nebo ERROR_NAME schází"
 
-#: gio/gdbusmessage.c:1302
+#: gio/gdbusmessage.c:1313
 msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing"
 msgstr "Zpráva SIGNAL: pole se záhlavím PATH, INTERFACE nebo MEMBER schází"
 
-#: gio/gdbusmessage.c:1310
+#: gio/gdbusmessage.c:1321
 msgid ""
 "SIGNAL message: The PATH header field is using the reserved value /org/"
 "freedesktop/DBus/Local"
@@ -746,7 +746,7 @@ msgstr ""
 "Zpráva SIGNAL: pole se záhlavím PATH používá rezervovanou hodnotu /org/"
 "freedesktop/DBus/Local"
 
-#: gio/gdbusmessage.c:1318
+#: gio/gdbusmessage.c:1329
 msgid ""
 "SIGNAL message: The INTERFACE header field is using the reserved value org."
 "freedesktop.DBus.Local"
@@ -754,7 +754,7 @@ msgstr ""
 "Zpráva SIGNAL: pole se záhlavím INTERFACE používá rezervovanou hodnotu org."
 "freedesktop.DBus.Local"
 
-#: gio/gdbusmessage.c:1366 gio/gdbusmessage.c:1426
+#: gio/gdbusmessage.c:1377 gio/gdbusmessage.c:1437
 #, c-format
 msgid "Wanted to read %lu byte but only got %lu"
 msgid_plural "Wanted to read %lu bytes but only got %lu"
@@ -762,12 +762,12 @@ msgstr[0] "Zamýšlel se přečíst %lu bajt, ale obdrženo %lu"
 msgstr[1] "Zamýšlely se přečíst %lu bajty, ale obdrženo %lu"
 msgstr[2] "Zamýšlelo se přečíst %lu bajtů, ale obdrženo %lu"
 
-#: gio/gdbusmessage.c:1380
+#: gio/gdbusmessage.c:1391
 #, c-format
 msgid "Expected NUL byte after the string “%s” but found byte %d"
 msgstr "Očekáván bajt NULL za řetězcem „%s“, ale byl nalezen bajt %d"
 
-#: gio/gdbusmessage.c:1399
+#: gio/gdbusmessage.c:1410
 #, c-format
 msgid ""
 "Expected valid UTF-8 string but found invalid bytes at byte offset %d "
@@ -776,21 +776,21 @@ msgstr ""
 "Očekáván platný řetězec UTF-8, ale byly nalezeny neplatné bajty na pozici %d "
 "(délka řetězce je %d). Platný řetězec UTF-8 až do příslušného bodu byl „%s“"
 
-#: gio/gdbusmessage.c:1463 gio/gdbusmessage.c:1711 gio/gdbusmessage.c:1900
+#: gio/gdbusmessage.c:1474 gio/gdbusmessage.c:1722 gio/gdbusmessage.c:1911
 msgid "Value nested too deeply"
 msgstr "Hodnota je zanořená příliš hluboko"
 
-#: gio/gdbusmessage.c:1609
+#: gio/gdbusmessage.c:1620
 #, c-format
 msgid "Parsed value “%s” is not a valid D-Bus object path"
 msgstr "Analyzovaná hodnota „%s“ není platná cesta objektu D-Bus"
 
-#: gio/gdbusmessage.c:1631
+#: gio/gdbusmessage.c:1642
 #, c-format
 msgid "Parsed value “%s” is not a valid D-Bus signature"
 msgstr "Analyzovaná hodnota „%s“ není platný podpis D-Bus"
 
-#: gio/gdbusmessage.c:1678
+#: gio/gdbusmessage.c:1689
 #, c-format
 msgid ""
 "Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)."
@@ -803,7 +803,7 @@ msgstr[1] ""
 msgstr[2] ""
 "Zjištěno pole o délce %u bajtů. Maximální délka je 2<<26 bajtů (64 MiB)."
 
-#: gio/gdbusmessage.c:1698
+#: gio/gdbusmessage.c:1709
 #, c-format
 msgid ""
 "Encountered array of type “a%c”, expected to have a length a multiple of %u "
@@ -812,12 +812,12 @@ msgstr ""
 "Vyskytlo se pole typu „a%c“, které by mělo mít délku v násobku %u bajtů, ale "
 "skutečná délka je %u bajtů"
 
-#: gio/gdbusmessage.c:1884
+#: gio/gdbusmessage.c:1895
 #, c-format
 msgid "Parsed value “%s” for variant is not a valid D-Bus signature"
 msgstr "Analyzovaná hodnota „%s“ varianty není platným podpisem D-Bus"
 
-#: gio/gdbusmessage.c:1925
+#: gio/gdbusmessage.c:1936
 #, c-format
 msgid ""
 "Error deserializing GVariant with type string “%s” from the D-Bus wire format"
@@ -825,7 +825,7 @@ msgstr ""
 "Chyba při rušení serializace GVariant s řetězcem typu „%s“ z přenosového "
 "formátu D-Bus"
 
-#: gio/gdbusmessage.c:2110
+#: gio/gdbusmessage.c:2121
 #, c-format
 msgid ""
 "Invalid endianness value. Expected 0x6c (“l”) or 0x42 (“B”) but found value "
@@ -834,27 +834,27 @@ msgstr ""
 "Neplatná hodnota endianity. Očekávána 0x6c („l“) nebo 0x42 („B“), ale "
 "nalezena hodnota 0x%02x"
 
-#: gio/gdbusmessage.c:2123
+#: gio/gdbusmessage.c:2134
 #, c-format
 msgid "Invalid major protocol version. Expected 1 but found %d"
 msgstr "Neplatná verze hlavního protokolu. Očekávána 1, ale nalezena %d"
 
-#: gio/gdbusmessage.c:2177 gio/gdbusmessage.c:2773
+#: gio/gdbusmessage.c:2188 gio/gdbusmessage.c:2784
 msgid "Signature header found but is not of type signature"
 msgstr "Byla nalezena hlavička podpisu, ale není typu podpis"
 
-#: gio/gdbusmessage.c:2189
+#: gio/gdbusmessage.c:2200
 #, c-format
 msgid "Signature header with signature “%s” found but message body is empty"
 msgstr ""
 "Byla nalezena hlavička podpisu s podpisem „%s“, ale tělo zprávy je prázdné"
 
-#: gio/gdbusmessage.c:2204
+#: gio/gdbusmessage.c:2215
 #, c-format
 msgid "Parsed value “%s” is not a valid D-Bus signature (for body)"
 msgstr "Analyzovaná hodnota „%s“ není platným podpisem D-Bus (pro tělo)"
 
-#: gio/gdbusmessage.c:2236
+#: gio/gdbusmessage.c:2247
 #, c-format
 msgid "No signature header in message but the message body is %u byte"
 msgid_plural "No signature header in message but the message body is %u bytes"
@@ -862,11 +862,11 @@ msgstr[0] "Ve zprávě není hlavička s podpisem, ale tělo zprávy má %u bajt
 msgstr[1] "Ve zprávě není hlavička s podpisem, ale tělo zprávy má %u bajty"
 msgstr[2] "Ve zprávě není hlavička s podpisem, ale tělo zprávy má %u bajtů"
 
-#: gio/gdbusmessage.c:2246
+#: gio/gdbusmessage.c:2257
 msgid "Cannot deserialize message: "
 msgstr "Nelze zrušit serializaci zprávy: "
 
-#: gio/gdbusmessage.c:2590
+#: gio/gdbusmessage.c:2601
 #, c-format
 msgid ""
 "Error serializing GVariant with type string “%s” to the D-Bus wire format"
@@ -874,59 +874,59 @@ msgstr ""
 "Chyba při serializaci GVariant s řetězcem typu „%s“ do přenosového formátu D-"
 "Bus"
 
-#: gio/gdbusmessage.c:2727
+#: gio/gdbusmessage.c:2738
 #, c-format
 msgid ""
 "Number of file descriptors in message (%d) differs from header field (%d)"
 msgstr ""
 "Počet popisovačů souborů ve zprávě (%d) se liší od pole v hlavičce (%d)"
 
-#: gio/gdbusmessage.c:2735
+#: gio/gdbusmessage.c:2746
 msgid "Cannot serialize message: "
 msgstr "Nelze serializovat zprávu: "
 
-#: gio/gdbusmessage.c:2788
+#: gio/gdbusmessage.c:2799
 #, c-format
 msgid "Message body has signature “%s” but there is no signature header"
 msgstr "Tělo zprávy má podpis „%s“, ale záhlaví s podpisem neexistuje"
 
-#: gio/gdbusmessage.c:2798
+#: gio/gdbusmessage.c:2809
 #, c-format
 msgid ""
 "Message body has type signature “%s” but signature in the header field is "
 "“%s”"
 msgstr "Tělo zprávy má podpis typu „%s“, ale podpis v poli se záhlavím je „%s“"
 
-#: gio/gdbusmessage.c:2814
+#: gio/gdbusmessage.c:2825
 #, c-format
 msgid "Message body is empty but signature in the header field is “(%s)”"
 msgstr "Tělo zprávy je prázdné, ale podpis v poli se záhlavím je „(%s)“"
 
-#: gio/gdbusmessage.c:3367
+#: gio/gdbusmessage.c:3378
 #, c-format
 msgid "Error return with body of type “%s”"
 msgstr "Navrácena chyba s tělem typu „%s“"
 
-#: gio/gdbusmessage.c:3375
+#: gio/gdbusmessage.c:3386
 msgid "Error return with empty body"
 msgstr "Navrácena chyba s prázdným tělem"
 
-#: gio/gdbusprivate.c:2244
+#: gio/gdbusprivate.c:2247
 #, c-format
 msgid "(Type any character to close this window)\n"
 msgstr "(Zmáčknutím libovolného znaku okno zavřete)\n"
 
-#: gio/gdbusprivate.c:2418
+#: gio/gdbusprivate.c:2421
 #, c-format
 msgid "Session dbus not running, and autolaunch failed"
 msgstr "Služba dbus sezení neběží a automatické spuštění selhalo"
 
-#: gio/gdbusprivate.c:2441
+#: gio/gdbusprivate.c:2444
 #, c-format
 msgid "Unable to get Hardware profile: %s"
 msgstr "Nelze získat profil hardwaru: %s"
 
-#: gio/gdbusprivate.c:2486
+#: gio/gdbusprivate.c:2489
 msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: "
 msgstr "Nelze načíst /var/lib/dbus/machine-id nebo /etc/machine-id: "
 
@@ -972,7 +972,7 @@ msgstr "Řetězec „%s“ není platné D-Bus GUID"
 msgid "Cannot listen on unsupported transport “%s”"
 msgstr "Nelze naslouchat na nepodporovaném přenosu „%s“"
 
-#: gio/gdbus-tool.c:107
+#: gio/gdbus-tool.c:111
 #, c-format
 msgid ""
 "Commands:\n"
@@ -995,60 +995,60 @@ msgstr ""
 "\n"
 "Nápovědu k jednotlivým příkazům získáte použitím „%s PŘÍKAZ --help“.\n"
 
-#: gio/gdbus-tool.c:197 gio/gdbus-tool.c:264 gio/gdbus-tool.c:336
-#: gio/gdbus-tool.c:360 gio/gdbus-tool.c:850 gio/gdbus-tool.c:1187
-#: gio/gdbus-tool.c:1672
+#: gio/gdbus-tool.c:201 gio/gdbus-tool.c:268 gio/gdbus-tool.c:340
+#: gio/gdbus-tool.c:364 gio/gdbus-tool.c:854 gio/gdbus-tool.c:1231
+#: gio/gdbus-tool.c:1719
 #, c-format
 msgid "Error: %s\n"
 msgstr "Chyba: %s\n"
 
-#: gio/gdbus-tool.c:208 gio/gdbus-tool.c:277 gio/gdbus-tool.c:1688
+#: gio/gdbus-tool.c:212 gio/gdbus-tool.c:281 gio/gdbus-tool.c:1735
 #, c-format
 msgid "Error parsing introspection XML: %s\n"
 msgstr "Chyba při analýze introspection XML: %s\n"
 
-#: gio/gdbus-tool.c:246
+#: gio/gdbus-tool.c:250
 #, c-format
 msgid "Error: %s is not a valid name\n"
 msgstr "Chyba: %s není platným názvem\n"
 
-#: gio/gdbus-tool.c:394
+#: gio/gdbus-tool.c:398
 msgid "Connect to the system bus"
 msgstr "Připojit k systémové sběrnici"
 
-#: gio/gdbus-tool.c:395
+#: gio/gdbus-tool.c:399
 msgid "Connect to the session bus"
 msgstr "Připojit ke sběrnici sezení"
 
-#: gio/gdbus-tool.c:396
+#: gio/gdbus-tool.c:400
 msgid "Connect to given D-Bus address"
 msgstr "Připojit k dané adrese D-Bus"
 
-#: gio/gdbus-tool.c:406
+#: gio/gdbus-tool.c:410
 msgid "Connection Endpoint Options:"
 msgstr "Volby koncového bodu spojení:"
 
-#: gio/gdbus-tool.c:407
+#: gio/gdbus-tool.c:411
 msgid "Options specifying the connection endpoint"
 msgstr "Volby určující koncový bod spojení"
 
-#: gio/gdbus-tool.c:430
+#: gio/gdbus-tool.c:434
 #, c-format
 msgid "No connection endpoint specified"
 msgstr "Neurčen žádný koncový bod spojení"
 
-#: gio/gdbus-tool.c:440
+#: gio/gdbus-tool.c:444
 #, c-format
 msgid "Multiple connection endpoints specified"
 msgstr "Určeno více koncových bodů spojení"
 
-#: gio/gdbus-tool.c:513
+#: gio/gdbus-tool.c:517
 #, c-format
 msgid ""
 "Warning: According to introspection data, interface “%s” does not exist\n"
 msgstr "Varování: Podle introspektivních dat rozhraní „%s“ neexistuje\n"
 
-#: gio/gdbus-tool.c:522
+#: gio/gdbus-tool.c:526
 #, c-format
 msgid ""
 "Warning: According to introspection data, method “%s” does not exist on "
@@ -1057,163 +1057,168 @@ msgstr ""
 "Varování: Podle introspektivních dat metoda „%s“ neexistuje na rozhraní "
 "„%s“\n"
 
-#: gio/gdbus-tool.c:584
+#: gio/gdbus-tool.c:588
 msgid "Optional destination for signal (unique name)"
 msgstr "Volitelný cíl signálu (jedinečný název)"
 
-#: gio/gdbus-tool.c:585
+#: gio/gdbus-tool.c:589
 msgid "Object path to emit signal on"
 msgstr "Cesta objektu, na kterou se má vyslat signál"
 
-#: gio/gdbus-tool.c:586
+#: gio/gdbus-tool.c:590
 msgid "Signal and interface name"
 msgstr "Název signálu a rozhraní"
 
-#: gio/gdbus-tool.c:619
+#: gio/gdbus-tool.c:623
 msgid "Emit a signal."
 msgstr "Vyslat signál."
 
-#: gio/gdbus-tool.c:674 gio/gdbus-tool.c:981 gio/gdbus-tool.c:1775
-#: gio/gdbus-tool.c:2007 gio/gdbus-tool.c:2227
+#: gio/gdbus-tool.c:678 gio/gdbus-tool.c:992 gio/gdbus-tool.c:1822
+#: gio/gdbus-tool.c:2054 gio/gdbus-tool.c:2274
 #, c-format
 msgid "Error connecting: %s\n"
 msgstr "Chyba při spojení: %s\n"
 
-#: gio/gdbus-tool.c:694
+#: gio/gdbus-tool.c:698
 #, c-format
 msgid "Error: %s is not a valid unique bus name.\n"
 msgstr "Chyba: %s není platným jedinečným názvem sběrnice.\n"
 
-#: gio/gdbus-tool.c:713 gio/gdbus-tool.c:1024 gio/gdbus-tool.c:1818
+#: gio/gdbus-tool.c:717 gio/gdbus-tool.c:1035 gio/gdbus-tool.c:1865
 msgid "Error: Object path is not specified\n"
 msgstr "Chyba: Není určena žádná cesta k objektu\n"
 
-#: gio/gdbus-tool.c:736 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1838
-#: gio/gdbus-tool.c:2078
+#: gio/gdbus-tool.c:740 gio/gdbus-tool.c:1055 gio/gdbus-tool.c:1885
+#: gio/gdbus-tool.c:2125
 #, c-format
 msgid "Error: %s is not a valid object path\n"
 msgstr "Chyba: %s není platnou cestou objektu\n"
 
-#: gio/gdbus-tool.c:756
+#: gio/gdbus-tool.c:760
 msgid "Error: Signal name is not specified\n"
 msgstr "Chyba: Není určen název signálu\n"
 
-#: gio/gdbus-tool.c:770
+#: gio/gdbus-tool.c:774
 #, c-format
 msgid "Error: Signal name “%s” is invalid\n"
 msgstr "Chyba: Název signálu „%s“ je neplatný\n"
 
-#: gio/gdbus-tool.c:782
+#: gio/gdbus-tool.c:786
 #, c-format
 msgid "Error: %s is not a valid interface name\n"
 msgstr "Chyba: %s není platným názvem rozhraní\n"
 
-#: gio/gdbus-tool.c:788
+#: gio/gdbus-tool.c:792
 #, c-format
 msgid "Error: %s is not a valid member name\n"
 msgstr "Chyba: %s není platným názvem členu\n"
 
 #. Use the original non-"parse-me-harder" error
-#: gio/gdbus-tool.c:825 gio/gdbus-tool.c:1156
+#: gio/gdbus-tool.c:829 gio/gdbus-tool.c:1167
 #, c-format
 msgid "Error parsing parameter %d: %s\n"
 msgstr "Chyba při analyzování parametru %d: %s\n"
 
-#: gio/gdbus-tool.c:857
+#: gio/gdbus-tool.c:861
 #, c-format
 msgid "Error flushing connection: %s\n"
 msgstr "Chyba při vyprazdňování spojení: %s\n"
 
-#: gio/gdbus-tool.c:884
+#: gio/gdbus-tool.c:888
 msgid "Destination name to invoke method on"
 msgstr "Název cíle, u kterého se má spustit metoda"
 
-#: gio/gdbus-tool.c:885
+#: gio/gdbus-tool.c:889
 msgid "Object path to invoke method on"
 msgstr "Cesta objektu, u kterého se má spustit metoda"
 
-#: gio/gdbus-tool.c:886
+#: gio/gdbus-tool.c:890
 msgid "Method and interface name"
 msgstr "Název metody a rozhraní"
 
-#: gio/gdbus-tool.c:887
+#: gio/gdbus-tool.c:891
 msgid "Timeout in seconds"
 msgstr "Časový limit v sekundách"
 
-#: gio/gdbus-tool.c:926
+#: gio/gdbus-tool.c:937
 msgid "Invoke a method on a remote object."
 msgstr "Spustit metodu na vzdáleném objektu."
 
-#: gio/gdbus-tool.c:998 gio/gdbus-tool.c:1792 gio/gdbus-tool.c:2032
+#: gio/gdbus-tool.c:1009 gio/gdbus-tool.c:1839 gio/gdbus-tool.c:2079
 msgid "Error: Destination is not specified\n"
 msgstr "Chyba: Není určen žádný cíl\n"
 
-#: gio/gdbus-tool.c:1009 gio/gdbus-tool.c:1809 gio/gdbus-tool.c:2043
+#: gio/gdbus-tool.c:1020 gio/gdbus-tool.c:1856 gio/gdbus-tool.c:2090
 #, c-format
 msgid "Error: %s is not a valid bus name\n"
 msgstr "Chyba: %s není platným názvem sběrnice\n"
 
-#: gio/gdbus-tool.c:1059
+#: gio/gdbus-tool.c:1070
 msgid "Error: Method name is not specified\n"
 msgstr "Chyba: Není určen název metody\n"
 
-#: gio/gdbus-tool.c:1070
+#: gio/gdbus-tool.c:1081
 #, c-format
 msgid "Error: Method name “%s” is invalid\n"
 msgstr "Chyba: Název metody „%s“ je neplatný\n"
 
-#: gio/gdbus-tool.c:1148
+#: gio/gdbus-tool.c:1159
 #, c-format
 msgid "Error parsing parameter %d of type “%s”: %s\n"
 msgstr "Chyba při analyzování parametru %d typu „%s“: %s\n"
 
-#: gio/gdbus-tool.c:1634
+#: gio/gdbus-tool.c:1185
+#, c-format
+msgid "Error adding handle %d: %s\n"
+msgstr "Chyba při přidávání obsluhy %d: %s\n"
+
+#: gio/gdbus-tool.c:1681
 msgid "Destination name to introspect"
 msgstr "Název cíle, u kterého provést introspection"
 
-#: gio/gdbus-tool.c:1635
+#: gio/gdbus-tool.c:1682
 msgid "Object path to introspect"
 msgstr "Cesta objektu, u které provést introspection"
 
-#: gio/gdbus-tool.c:1636
+#: gio/gdbus-tool.c:1683
 msgid "Print XML"
 msgstr "Vypsat XML"
 
-#: gio/gdbus-tool.c:1637
+#: gio/gdbus-tool.c:1684
 msgid "Introspect children"
 msgstr "Provést introspection potomka"
 
-#: gio/gdbus-tool.c:1638
+#: gio/gdbus-tool.c:1685
 msgid "Only print properties"
 msgstr "Vypsat pouze vlastnosti"
 
-#: gio/gdbus-tool.c:1727
+#: gio/gdbus-tool.c:1774
 msgid "Introspect a remote object."
 msgstr "Provést introspection vzdáleného objektu."
 
-#: gio/gdbus-tool.c:1933
+#: gio/gdbus-tool.c:1980
 msgid "Destination name to monitor"
 msgstr "Název cíle určený ke sledování"
 
-#: gio/gdbus-tool.c:1934
+#: gio/gdbus-tool.c:1981
 msgid "Object path to monitor"
 msgstr "Cesta objektu určená ke sledování"
 
-#: gio/gdbus-tool.c:1959
+#: gio/gdbus-tool.c:2006
 msgid "Monitor a remote object."
 msgstr "Sledovat vzdálený objekt."
 
-#: gio/gdbus-tool.c:2017
+#: gio/gdbus-tool.c:2064
 msgid "Error: can’t monitor a non-message-bus connection\n"
 msgstr "Chyba: nelze monitorovat připojení na sběrnici bez zpráv\n"
 
-#: gio/gdbus-tool.c:2141
+#: gio/gdbus-tool.c:2188
 msgid "Service to activate before waiting for the other one (well-known name)"
 msgstr ""
 "Služba, která se má aktivovat před čekáním na jinou službu (oficiálně známý "
 "název)"
 
-#: gio/gdbus-tool.c:2144
+#: gio/gdbus-tool.c:2191
 msgid ""
 "Timeout to wait for before exiting with an error (seconds); 0 for no timeout "
 "(default)"
@@ -1221,27 +1226,27 @@ msgstr ""
 "Časové omezení čekaní, po kterém se skončí s chybou (v sekundách). 0 znamená "
 "bez omezení (výchozí)"
 
-#: gio/gdbus-tool.c:2192
+#: gio/gdbus-tool.c:2239
 msgid "[OPTION…] BUS-NAME"
 msgstr "[PŘEPÍNAČ…] NÁZEV-SBĚRNICE"
 
-#: gio/gdbus-tool.c:2193
+#: gio/gdbus-tool.c:2240
 msgid "Wait for a bus name to appear."
 msgstr "Čekat, než se objeví název sběrnice."
 
-#: gio/gdbus-tool.c:2269
+#: gio/gdbus-tool.c:2316
 msgid "Error: A service to activate for must be specified.\n"
 msgstr "Chyba: Musí být určena služba, pro kterou provádíte aktivaci.\n"
 
-#: gio/gdbus-tool.c:2274
+#: gio/gdbus-tool.c:2321
 msgid "Error: A service to wait for must be specified.\n"
 msgstr "Chyba: Musí být určena služba, na kterou čekáte.\n"
 
-#: gio/gdbus-tool.c:2279
+#: gio/gdbus-tool.c:2326
 msgid "Error: Too many arguments.\n"
 msgstr "Chyba: Příliš mnoho argumentů.\n"
 
-#: gio/gdbus-tool.c:2287 gio/gdbus-tool.c:2294
+#: gio/gdbus-tool.c:2334 gio/gdbus-tool.c:2341
 #, c-format
 msgid "Error: %s is not a valid well-known bus name.\n"
 msgstr "Chyba: %s není platným oficiálně známým názvem sběrnice.\n"
@@ -1344,11 +1349,11 @@ msgstr "Očekáváno GEmblem u GEmblemedIcon"
 
 #: gio/gfile.c:1044 gio/gfile.c:1282 gio/gfile.c:1420 gio/gfile.c:1658
 #: gio/gfile.c:1713 gio/gfile.c:1771 gio/gfile.c:1855 gio/gfile.c:1912
-#: gio/gfile.c:1976 gio/gfile.c:2031 gio/gfile.c:3722 gio/gfile.c:3777
-#: gio/gfile.c:4070 gio/gfile.c:4540 gio/gfile.c:4951 gio/gfile.c:5036
-#: gio/gfile.c:5126 gio/gfile.c:5223 gio/gfile.c:5310 gio/gfile.c:5411
-#: gio/gfile.c:8121 gio/gfile.c:8211 gio/gfile.c:8295
-#: gio/win32/gwinhttpfile.c:437
+#: gio/gfile.c:1976 gio/gfile.c:2031 gio/gfile.c:3745 gio/gfile.c:3800
+#: gio/gfile.c:4093 gio/gfile.c:4563 gio/gfile.c:4974 gio/gfile.c:5059
+#: gio/gfile.c:5149 gio/gfile.c:5246 gio/gfile.c:5333 gio/gfile.c:5434
+#: gio/gfile.c:8144 gio/gfile.c:8234 gio/gfile.c:8318
+#: gio/win32/gwinhttpfile.c:453
 msgid "Operation not supported"
 msgstr "Operace není podporována"
 
@@ -1377,53 +1382,53 @@ msgid "Can’t recursively copy directory"
 msgstr "Složku nelze kopírovat rekurzivně"
 
 # For splice(), see http://en.wikipedia.org/w/index.php?title=Splice_(system_call)&oldid=334434835
-#: gio/gfile.c:2952
+#: gio/gfile.c:2978
 msgid "Splice not supported"
 msgstr "splice() není podporováno"
 
-#: gio/gfile.c:2956 gio/gfile.c:3001
+#: gio/gfile.c:2982 gio/gfile.c:3027
 #, c-format
 msgid "Error splicing file: %s"
 msgstr "Chyba při spojování souboru: %s"
 
-#: gio/gfile.c:3117
+#: gio/gfile.c:3143
 msgid "Copy (reflink/clone) between mounts is not supported"
 msgstr "Kopírování (reflink/clone) mezi připojeními není podporováno"
 
-#: gio/gfile.c:3121
+#: gio/gfile.c:3147
 msgid "Copy (reflink/clone) is not supported or invalid"
 msgstr "Kopírování (reflink/clone) není podporováno nebo je neplatné"
 
-#: gio/gfile.c:3126
+#: gio/gfile.c:3152
 msgid "Copy (reflink/clone) is not supported or didn’t work"
 msgstr "Kopírování (reflink/clone) není podporováno nebo neproběhlo správně"
 
-#: gio/gfile.c:3190
+#: gio/gfile.c:3217
 msgid "Can’t copy special file"
 msgstr "Nelze kopírovat zvláštní soubor"
 
-#: gio/gfile.c:4003
+#: gio/gfile.c:4026
 msgid "Invalid symlink value given"
 msgstr "Zadaný symbolický odkaz je neplatný"
 
-#: gio/gfile.c:4013 glib/gfileutils.c:2349
+#: gio/gfile.c:4036 glib/gfileutils.c:2349
 msgid "Symbolic links not supported"
 msgstr "Symbolické odkazy nejsou podporovány"
 
-#: gio/gfile.c:4181
+#: gio/gfile.c:4204
 msgid "Trash not supported"
 msgstr "Zahozené není podporováno"
 
-#: gio/gfile.c:4293
+#: gio/gfile.c:4316
 #, c-format
 msgid "File names cannot contain “%c”"
 msgstr "Názvy souborů nemohou obsahovat „%c“"
 
-#: gio/gfile.c:6774 gio/gvolume.c:364
+#: gio/gfile.c:6797 gio/gvolume.c:364
 msgid "volume doesn’t implement mount"
 msgstr "svazek neumí připojení"
 
-#: gio/gfile.c:6888 gio/gfile.c:6936
+#: gio/gfile.c:6911 gio/gfile.c:6959
 msgid "No application is registered as handling this file"
 msgstr "Žádná aplikace není zaregistrována k obsluze tohoto souboru"
 
@@ -1676,7 +1681,7 @@ msgstr "Chyba při zápisu do standardního výstupu"
 #: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43
 #: gio/gio-tool-monitor.c:203 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70
 #: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89
-#: gio/gio-tool-trash.c:81 gio/gio-tool-tree.c:239
+#: gio/gio-tool-trash.c:90 gio/gio-tool-tree.c:239
 msgid "LOCATION"
 msgstr "UMÍSTĚNÍ"
 
@@ -1696,7 +1701,7 @@ msgstr ""
 
 #: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:364 gio/gio-tool-mkdir.c:76
 #: gio/gio-tool-monitor.c:228 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96
-#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:136
+#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:145
 msgid "No locations given"
 msgstr "Nebylo zadáno žádné umístění"
 
@@ -2241,7 +2246,7 @@ msgstr "Neplatný typ atributu „%s“"
 msgid "Empty the trash"
 msgstr "Vysypat koš"
 
-#: gio/gio-tool-trash.c:86
+#: gio/gio-tool-trash.c:95
 msgid "Move files or directories to the trash."
 msgstr "Přesunout soubory nebo složky do koše."
 
@@ -2869,7 +2874,7 @@ msgid "No schema files found: removed existing output file."
 msgstr ""
 "Žádné soubory schémat nenalezeny: odstraněn existující výstupní soubor."
 
-#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:420
+#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436
 #, c-format
 msgid "Invalid filename %s"
 msgstr "Neplatný název souboru %s"
@@ -3023,116 +3028,116 @@ msgstr "Neplatný název rozšířeného atributu"
 msgid "Error setting extended attribute “%s”: %s"
 msgstr "Chyba při nastavování rozšířeného atributu „%s“: %s"
 
-#: gio/glocalfileinfo.c:1663
+#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191
 msgid " (invalid encoding)"
 msgstr " (neplatné kódování)"
 
-#: gio/glocalfileinfo.c:1822 gio/glocalfileoutputstream.c:915
+#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:915
 #, c-format
 msgid "Error when getting information for file “%s”: %s"
 msgstr "Chyba při získávání informací pro soubor „%s“: %s"
 
-#: gio/glocalfileinfo.c:2088
+#: gio/glocalfileinfo.c:2134
 #, c-format
 msgid "Error when getting information for file descriptor: %s"
 msgstr "Chyba při získávání informací pro popisovače souboru: %s"
 
-#: gio/glocalfileinfo.c:2133
+#: gio/glocalfileinfo.c:2179
 msgid "Invalid attribute type (uint32 expected)"
 msgstr "Neplatný typ atributu (očekáván uint32)"
 
-#: gio/glocalfileinfo.c:2151
+#: gio/glocalfileinfo.c:2197
 msgid "Invalid attribute type (uint64 expected)"
 msgstr "Neplatný typ atributu (očekáván uint64)"
 
-#: gio/glocalfileinfo.c:2170 gio/glocalfileinfo.c:2189
+#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235
 msgid "Invalid attribute type (byte string expected)"
 msgstr "Neplatný typ atributu (očekáván bajtový řetězec)"
 
-#: gio/glocalfileinfo.c:2236
+#: gio/glocalfileinfo.c:2282
 msgid "Cannot set permissions on symlinks"
 msgstr "Nelze nastavit oprávnění na symbolických odkazech"
 
-#: gio/glocalfileinfo.c:2252
+#: gio/glocalfileinfo.c:2298
 #, c-format
 msgid "Error setting permissions: %s"
 msgstr "Chyba při nastavování oprávnění: %s"
 
-#: gio/glocalfileinfo.c:2303
+#: gio/glocalfileinfo.c:2349
 #, c-format
 msgid "Error setting owner: %s"
 msgstr "Chyba při nastavování vlastníka: %s"
 
-#: gio/glocalfileinfo.c:2326
+#: gio/glocalfileinfo.c:2372
 msgid "symlink must be non-NULL"
 msgstr "symbolický odkaz nesmí být prázdný"
 
-#: gio/glocalfileinfo.c:2336 gio/glocalfileinfo.c:2355
-#: gio/glocalfileinfo.c:2366
+#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401
+#: gio/glocalfileinfo.c:2412
 #, c-format
 msgid "Error setting symlink: %s"
 msgstr "Chyba při nastavování symbolického odkazu: %s"
 
-#: gio/glocalfileinfo.c:2345
+#: gio/glocalfileinfo.c:2391
 msgid "Error setting symlink: file is not a symlink"
 msgstr ""
 "Chyba při nastavování symbolického odkazu: soubor není symbolickým odkazem"
 
-#: gio/glocalfileinfo.c:2417
+#: gio/glocalfileinfo.c:2463
 #, c-format
 msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative"
 msgstr "Dodatečné nanosekundy %d pro UNIXové časové razítko %lld jsou záporné."
 
-#: gio/glocalfileinfo.c:2426
+#: gio/glocalfileinfo.c:2472
 #, c-format
 msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second"
 msgstr ""
 "Dodatečné nanosekundy %d pro UNIXové časové razítko %lld dosáhly 1 sekundy."
 
-#: gio/glocalfileinfo.c:2436
+#: gio/glocalfileinfo.c:2482
 #, c-format
 msgid "UNIX timestamp %lld does not fit into 64 bits"
 msgstr "UNIXové časové razítko %lld se nevleze do 64 bitů."
 
-#: gio/glocalfileinfo.c:2447
+#: gio/glocalfileinfo.c:2493
 #, c-format
 msgid "UNIX timestamp %lld is outside of the range supported by Windows"
 msgstr "UNIXové časové razítko %lld je mimo rozsah podporovaný Windows."
 
-#: gio/glocalfileinfo.c:2511
+#: gio/glocalfileinfo.c:2557
 #, c-format
 msgid "File name “%s” cannot be converted to UTF-16"
 msgstr "Název souboru „%s“ se nezdařilo převést do UTF-16."
 
-#: gio/glocalfileinfo.c:2530
+#: gio/glocalfileinfo.c:2576
 #, c-format
 msgid "File “%s” cannot be opened: Windows Error %lu"
 msgstr "Soubor „%s“ se nezdařilo otevřít: chyba Windows %lu"
 
-#: gio/glocalfileinfo.c:2543
+#: gio/glocalfileinfo.c:2589
 #, c-format
 msgid "Error setting modification or access time for file “%s”: %lu"
 msgstr "Chyba při nastavování času změny nebo přístupu u souboru „%s“: %lu"
 
-#: gio/glocalfileinfo.c:2644
+#: gio/glocalfileinfo.c:2690
 #, c-format
 msgid "Error setting modification or access time: %s"
 msgstr "Chyba při nastavování času změny nebo přístupu: %s"
 
-#: gio/glocalfileinfo.c:2667
+#: gio/glocalfileinfo.c:2713
 msgid "SELinux context must be non-NULL"
 msgstr "Kontext SELinux nesmí být prázdný."
 
-#: gio/glocalfileinfo.c:2682
+#: gio/glocalfileinfo.c:2728
 #, c-format
 msgid "Error setting SELinux context: %s"
 msgstr "Chyba při nastavování kontextu SELinux: %s"
 
-#: gio/glocalfileinfo.c:2689
+#: gio/glocalfileinfo.c:2735
 msgid "SELinux is not enabled on this system"
 msgstr "V tomto systému není SELinux povolen"
 
-#: gio/glocalfileinfo.c:2781
+#: gio/glocalfileinfo.c:2827
 #, c-format
 msgid "Setting attribute %s not supported"
 msgstr "Nastavení atributu %s není podporováno"
@@ -3900,30 +3905,26 @@ msgstr "Nelze číst pověření k soketu: %s"
 msgid "g_socket_get_credentials not implemented for this OS"
 msgstr "g_socket_get_credentials není u tohoto OS implementováno"
 
-#: gio/gsocketclient.c:182
+#: gio/gsocketclient.c:191
 #, c-format
 msgid "Could not connect to proxy server %s: "
 msgstr "Nelze se připojit k serveru proxy %s: "
 
-#: gio/gsocketclient.c:196
+#: gio/gsocketclient.c:205
 #, c-format
 msgid "Could not connect to %s: "
 msgstr "Nelze se připojit k %s: "
 
-#: gio/gsocketclient.c:198
+#: gio/gsocketclient.c:207
 msgid "Could not connect: "
 msgstr "Nelze se připojit: "
 
-#: gio/gsocketclient.c:1037 gio/gsocketclient.c:1866
-msgid "Unknown error on connect"
-msgstr "Neznámá chyba při spojení"
-
-#: gio/gsocketclient.c:1091 gio/gsocketclient.c:1668
+#: gio/gsocketclient.c:1162 gio/gsocketclient.c:1749
 msgid "Proxying over a non-TCP connection is not supported."
 msgstr ""
 "Není podporován pokus o proxy přes spojení, které není založeno na TCP."
 
-#: gio/gsocketclient.c:1120 gio/gsocketclient.c:1698
+#: gio/gsocketclient.c:1194 gio/gsocketclient.c:1778
 #, c-format
 msgid "Proxy protocol “%s” is not supported."
 msgstr "Protokol proxy „%s“ není podporován."
@@ -4053,25 +4054,29 @@ msgstr "Dočasně není možné vyřešit „%s“"
 msgid "Error resolving “%s”"
 msgstr "Chyba při řešení „%s“"
 
-#: gio/gtlscertificate.c:243
+#: gio/gtlscertificate.c:298
 msgid "No PEM-encoded private key found"
-msgstr "Nenalezen žádný soukromý klíč kódovaný jako PEM"
+msgstr "Nebyl nalezen žádný soukromý klíč kódovaný jako PEM."
 
-#: gio/gtlscertificate.c:253
+#: gio/gtlscertificate.c:308
 msgid "Cannot decrypt PEM-encoded private key"
 msgstr "Nelze dešifrovat soukromý klíč kódovaný jako PEM"
 
-#: gio/gtlscertificate.c:264
+#: gio/gtlscertificate.c:319
 msgid "Could not parse PEM-encoded private key"
-msgstr "Nelze analyzovat soukromý klíč kódovaný jako PEM"
+msgstr "Nezdařilo se analyzovat soukromý klíč kódovaný jako PEM."
 
-#: gio/gtlscertificate.c:291
+#: gio/gtlscertificate.c:346
 msgid "No PEM-encoded certificate found"
-msgstr "Nenalezen žádný certifikát kódovaný jako PEM"
+msgstr "Nebyl nalezen žádný certifikát kódovaný jako PEM."
 
-#: gio/gtlscertificate.c:300
+#: gio/gtlscertificate.c:355
 msgid "Could not parse PEM-encoded certificate"
-msgstr "Nelze analyzovat certifikát kódovaný jako PEM"
+msgstr "Nezdařilo se analyzovat certifikát kódovaný jako PEM."
+
+#: gio/gtlscertificate.c:710
+msgid "This GTlsBackend does not support creating PKCS #11 certificates"
+msgstr "Tento GTlsBackend nepodporuje vytváření certifikátů PKCS #11."
 
 #: gio/gtlspassword.c:111
 msgid ""
@@ -5712,47 +5717,47 @@ msgstr "Proces potomka byl zastaven signálem %ld"
 msgid "Child process exited abnormally"
 msgstr "Proces potomka neskončil normálně"
 
-#: glib/gspawn.c:1532 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358
+#: glib/gspawn.c:1540 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358
 #, c-format
 msgid "Failed to read from child pipe (%s)"
 msgstr "Selhalo čtení z roury potomka (%s)"
 
-#: glib/gspawn.c:1788
+#: glib/gspawn.c:1796
 #, c-format
 msgid "Failed to spawn child process “%s” (%s)"
 msgstr "Selhalo zplození procesu potomka „%s“ (%s)"
 
-#: glib/gspawn.c:1871
+#: glib/gspawn.c:1879
 #, c-format
 msgid "Failed to fork (%s)"
 msgstr "Selhalo rozvětvení procesu (%s)"
 
-#: glib/gspawn.c:2026 glib/gspawn-win32.c:381
+#: glib/gspawn.c:2034 glib/gspawn-win32.c:381
 #, c-format
 msgid "Failed to change to directory “%s” (%s)"
 msgstr "Selhal přechod do složky „%s“ (%s)"
 
-#: glib/gspawn.c:2036
+#: glib/gspawn.c:2044
 #, c-format
 msgid "Failed to execute child process “%s” (%s)"
 msgstr "Selhalo spuštění procesu potomka „%s“ (%s)"
 
-#: glib/gspawn.c:2046
+#: glib/gspawn.c:2054
 #, c-format
 msgid "Failed to redirect output or input of child process (%s)"
 msgstr "Selhalo přesměrování vstupu nebo výstupu procesu potomka (%s)"
 
-#: glib/gspawn.c:2055
+#: glib/gspawn.c:2063
 #, c-format
 msgid "Failed to fork child process (%s)"
 msgstr "Selhalo rozvětvení procesu potomka (%s)"
 
-#: glib/gspawn.c:2063
+#: glib/gspawn.c:2071
 #, c-format
 msgid "Unknown error executing child process “%s”"
 msgstr "Neznámá chyba při běhu procesu potomka „%s“"
 
-#: glib/gspawn.c:2087
+#: glib/gspawn.c:2095
 #, c-format
 msgid "Failed to read enough data from child pid pipe (%s)"
 msgstr "Nezdařilo se přečíst dostatek dat z roury pid potomka (%s)"
@@ -5835,41 +5840,41 @@ msgstr "Neplatný znak v adrese URI"
 msgid "Non-UTF-8 characters in URI"
 msgstr "Znak mimo standard UTF-8 v adrese URI"
 
-#: glib/guri.c:462
+#: glib/guri.c:538
 #, c-format
 msgid "Invalid IPv6 address ‘%.*s’ in URI"
 msgstr "Neplatná adresa IPv6 „%.*s“ v adrese URI"
 
-#: glib/guri.c:524
+#: glib/guri.c:593
 #, c-format
 msgid "Illegal encoded IP address ‘%.*s’ in URI"
 msgstr "Neplatná zakódovaná adresa IP „%.*s“ v adrese URI"
 
-#: glib/guri.c:558 glib/guri.c:570
+#: glib/guri.c:625 glib/guri.c:637
 #, c-format
 msgid "Could not parse port ‘%.*s’ in URI"
 msgstr "Nezdařilo se zpracovat port „%.*s“ v adrese URI"
 
-#: glib/guri.c:577
+#: glib/guri.c:644
 #, c-format
 msgid "Port ‘%.*s’ in URI is out of range"
 msgstr "Port „%.*s“ v adrese URI je mimo rozsah"
 
-#: glib/guri.c:1055 glib/guri.c:1119
+#: glib/guri.c:1124 glib/guri.c:1188
 #, c-format
 msgid "URI ‘%s’ is not an absolute URI"
 msgstr "Adresa URI „%s“ není absolutní"
 
-#: glib/guri.c:1061
+#: glib/guri.c:1130
 #, c-format
 msgid "URI ‘%s’ has no host component"
 msgstr "Adresa URI „%s“ nemá část s hostitelem"
 
-#: glib/guri.c:1263
+#: glib/guri.c:1335
 msgid "URI is not absolute, and no base URI was provided"
 msgstr "Adresa URI není absolutní a není poskytnuta žádná základní URI"
 
-#: glib/guri.c:2019
+#: glib/guri.c:2088
 msgid "Missing ‘=’ and parameter value"
 msgstr "Schází „=“ a hodnota parametru"
 
@@ -5891,150 +5896,150 @@ msgid "Character out of range for UTF-16"
 msgstr "Znak je mimo rozsah UTF-16"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2756
+#: glib/gutils.c:2759
 #, c-format
 msgid "%.1f kB"
 msgstr "%.1f kB"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2758
+#: glib/gutils.c:2761
 #, c-format
 msgid "%.1f MB"
 msgstr "%.1f MB"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2760
+#: glib/gutils.c:2763
 #, c-format
 msgid "%.1f GB"
 msgstr "%.1f GB"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2762
+#: glib/gutils.c:2765
 #, c-format
 msgid "%.1f TB"
 msgstr "%.1f TB"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2764
+#: glib/gutils.c:2767
 #, c-format
 msgid "%.1f PB"
 msgstr "%.1f PB"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2766
+#: glib/gutils.c:2769
 #, c-format
 msgid "%.1f EB"
 msgstr "%.1f EB"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2770
+#: glib/gutils.c:2773
 #, c-format
 msgid "%.1f KiB"
 msgstr "%.1f KiB"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2772
+#: glib/gutils.c:2775
 #, c-format
 msgid "%.1f MiB"
 msgstr "%.1f MiB"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2774
+#: glib/gutils.c:2777
 #, c-format
 msgid "%.1f GiB"
 msgstr "%.1f GiB"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2776
+#: glib/gutils.c:2779
 #, c-format
 msgid "%.1f TiB"
 msgstr "%.1f TiB"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2778
+#: glib/gutils.c:2781
 #, c-format
 msgid "%.1f PiB"
 msgstr "%.1f PiB"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2780
+#: glib/gutils.c:2783
 #, c-format
 msgid "%.1f EiB"
 msgstr "%.1f EiB"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2784
+#: glib/gutils.c:2787
 #, c-format
 msgid "%.1f kb"
 msgstr "%.1f kb"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2786
+#: glib/gutils.c:2789
 #, c-format
 msgid "%.1f Mb"
 msgstr "%.1f Mb"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2788
+#: glib/gutils.c:2791
 #, c-format
 msgid "%.1f Gb"
 msgstr "%.1f Gb"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2790
+#: glib/gutils.c:2793
 #, c-format
 msgid "%.1f Tb"
 msgstr "%.1f Tb"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2792
+#: glib/gutils.c:2795
 #, c-format
 msgid "%.1f Pb"
 msgstr "%.1f Pb"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2794
+#: glib/gutils.c:2797
 #, c-format
 msgid "%.1f Eb"
 msgstr "%.1f Eb"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2798
+#: glib/gutils.c:2801
 #, c-format
 msgid "%.1f Kib"
 msgstr "%.1f Kib"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2800
+#: glib/gutils.c:2803
 #, c-format
 msgid "%.1f Mib"
 msgstr "%.1f Mib"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2802
+#: glib/gutils.c:2805
 #, c-format
 msgid "%.1f Gib"
 msgstr "%.1f Gib"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2804
+#: glib/gutils.c:2807
 #, c-format
 msgid "%.1f Tib"
 msgstr "%.1f Tib"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2806
+#: glib/gutils.c:2809
 #, c-format
 msgid "%.1f Pib"
 msgstr "%.1f Pib"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2808
+#: glib/gutils.c:2811
 #, c-format
 msgid "%.1f Eib"
 msgstr "%.1f Eib"
 
-#: glib/gutils.c:2842 glib/gutils.c:2959
+#: glib/gutils.c:2845 glib/gutils.c:2962
 #, c-format
 msgid "%u byte"
 msgid_plural "%u bytes"
@@ -6042,7 +6047,7 @@ msgstr[0] "%u bajt"
 msgstr[1] "%u bajty"
 msgstr[2] "%u bajtů"
 
-#: glib/gutils.c:2846
+#: glib/gutils.c:2849
 #, c-format
 msgid "%u bit"
 msgid_plural "%u bits"
@@ -6051,7 +6056,7 @@ msgstr[1] "%u bity"
 msgstr[2] "%u bitů"
 
 #. Translators: the %s in "%s bytes" will always be replaced by a number.
-#: glib/gutils.c:2913
+#: glib/gutils.c:2916
 #, c-format
 msgid "%s byte"
 msgid_plural "%s bytes"
@@ -6060,7 +6065,7 @@ msgstr[1] "%s bajty"
 msgstr[2] "%s bajtů"
 
 #. Translators: the %s in "%s bits" will always be replaced by a number.
-#: glib/gutils.c:2918
+#: glib/gutils.c:2921
 #, c-format
 msgid "%s bit"
 msgid_plural "%s bits"
@@ -6073,32 +6078,32 @@ msgstr[2] "%s bitů"
 #. * compatibility.  Users will not see this string unless a program is using this deprecated function.
 #. * Please translate as literally as possible.
 #.
-#: glib/gutils.c:2972
+#: glib/gutils.c:2975
 #, c-format
 msgid "%.1f KB"
 msgstr "%.1f KB"
 
-#: glib/gutils.c:2977
+#: glib/gutils.c:2980
 #, c-format
 msgid "%.1f MB"
 msgstr "%.1f MB"
 
-#: glib/gutils.c:2982
+#: glib/gutils.c:2985
 #, c-format
 msgid "%.1f GB"
 msgstr "%.1f GB"
 
-#: glib/gutils.c:2987
+#: glib/gutils.c:2990
 #, c-format
 msgid "%.1f TB"
 msgstr "%.1f TB"
 
-#: glib/gutils.c:2992
+#: glib/gutils.c:2995
 #, c-format
 msgid "%.1f PB"
 msgstr "%.1f PB"
 
-#: glib/gutils.c:2997
+#: glib/gutils.c:3000
 #, c-format
 msgid "%.1f EB"
 msgstr "%.1f EB"
index fecb4f5..c833581 100644 (file)
--- a/po/es.po
+++ b/po/es.po
@@ -14,8 +14,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: glib.master\n"
 "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n"
-"POT-Creation-Date: 2020-08-07 14:14+0000\n"
-"PO-Revision-Date: 2020-08-11 12:12+0200\n"
+"POT-Creation-Date: 2020-11-06 17:19+0000\n"
+"PO-Revision-Date: 2020-12-02 10:43+0100\n"
 "Last-Translator: Daniel Mustieles <daniel.mustieles@gmail.com>\n"
 "Language-Team: Spanish - Spain <gnome-es-list@gnome.org>\n"
 "Language: es_ES\n"
@@ -23,7 +23,7 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Gtranslator 3.36.0\n"
+"X-Generator: Gtranslator 3.38.0\n"
 
 #: gio/gapplication.c:500
 msgid "GApplication options"
@@ -110,7 +110,7 @@ msgstr ""
 msgid "APPID"
 msgstr "APPID"
 
-#: gio/gapplication-tool.c:70 gio/gapplication-tool.c:133 gio/gdbus-tool.c:102
+#: gio/gapplication-tool.c:70 gio/gapplication-tool.c:133 gio/gdbus-tool.c:106
 #: gio/gio-tool.c:224
 msgid "COMMAND"
 msgstr "COMANDO"
@@ -290,7 +290,7 @@ msgstr "El flujo ya se cerró"
 msgid "Truncate not supported on base stream"
 msgstr "No se soporta el truncado en el flujo base"
 
-#: gio/gcancellable.c:319 gio/gdbusconnection.c:1862 gio/gdbusprivate.c:1413
+#: gio/gcancellable.c:319 gio/gdbusconnection.c:1862 gio/gdbusprivate.c:1416
 #: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897
 #, c-format
 msgid "Operation was cancelled"
@@ -530,7 +530,7 @@ msgstr ""
 "No se puede determinar la dirección del bus de sesión (no implementado para "
 "este SO)"
 
-#: gio/gdbusaddress.c:1357 gio/gdbusconnection.c:7192
+#: gio/gdbusaddress.c:1357 gio/gdbusconnection.c:7217
 #, c-format
 msgid ""
 "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable "
@@ -539,7 +539,7 @@ msgstr ""
 "No se puede determinar la dirección del bus desde la variable de entorno "
 "DBUS_STARTER_BUS_TYPE; variable «%s» desconocida"
 
-#: gio/gdbusaddress.c:1366 gio/gdbusconnection.c:7201
+#: gio/gdbusaddress.c:1366 gio/gdbusconnection.c:7226
 msgid ""
 "Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment "
 "variable is not set"
@@ -573,12 +573,12 @@ msgstr ""
 msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer"
 msgstr "Cancelado a través de GDBusAuthObserver::authorize-authenticated-peer"
 
-#: gio/gdbusauthmechanismsha1.c:265
+#: gio/gdbusauthmechanismsha1.c:296
 #, c-format
 msgid "Error when getting information for directory “%s”: %s"
 msgstr "Error al obtener la información de la carpeta «%s»: %s"
 
-#: gio/gdbusauthmechanismsha1.c:280
+#: gio/gdbusauthmechanismsha1.c:311
 #, c-format
 msgid ""
 "Permissions on directory “%s” are malformed. Expected mode 0700, got 0%o"
@@ -586,24 +586,24 @@ msgstr ""
 "Los permisos de la carpeta «%s» están mal formados. Se esperaba el modo "
 "0700, se obtuvo 0%o"
 
-#: gio/gdbusauthmechanismsha1.c:310
+#: gio/gdbusauthmechanismsha1.c:341
 #, c-format
 msgid "Error creating directory “%s”: %s"
 msgstr "Error al crear la carpeta %s: %s"
 
-#: gio/gdbusauthmechanismsha1.c:355
+#: gio/gdbusauthmechanismsha1.c:386
 #, c-format
 msgid "Error opening keyring “%s” for reading: "
 msgstr "Error al abrir el depósito de claves «%s» para su lectura: "
 
-#: gio/gdbusauthmechanismsha1.c:378 gio/gdbusauthmechanismsha1.c:700
+#: gio/gdbusauthmechanismsha1.c:409 gio/gdbusauthmechanismsha1.c:731
 #, c-format
 msgid "Line %d of the keyring at “%s” with content “%s” is malformed"
 msgstr ""
 "La línea %d del depósito de claves en «%s» con contenido «%s» está mal "
 "formada"
 
-#: gio/gdbusauthmechanismsha1.c:392 gio/gdbusauthmechanismsha1.c:714
+#: gio/gdbusauthmechanismsha1.c:423 gio/gdbusauthmechanismsha1.c:745
 #, c-format
 msgid ""
 "First token of line %d of the keyring at “%s” with content “%s” is malformed"
@@ -611,7 +611,7 @@ msgstr ""
 "El primer token de la línea %d del depósito de claves en «%s» con contenido "
 "«%s» está mal formado"
 
-#: gio/gdbusauthmechanismsha1.c:406 gio/gdbusauthmechanismsha1.c:728
+#: gio/gdbusauthmechanismsha1.c:437 gio/gdbusauthmechanismsha1.c:759
 #, c-format
 msgid ""
 "Second token of line %d of the keyring at “%s” with content “%s” is malformed"
@@ -619,37 +619,37 @@ msgstr ""
 "El segundo token de la línea %d del depósito de claves en «%s» con contenido "
 "«%s» está mal formado"
 
-#: gio/gdbusauthmechanismsha1.c:430
+#: gio/gdbusauthmechanismsha1.c:461
 #, c-format
 msgid "Didn’t find cookie with id %d in the keyring at “%s”"
 msgstr "No se encontró la «cookie» con ID %d en el depósito de claves en «%s»"
 
-#: gio/gdbusauthmechanismsha1.c:476
+#: gio/gdbusauthmechanismsha1.c:507
 #, c-format
 msgid "Error creating lock file “%s”: %s"
 msgstr "Error al crear el archivo de bloqueo «%s»: %s"
 
-#: gio/gdbusauthmechanismsha1.c:540
+#: gio/gdbusauthmechanismsha1.c:571
 #, c-format
 msgid "Error deleting stale lock file “%s”: %s"
 msgstr "Error al eliminar el archivo de bloqueo antiguo «%s»: %s"
 
-#: gio/gdbusauthmechanismsha1.c:579
+#: gio/gdbusauthmechanismsha1.c:610
 #, c-format
 msgid "Error closing (unlinked) lock file “%s”: %s"
 msgstr "Error al cerrar (desenlazar) el archivo de bloqueo «%s»: %s"
 
-#: gio/gdbusauthmechanismsha1.c:590
+#: gio/gdbusauthmechanismsha1.c:621
 #, c-format
 msgid "Error unlinking lock file “%s”: %s"
 msgstr "Error al desenlazar el archivo de bloqueo «%s»: %s"
 
-#: gio/gdbusauthmechanismsha1.c:667
+#: gio/gdbusauthmechanismsha1.c:698
 #, c-format
 msgid "Error opening keyring “%s” for writing: "
 msgstr "Error al abrir el depósito de claves «%s» para su escritura:"
 
-#: gio/gdbusauthmechanismsha1.c:865
+#: gio/gdbusauthmechanismsha1.c:892
 #, c-format
 msgid "(Additionally, releasing the lock for “%s” also failed: %s) "
 msgstr ""
@@ -701,12 +701,12 @@ msgstr ""
 "obtuvo «%s»."
 
 #: gio/gdbusconnection.c:4453 gio/gdbusconnection.c:4661
-#: gio/gdbusconnection.c:6632
+#: gio/gdbusconnection.c:6657
 #, c-format
 msgid "No such interface “%s”"
 msgstr "La interfaz «%s» no existe"
 
-#: gio/gdbusconnection.c:4879 gio/gdbusconnection.c:7141
+#: gio/gdbusconnection.c:4879 gio/gdbusconnection.c:7166
 #, c-format
 msgid "No such interface “%s” on object at path %s"
 msgstr "No existe la interfaz «%s» en el objeto en la ruta %s"
@@ -741,38 +741,38 @@ msgstr "No se pudo establecer la propiedad %s.%s"
 msgid "Method “%s” returned type “%s”, but expected “%s”"
 msgstr "El método «%s» devolvió el tipo «%s» pero se esperaba «%s»"
 
-#: gio/gdbusconnection.c:6743
+#: gio/gdbusconnection.c:6768
 #, c-format
 msgid "Method “%s” on interface “%s” with signature “%s” does not exist"
 msgstr "El método «%s» con interfaz «%s» y firma «%s» no existe"
 
-#: gio/gdbusconnection.c:6864
+#: gio/gdbusconnection.c:6889
 #, c-format
 msgid "A subtree is already exported for %s"
 msgstr "Ya se ha exportado un subárbol para %s"
 
-#: gio/gdbusmessage.c:1255
+#: gio/gdbusmessage.c:1266
 msgid "type is INVALID"
 msgstr "el tipo no es válido («INVALID»)"
 
-#: gio/gdbusmessage.c:1266
+#: gio/gdbusmessage.c:1277
 msgid "METHOD_CALL message: PATH or MEMBER header field is missing"
 msgstr "Mensaje de METHOD_CALL: falta el campo de cabecera PATH o MEMEBER"
 
-#: gio/gdbusmessage.c:1277
+#: gio/gdbusmessage.c:1288
 msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing"
 msgstr "Mensaje de METHOD_RETURN: falta el campo de cabecera REPLY_SERIAL"
 
-#: gio/gdbusmessage.c:1289
+#: gio/gdbusmessage.c:1300
 msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing"
 msgstr ""
 "Mensaje de ERROR: falta el campo de cabecera REPLY_SERRIAL o ERROR_NAME"
 
-#: gio/gdbusmessage.c:1302
+#: gio/gdbusmessage.c:1313
 msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing"
 msgstr "Mensaje de SIGNAL: falta el campo de cabecera PATH, INTERFACE o MEMBER"
 
-#: gio/gdbusmessage.c:1310
+#: gio/gdbusmessage.c:1321
 msgid ""
 "SIGNAL message: The PATH header field is using the reserved value /org/"
 "freedesktop/DBus/Local"
@@ -780,7 +780,7 @@ msgstr ""
 "Mensaje de SIGNAL: el campo de cabecera PATH está usando el valor reservado /"
 "org/freedesktop/DBus/Local"
 
-#: gio/gdbusmessage.c:1318
+#: gio/gdbusmessage.c:1329
 msgid ""
 "SIGNAL message: The INTERFACE header field is using the reserved value org."
 "freedesktop.DBus.Local"
@@ -788,21 +788,21 @@ msgstr ""
 "Mensaje de SIGNAL: el campo de cabecera INTERFACE está usando el valor "
 "reservado org.freedesktop.DBus.Local"
 
-#: gio/gdbusmessage.c:1366 gio/gdbusmessage.c:1426
+#: gio/gdbusmessage.c:1377 gio/gdbusmessage.c:1437
 #, c-format
 msgid "Wanted to read %lu byte but only got %lu"
 msgid_plural "Wanted to read %lu bytes but only got %lu"
 msgstr[0] "Se quería leer %lu byte pero sólo se obtuvo %lu"
 msgstr[1] "Se querían leer %lu bytes pero sólo se obtuvo %lu"
 
-#: gio/gdbusmessage.c:1380
+#: gio/gdbusmessage.c:1391
 #, c-format
 msgid "Expected NUL byte after the string “%s” but found byte %d"
 msgstr ""
 "Se esperaba el byte NULL después de la cadena «%s» pero se encontró el byte "
 "%d"
 
-#: gio/gdbusmessage.c:1399
+#: gio/gdbusmessage.c:1410
 #, c-format
 msgid ""
 "Expected valid UTF-8 string but found invalid bytes at byte offset %d "
@@ -812,21 +812,21 @@ msgstr ""
 "en el byte desplazado %d (la longitud de la cadena es %d). La cadena UTF-8 "
 "válida hasta ese punto era «%s»."
 
-#: gio/gdbusmessage.c:1463 gio/gdbusmessage.c:1711 gio/gdbusmessage.c:1900
+#: gio/gdbusmessage.c:1474 gio/gdbusmessage.c:1722 gio/gdbusmessage.c:1911
 msgid "Value nested too deeply"
 msgstr "Valor anidado demasiado profundamente"
 
-#: gio/gdbusmessage.c:1609
+#: gio/gdbusmessage.c:1620
 #, c-format
 msgid "Parsed value “%s” is not a valid D-Bus object path"
 msgstr "El valor analizado «%s» no es un objeto de ruta D-Bus válido"
 
-#: gio/gdbusmessage.c:1631
+#: gio/gdbusmessage.c:1642
 #, c-format
 msgid "Parsed value “%s” is not a valid D-Bus signature"
 msgstr "El valor analizado «%s» no es una firma de D-Bus válida"
 
-#: gio/gdbusmessage.c:1678
+#: gio/gdbusmessage.c:1689
 #, c-format
 msgid ""
 "Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)."
@@ -839,7 +839,7 @@ msgstr[1] ""
 "Se encontró un array de longitud %u bytes. La longitud máxima es 2<<26 bytes "
 "(64 MiB)."
 
-#: gio/gdbusmessage.c:1698
+#: gio/gdbusmessage.c:1709
 #, c-format
 msgid ""
 "Encountered array of type “a%c”, expected to have a length a multiple of %u "
@@ -848,13 +848,13 @@ msgstr ""
 "Encontrado un vector de tipo «a%c», esperando que su longitud fuese múltiplo "
 "de %u bytes, pero su longitud es de %u"
 
-#: gio/gdbusmessage.c:1884
+#: gio/gdbusmessage.c:1895
 #, c-format
 msgid "Parsed value “%s” for variant is not a valid D-Bus signature"
 msgstr ""
 "El valor analizado «%s» para la variante no es una firma de D-Bus válida"
 
-#: gio/gdbusmessage.c:1925
+#: gio/gdbusmessage.c:1936
 #, c-format
 msgid ""
 "Error deserializing GVariant with type string “%s” from the D-Bus wire format"
@@ -862,7 +862,7 @@ msgstr ""
 "Error al deserializar GVariant con el tipo de cadena «%s» al formato de "
 "mensaje de D-Bus"
 
-#: gio/gdbusmessage.c:2110
+#: gio/gdbusmessage.c:2121
 #, c-format
 msgid ""
 "Invalid endianness value. Expected 0x6c (“l”) or 0x42 (“B”) but found value "
@@ -871,31 +871,31 @@ msgstr ""
 "Valor endian no válido. Se esperaba 0x6c («l») o 0x42 («B»)» pero se obtuvo "
 "el valor 0x%02x"
 
-#: gio/gdbusmessage.c:2123
+#: gio/gdbusmessage.c:2134
 #, c-format
 msgid "Invalid major protocol version. Expected 1 but found %d"
 msgstr ""
 "La versión principal del protocolo no es válida. Se esperaba 1 pero se "
 "encontró %d."
 
-#: gio/gdbusmessage.c:2177 gio/gdbusmessage.c:2773
+#: gio/gdbusmessage.c:2188 gio/gdbusmessage.c:2784
 msgid "Signature header found but is not of type signature"
 msgstr "Cabecera de firma encontrada pero no es del tipo firma"
 
-#: gio/gdbusmessage.c:2189
+#: gio/gdbusmessage.c:2200
 #, c-format
 msgid "Signature header with signature “%s” found but message body is empty"
 msgstr ""
 "Se encontró la cabecera de firma con firma «%s» pero el cuerpo del mensaje "
 "está vacío"
 
-#: gio/gdbusmessage.c:2204
+#: gio/gdbusmessage.c:2215
 #, c-format
 msgid "Parsed value “%s” is not a valid D-Bus signature (for body)"
 msgstr ""
 "El valor analizado «%s» no es una firma de D-Bus válida (para el cuerpo)"
 
-#: gio/gdbusmessage.c:2236
+#: gio/gdbusmessage.c:2247
 #, c-format
 msgid "No signature header in message but the message body is %u byte"
 msgid_plural "No signature header in message but the message body is %u bytes"
@@ -906,11 +906,11 @@ msgstr[1] ""
 "No existe la cabecera de firma en el mensaje pero el cuerpo del mensaje "
 "tiene %u bytes"
 
-#: gio/gdbusmessage.c:2246
+#: gio/gdbusmessage.c:2257
 msgid "Cannot deserialize message: "
 msgstr "No se puede deserializar el mensaje: "
 
-#: gio/gdbusmessage.c:2590
+#: gio/gdbusmessage.c:2601
 #, c-format
 msgid ""
 "Error serializing GVariant with type string “%s” to the D-Bus wire format"
@@ -918,7 +918,7 @@ msgstr ""
 "Error al serializar GVariant con el tipo de cadena «%s» al formato de "
 "mensaje de D-Bus"
 
-#: gio/gdbusmessage.c:2727
+#: gio/gdbusmessage.c:2738
 #, c-format
 msgid ""
 "Number of file descriptors in message (%d) differs from header field (%d)"
@@ -926,17 +926,17 @@ msgstr ""
 "El número de descriptores de archivos en el mensaje (%d) es distinto del "
 "campo de cabecera (%d)"
 
-#: gio/gdbusmessage.c:2735
+#: gio/gdbusmessage.c:2746
 msgid "Cannot serialize message: "
 msgstr "No se puede serializar el mensaje: "
 
-#: gio/gdbusmessage.c:2788
+#: gio/gdbusmessage.c:2799
 #, c-format
 msgid "Message body has signature “%s” but there is no signature header"
 msgstr ""
 "El cuerpo del mensaje tiene la firma «%s» pero no existe la cabecera de firma"
 
-#: gio/gdbusmessage.c:2798
+#: gio/gdbusmessage.c:2809
 #, c-format
 msgid ""
 "Message body has type signature “%s” but signature in the header field is "
@@ -945,39 +945,39 @@ msgstr ""
 "El cuerpo del mensaje tiene un tipo de firma «%s» pero la firma en el campo "
 "de cabecera es «%s»"
 
-#: gio/gdbusmessage.c:2814
+#: gio/gdbusmessage.c:2825
 #, c-format
 msgid "Message body is empty but signature in the header field is “(%s)”"
 msgstr ""
 "El cuerpo del mensaje está vacío pero la firma en el campo de cabecera es "
 "«(%s)»"
 
-#: gio/gdbusmessage.c:3367
+#: gio/gdbusmessage.c:3378
 #, c-format
 msgid "Error return with body of type “%s”"
 msgstr "Error al devolver el cuerpo de tipo «%s»"
 
-#: gio/gdbusmessage.c:3375
+#: gio/gdbusmessage.c:3386
 msgid "Error return with empty body"
 msgstr "Error al devolver un cuepro vacío"
 
-#: gio/gdbusprivate.c:2244
+#: gio/gdbusprivate.c:2247
 #, c-format
 msgid "(Type any character to close this window)\n"
 msgstr "(Escriba un carácter cualquiera para cerrar esta ventana)\n"
 
-#: gio/gdbusprivate.c:2418
+#: gio/gdbusprivate.c:2421
 #, c-format
 msgid "Session dbus not running, and autolaunch failed"
 msgstr ""
 "La sesión de dbus no está en ejecución, y falló el lanzamiento automático"
 
-#: gio/gdbusprivate.c:2441
+#: gio/gdbusprivate.c:2444
 #, c-format
 msgid "Unable to get Hardware profile: %s"
 msgstr "No se pudo obtener el perfil de hardware: %s"
 
-#: gio/gdbusprivate.c:2486
+#: gio/gdbusprivate.c:2489
 msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: "
 msgstr "No se puede cargar /var/lib/dbus/machine-id o /etc/machine-id: "
 
@@ -1026,7 +1026,7 @@ msgstr "La cadena «%s» no es un GUID válido de D-Bus"
 msgid "Cannot listen on unsupported transport “%s”"
 msgstr "No se puede escuchar en un transporte no soportado «%s»"
 
-#: gio/gdbus-tool.c:107
+#: gio/gdbus-tool.c:111
 #, c-format
 msgid ""
 "Commands:\n"
@@ -1049,54 +1049,54 @@ msgstr ""
 "\n"
 "Use «%s COMANDO --help» para obtener ayuda de cada comando.\n"
 
-#: gio/gdbus-tool.c:197 gio/gdbus-tool.c:264 gio/gdbus-tool.c:336
-#: gio/gdbus-tool.c:360 gio/gdbus-tool.c:850 gio/gdbus-tool.c:1187
-#: gio/gdbus-tool.c:1672
+#: gio/gdbus-tool.c:201 gio/gdbus-tool.c:268 gio/gdbus-tool.c:340
+#: gio/gdbus-tool.c:364 gio/gdbus-tool.c:854 gio/gdbus-tool.c:1231
+#: gio/gdbus-tool.c:1719
 #, c-format
 msgid "Error: %s\n"
 msgstr "Error: %s\n"
 
-#: gio/gdbus-tool.c:208 gio/gdbus-tool.c:277 gio/gdbus-tool.c:1688
+#: gio/gdbus-tool.c:212 gio/gdbus-tool.c:281 gio/gdbus-tool.c:1735
 #, c-format
 msgid "Error parsing introspection XML: %s\n"
 msgstr "Error al analizar la introspección XML: %s\n"
 
-#: gio/gdbus-tool.c:246
+#: gio/gdbus-tool.c:250
 #, c-format
 msgid "Error: %s is not a valid name\n"
 msgstr "Error: %s no es un nombre válido\n"
 
-#: gio/gdbus-tool.c:394
+#: gio/gdbus-tool.c:398
 msgid "Connect to the system bus"
 msgstr "Conectar con el bus del sistema"
 
-#: gio/gdbus-tool.c:395
+#: gio/gdbus-tool.c:399
 msgid "Connect to the session bus"
 msgstr "Conectar con el bus de sesión"
 
-#: gio/gdbus-tool.c:396
+#: gio/gdbus-tool.c:400
 msgid "Connect to given D-Bus address"
 msgstr "Conectar con la dirección de D-Bus proporcionada"
 
-#: gio/gdbus-tool.c:406
+#: gio/gdbus-tool.c:410
 msgid "Connection Endpoint Options:"
 msgstr "Opciones de conexión del extremo:"
 
-#: gio/gdbus-tool.c:407
+#: gio/gdbus-tool.c:411
 msgid "Options specifying the connection endpoint"
 msgstr "Opciones para especificar la conexión del extremo:"
 
-#: gio/gdbus-tool.c:430
+#: gio/gdbus-tool.c:434
 #, c-format
 msgid "No connection endpoint specified"
 msgstr "No se especificó ningún punto de conexión extremo"
 
-#: gio/gdbus-tool.c:440
+#: gio/gdbus-tool.c:444
 #, c-format
 msgid "Multiple connection endpoints specified"
 msgstr "Se especificaron varios puntos de conexión extremos"
 
-#: gio/gdbus-tool.c:513
+#: gio/gdbus-tool.c:517
 #, c-format
 msgid ""
 "Warning: According to introspection data, interface “%s” does not exist\n"
@@ -1104,7 +1104,7 @@ msgstr ""
 "Advertencia: según la introspección de los datos, la interfaz «%s» no "
 "existe\n"
 
-#: gio/gdbus-tool.c:522
+#: gio/gdbus-tool.c:526
 #, c-format
 msgid ""
 "Warning: According to introspection data, method “%s” does not exist on "
@@ -1113,162 +1113,168 @@ msgstr ""
 "Advertencia: según la introspección de los datos, el método «%s» no existe "
 "en la interfaz «%s»\n"
 
-#: gio/gdbus-tool.c:584
+#: gio/gdbus-tool.c:588
 msgid "Optional destination for signal (unique name)"
 msgstr "Destino opcional para la señal (nombre único)"
 
-#: gio/gdbus-tool.c:585
+#: gio/gdbus-tool.c:589
 msgid "Object path to emit signal on"
 msgstr "Ruta del objeto sobre el que emitir la señal"
 
-#: gio/gdbus-tool.c:586
+#: gio/gdbus-tool.c:590
 msgid "Signal and interface name"
 msgstr "Nombres de la interfaz y señal"
 
-#: gio/gdbus-tool.c:619
+#: gio/gdbus-tool.c:623
 msgid "Emit a signal."
 msgstr "Emitir una señal."
 
-#: gio/gdbus-tool.c:674 gio/gdbus-tool.c:981 gio/gdbus-tool.c:1775
-#: gio/gdbus-tool.c:2007 gio/gdbus-tool.c:2227
+#: gio/gdbus-tool.c:678 gio/gdbus-tool.c:992 gio/gdbus-tool.c:1822
+#: gio/gdbus-tool.c:2054 gio/gdbus-tool.c:2274
 #, c-format
 msgid "Error connecting: %s\n"
 msgstr "Error al conectar: %s\n"
 
-#: gio/gdbus-tool.c:694
+#: gio/gdbus-tool.c:698
 #, c-format
 msgid "Error: %s is not a valid unique bus name.\n"
 msgstr "Error: %s no es un nombre de bus único válido.\n"
 
-#: gio/gdbus-tool.c:713 gio/gdbus-tool.c:1024 gio/gdbus-tool.c:1818
+#: gio/gdbus-tool.c:717 gio/gdbus-tool.c:1035 gio/gdbus-tool.c:1865
 msgid "Error: Object path is not specified\n"
 msgstr "Error: no se especificó la ruta del objeto\n"
 
-#: gio/gdbus-tool.c:736 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1838
-#: gio/gdbus-tool.c:2078
+#: gio/gdbus-tool.c:740 gio/gdbus-tool.c:1055 gio/gdbus-tool.c:1885
+#: gio/gdbus-tool.c:2125
 #, c-format
 msgid "Error: %s is not a valid object path\n"
 msgstr "Error: %s no es una ruta de objeto válida\n"
 
-#: gio/gdbus-tool.c:756
+#: gio/gdbus-tool.c:760
 msgid "Error: Signal name is not specified\n"
 msgstr "Error: no se especificó el nombre de la señal\n"
 
-#: gio/gdbus-tool.c:770
+#: gio/gdbus-tool.c:774
 #, c-format
 msgid "Error: Signal name “%s” is invalid\n"
 msgstr "Error: el nombre de la señal «%s» no es válido\n"
 
-#: gio/gdbus-tool.c:782
+#: gio/gdbus-tool.c:786
 #, c-format
 msgid "Error: %s is not a valid interface name\n"
 msgstr "Error: %s no es un nombre de interfaz válida\n"
 
-#: gio/gdbus-tool.c:788
+#: gio/gdbus-tool.c:792
 #, c-format
 msgid "Error: %s is not a valid member name\n"
 msgstr "Error: %s no es un nombre de miembro válido\n"
 
 #. Use the original non-"parse-me-harder" error
-#: gio/gdbus-tool.c:825 gio/gdbus-tool.c:1156
+#: gio/gdbus-tool.c:829 gio/gdbus-tool.c:1167
 #, c-format
 msgid "Error parsing parameter %d: %s\n"
 msgstr "Error al analizar el parámetro %d: %s\n"
 
-#: gio/gdbus-tool.c:857
+#: gio/gdbus-tool.c:861
 #, c-format
 msgid "Error flushing connection: %s\n"
 msgstr "Error al limpiar la conexión: %s\n"
 
-#: gio/gdbus-tool.c:884
+#: gio/gdbus-tool.c:888
 msgid "Destination name to invoke method on"
 msgstr "Nombre del detino sobre el que invocar elmétodo"
 
-#: gio/gdbus-tool.c:885
+#: gio/gdbus-tool.c:889
 msgid "Object path to invoke method on"
 msgstr "Ruta del objeto sobre la que invocar el método"
 
-#: gio/gdbus-tool.c:886
+#: gio/gdbus-tool.c:890
 msgid "Method and interface name"
 msgstr "Nombre de la interfaz y método"
 
-#: gio/gdbus-tool.c:887
+#: gio/gdbus-tool.c:891
 msgid "Timeout in seconds"
 msgstr "Tiempo de expiración en segundos"
 
-#: gio/gdbus-tool.c:926
+#: gio/gdbus-tool.c:937
 msgid "Invoke a method on a remote object."
 msgstr "Invocar un método en un objeto remoto."
 
-#: gio/gdbus-tool.c:998 gio/gdbus-tool.c:1792 gio/gdbus-tool.c:2032
+#: gio/gdbus-tool.c:1009 gio/gdbus-tool.c:1839 gio/gdbus-tool.c:2079
 msgid "Error: Destination is not specified\n"
 msgstr "Error: el destino no está especificado\n"
 
-#: gio/gdbus-tool.c:1009 gio/gdbus-tool.c:1809 gio/gdbus-tool.c:2043
+#: gio/gdbus-tool.c:1020 gio/gdbus-tool.c:1856 gio/gdbus-tool.c:2090
 #, c-format
 msgid "Error: %s is not a valid bus name\n"
 msgstr "Error: %s no es un nombre de bus válido\n"
 
-#: gio/gdbus-tool.c:1059
+#: gio/gdbus-tool.c:1070
 msgid "Error: Method name is not specified\n"
 msgstr "Error: no se especificó el nombre del método\n"
 
-#: gio/gdbus-tool.c:1070
+#: gio/gdbus-tool.c:1081
 #, c-format
 msgid "Error: Method name “%s” is invalid\n"
 msgstr "Error: el nombre del método «%s» no es válido\n"
 
-#: gio/gdbus-tool.c:1148
+#: gio/gdbus-tool.c:1159
 #, c-format
 msgid "Error parsing parameter %d of type “%s”: %s\n"
 msgstr "Error al analizar el parámetro %d del tipo «%s»: %s\n"
 
-#: gio/gdbus-tool.c:1634
+#: gio/gdbus-tool.c:1185
+#, c-format
+#| msgid "Error reading from handle: %s"
+msgid "Error adding handle %d: %s\n"
+msgstr "Error al añadir el manejador %d: %s\n"
+
+#: gio/gdbus-tool.c:1681
 msgid "Destination name to introspect"
 msgstr "Nombre de destino que introspeccionar"
 
-#: gio/gdbus-tool.c:1635
+#: gio/gdbus-tool.c:1682
 msgid "Object path to introspect"
 msgstr "Ruta del objeto que introspeccionar"
 
-#: gio/gdbus-tool.c:1636
+#: gio/gdbus-tool.c:1683
 msgid "Print XML"
 msgstr "Imprimir XML"
 
-#: gio/gdbus-tool.c:1637
+#: gio/gdbus-tool.c:1684
 msgid "Introspect children"
 msgstr "Introspeccionar hijo"
 
-#: gio/gdbus-tool.c:1638
+#: gio/gdbus-tool.c:1685
 msgid "Only print properties"
 msgstr "Solo mostrar propiedades"
 
-#: gio/gdbus-tool.c:1727
+#: gio/gdbus-tool.c:1774
 msgid "Introspect a remote object."
 msgstr "Introspeccionar un objeto remoto."
 
-#: gio/gdbus-tool.c:1933
+#: gio/gdbus-tool.c:1980
 msgid "Destination name to monitor"
 msgstr "Nombre de destino para monitorizar"
 
-#: gio/gdbus-tool.c:1934
+#: gio/gdbus-tool.c:1981
 msgid "Object path to monitor"
 msgstr "Ruta objeto para monitorizar"
 
-#: gio/gdbus-tool.c:1959
+#: gio/gdbus-tool.c:2006
 msgid "Monitor a remote object."
 msgstr "Monitorizar un objeto remoto."
 
-#: gio/gdbus-tool.c:2017
+#: gio/gdbus-tool.c:2064
 msgid "Error: can’t monitor a non-message-bus connection\n"
 msgstr ""
 "Error: no se puede monitorizar una conexión que no sea de mensajes del bus\n"
 
-#: gio/gdbus-tool.c:2141
+#: gio/gdbus-tool.c:2188
 msgid "Service to activate before waiting for the other one (well-known name)"
 msgstr "Servicio que activar antes de esperar a otro (nombre conocido)"
 
-#: gio/gdbus-tool.c:2144
+#: gio/gdbus-tool.c:2191
 msgid ""
 "Timeout to wait for before exiting with an error (seconds); 0 for no timeout "
 "(default)"
@@ -1276,65 +1282,65 @@ msgstr ""
 "Tiempo que esperar antes de salir con un error (en segundos); 0 para que no "
 "haya tiempo de expiración (predeterminado)"
 
-#: gio/gdbus-tool.c:2192
+#: gio/gdbus-tool.c:2239
 msgid "[OPTION…] BUS-NAME"
 msgstr "[OPCIÓN…] NOMBRE-BUS"
 
-#: gio/gdbus-tool.c:2193
+#: gio/gdbus-tool.c:2240
 msgid "Wait for a bus name to appear."
 msgstr "Esperar a que aparezca el nombre del bus."
 
-#: gio/gdbus-tool.c:2269
+#: gio/gdbus-tool.c:2316
 msgid "Error: A service to activate for must be specified.\n"
 msgstr "Error: se debe especificar un servicio que activar.\n"
 
-#: gio/gdbus-tool.c:2274
+#: gio/gdbus-tool.c:2321
 msgid "Error: A service to wait for must be specified.\n"
 msgstr "Error: se debe especificar un servicio al que esperar.\n"
 
-#: gio/gdbus-tool.c:2279
+#: gio/gdbus-tool.c:2326
 msgid "Error: Too many arguments.\n"
 msgstr "Demasiados argumentos.\n"
 
-#: gio/gdbus-tool.c:2287 gio/gdbus-tool.c:2294
+#: gio/gdbus-tool.c:2334 gio/gdbus-tool.c:2341
 #, c-format
 msgid "Error: %s is not a valid well-known bus name.\n"
 msgstr "Error: %s no es un nombre de bus conocido válido\n"
 
-#: gio/gdesktopappinfo.c:2071 gio/gdesktopappinfo.c:4891
+#: gio/gdesktopappinfo.c:2073 gio/gdesktopappinfo.c:4893
 msgid "Unnamed"
 msgstr "Sin nombre"
 
-#: gio/gdesktopappinfo.c:2481
+#: gio/gdesktopappinfo.c:2483
 msgid "Desktop file didn’t specify Exec field"
 msgstr "El archivo de escritorio no especificó el campo Exec"
 
-#: gio/gdesktopappinfo.c:2761
+#: gio/gdesktopappinfo.c:2763
 msgid "Unable to find terminal required for application"
 msgstr "Imposible encontrar el terminal requerido por la aplicación"
 
-#: gio/gdesktopappinfo.c:3412
+#: gio/gdesktopappinfo.c:3414
 #, c-format
 msgid "Can’t create user application configuration folder %s: %s"
 msgstr ""
 "No se puede crear la carpeta de configuración de la aplicación %s del "
 "usuario: %s"
 
-#: gio/gdesktopappinfo.c:3416
+#: gio/gdesktopappinfo.c:3418
 #, c-format
 msgid "Can’t create user MIME configuration folder %s: %s"
 msgstr "No se puede crear la carpeta de configuración MIME %s del usuario: %s"
 
-#: gio/gdesktopappinfo.c:3658 gio/gdesktopappinfo.c:3682
+#: gio/gdesktopappinfo.c:3660 gio/gdesktopappinfo.c:3684
 msgid "Application information lacks an identifier"
 msgstr "La información de la aplicación carece de un identificador"
 
-#: gio/gdesktopappinfo.c:3918
+#: gio/gdesktopappinfo.c:3920
 #, c-format
 msgid "Can’t create user desktop file %s"
 msgstr "No se puede crear el archivo de escritorio %s del usuario"
 
-#: gio/gdesktopappinfo.c:4054
+#: gio/gdesktopappinfo.c:4056
 #, c-format
 msgid "Custom definition for %s"
 msgstr "Definición personalizada para %s"
@@ -1401,11 +1407,11 @@ msgstr "Se esperaba un GEmblem para GEmblemedIconjo"
 
 #: gio/gfile.c:1044 gio/gfile.c:1282 gio/gfile.c:1420 gio/gfile.c:1658
 #: gio/gfile.c:1713 gio/gfile.c:1771 gio/gfile.c:1855 gio/gfile.c:1912
-#: gio/gfile.c:1976 gio/gfile.c:2031 gio/gfile.c:3722 gio/gfile.c:3777
-#: gio/gfile.c:4055 gio/gfile.c:4525 gio/gfile.c:4936 gio/gfile.c:5021
-#: gio/gfile.c:5111 gio/gfile.c:5208 gio/gfile.c:5295 gio/gfile.c:5396
-#: gio/gfile.c:8106 gio/gfile.c:8196 gio/gfile.c:8280
-#: gio/win32/gwinhttpfile.c:437
+#: gio/gfile.c:1976 gio/gfile.c:2031 gio/gfile.c:3745 gio/gfile.c:3800
+#: gio/gfile.c:4093 gio/gfile.c:4563 gio/gfile.c:4974 gio/gfile.c:5059
+#: gio/gfile.c:5149 gio/gfile.c:5246 gio/gfile.c:5333 gio/gfile.c:5434
+#: gio/gfile.c:8144 gio/gfile.c:8234 gio/gfile.c:8318
+#: gio/win32/gwinhttpfile.c:453
 msgid "Operation not supported"
 msgstr "Operación no soportada"
 
@@ -1417,7 +1423,7 @@ msgstr "Operación no soportada"
 msgid "Containing mount does not exist"
 msgstr "El punto de montaje contenido no existe"
 
-#: gio/gfile.c:2590 gio/glocalfile.c:2434
+#: gio/gfile.c:2590 gio/glocalfile.c:2430
 msgid "Can’t copy over directory"
 msgstr "No se puede copiar sobre la carpeta"
 
@@ -1433,53 +1439,53 @@ msgstr "El archivo destino ya existe"
 msgid "Can’t recursively copy directory"
 msgstr "No se puede copiar la carpeta recursivamente"
 
-#: gio/gfile.c:2952
+#: gio/gfile.c:2978
 msgid "Splice not supported"
 msgstr "La unión no  está soportada"
 
-#: gio/gfile.c:2956 gio/gfile.c:3001
+#: gio/gfile.c:2982 gio/gfile.c:3027
 #, c-format
 msgid "Error splicing file: %s"
 msgstr "Error al unir el archivo: %s"
 
-#: gio/gfile.c:3117
+#: gio/gfile.c:3143
 msgid "Copy (reflink/clone) between mounts is not supported"
 msgstr "Copiar (reflink/clone) entre puntos de montaje no está soportado"
 
-#: gio/gfile.c:3121
+#: gio/gfile.c:3147
 msgid "Copy (reflink/clone) is not supported or invalid"
 msgstr "Copiar (reflink/clone) no está soportado o no es válido"
 
-#: gio/gfile.c:3126
+#: gio/gfile.c:3152
 msgid "Copy (reflink/clone) is not supported or didn’t work"
 msgstr "Copiar (reflink/clone) no está soportado o no ha funcionado"
 
-#: gio/gfile.c:3190
+#: gio/gfile.c:3217
 msgid "Can’t copy special file"
 msgstr "No se puede copiar el archivo especial"
 
-#: gio/gfile.c:4003
+#: gio/gfile.c:4026
 msgid "Invalid symlink value given"
 msgstr "El valor del enlace simbólico dado no es válido"
 
-#: gio/gfile.c:4013 glib/gfileutils.c:2349
+#: gio/gfile.c:4036 glib/gfileutils.c:2349
 msgid "Symbolic links not supported"
 msgstr "Enlaces simbólicos no soportados"
 
-#: gio/gfile.c:4166
+#: gio/gfile.c:4204
 msgid "Trash not supported"
 msgstr "No se soporta mover a la papelera"
 
-#: gio/gfile.c:4278
+#: gio/gfile.c:4316
 #, c-format
 msgid "File names cannot contain “%c”"
 msgstr "Los nombres de archivo no pueden contener «%c»"
 
-#: gio/gfile.c:6759 gio/gvolume.c:364
+#: gio/gfile.c:6797 gio/gvolume.c:364
 msgid "volume doesn’t implement mount"
 msgstr "el volumen no implementa el montaje"
 
-#: gio/gfile.c:6873 gio/gfile.c:6921
+#: gio/gfile.c:6911 gio/gfile.c:6959
 msgid "No application is registered as handling this file"
 msgstr "No hay ninguna aplicación registrada para manejar este archivo"
 
@@ -1735,7 +1741,7 @@ msgstr "Error al escribir en la salida estándar"
 #: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43
 #: gio/gio-tool-monitor.c:203 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70
 #: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89
-#: gio/gio-tool-trash.c:81 gio/gio-tool-tree.c:239
+#: gio/gio-tool-trash.c:90 gio/gio-tool-tree.c:239
 msgid "LOCATION"
 msgstr "UBICACIÓN"
 
@@ -1755,7 +1761,7 @@ msgstr ""
 
 #: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:364 gio/gio-tool-mkdir.c:76
 #: gio/gio-tool-monitor.c:228 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96
-#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:136
+#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:145
 msgid "No locations given"
 msgstr "No se han proporcionado ubicaciones"
 
@@ -2306,7 +2312,7 @@ msgstr "Tipo de atributo «%s» no válido"
 msgid "Empty the trash"
 msgstr "Vaciar la papelera"
 
-#: gio/gio-tool-trash.c:86
+#: gio/gio-tool-trash.c:95
 msgid "Move files or directories to the trash."
 msgstr "Mover archivos o carpetas a la papelera."
 
@@ -2943,7 +2949,7 @@ msgstr ""
 "No se han encontrado archivos de esquemas: se ha eliminado el archivo de "
 "salida existente."
 
-#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:420
+#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436
 #, c-format
 msgid "Invalid filename %s"
 msgstr "Nombre de archivo no válido %s"
@@ -2975,261 +2981,261 @@ msgstr "Error al leer el archivo %s: %s"
 msgid "Can’t rename file, filename already exists"
 msgstr "No se puede renombrar el archivo, el nombre de archivo ya existe"
 
-#: gio/glocalfile.c:1182 gio/glocalfile.c:2328 gio/glocalfile.c:2356
-#: gio/glocalfile.c:2495 gio/glocalfileoutputstream.c:645
+#: gio/glocalfile.c:1182 gio/glocalfile.c:2324 gio/glocalfile.c:2352
+#: gio/glocalfile.c:2491 gio/glocalfileoutputstream.c:650
 msgid "Invalid filename"
 msgstr "Nombre de archivo no válido"
 
-#: gio/glocalfile.c:1350 gio/glocalfile.c:1365
+#: gio/glocalfile.c:1350 gio/glocalfile.c:1361
 #, c-format
 msgid "Error opening file %s: %s"
 msgstr "Error al abrir el archivo %s: %s"
 
-#: gio/glocalfile.c:1490
+#: gio/glocalfile.c:1486
 #, c-format
 msgid "Error removing file %s: %s"
 msgstr "Error al eliminar el archivo %s: %s"
 
-#: gio/glocalfile.c:1973
+#: gio/glocalfile.c:1969
 #, c-format
 msgid "Error trashing file %s: %s"
 msgstr "Error al mover a la papelera el archivo %s: %s"
 
-#: gio/glocalfile.c:2014
+#: gio/glocalfile.c:2010
 #, c-format
 msgid "Unable to create trash dir %s: %s"
 msgstr "No se pudo crear la carpeta de papelera %s: %s"
 
-#: gio/glocalfile.c:2034
+#: gio/glocalfile.c:2030
 #, c-format
 msgid "Unable to find toplevel directory to trash %s"
 msgstr "No se pudo encontrar la carpeta de nivel superior para la papelera %s"
 
-#: gio/glocalfile.c:2042
+#: gio/glocalfile.c:2038
 #, c-format
 msgid "Trashing on system internal mounts is not supported"
 msgstr "Copiar (reflink/clone) entre puntos de montaje no está soportado"
 
-#: gio/glocalfile.c:2122 gio/glocalfile.c:2142
+#: gio/glocalfile.c:2118 gio/glocalfile.c:2138
 #, c-format
 msgid "Unable to find or create trash directory for %s"
 msgstr "No se pudo encontrar o crear la carpeta de la papelera para %s"
 
-#: gio/glocalfile.c:2177
+#: gio/glocalfile.c:2173
 #, c-format
 msgid "Unable to create trashing info file for %s: %s"
 msgstr "No se pudo crear la información de papelera para el archivo %s: %s"
 
-#: gio/glocalfile.c:2239
+#: gio/glocalfile.c:2235
 #, c-format
 msgid "Unable to trash file %s across filesystem boundaries"
 msgstr ""
 "No se pudo enviar a la papelera el archivo %s entre sistemas de archivos"
 
-#: gio/glocalfile.c:2243 gio/glocalfile.c:2299
+#: gio/glocalfile.c:2239 gio/glocalfile.c:2295
 #, c-format
 msgid "Unable to trash file %s: %s"
 msgstr "No se pudo enviar a la papelera el archivo %s: %s"
 
-#: gio/glocalfile.c:2305
+#: gio/glocalfile.c:2301
 #, c-format
 msgid "Unable to trash file %s"
 msgstr "No se pudo enviar a la papelera el archivo %s"
 
-#: gio/glocalfile.c:2331
+#: gio/glocalfile.c:2327
 #, c-format
 msgid "Error creating directory %s: %s"
 msgstr "Error al crear la carpeta %s: %s"
 
-#: gio/glocalfile.c:2360
+#: gio/glocalfile.c:2356
 #, c-format
 msgid "Filesystem does not support symbolic links"
 msgstr "El sistema de archivos no soporta enlaces simbólicos"
 
-#: gio/glocalfile.c:2363
+#: gio/glocalfile.c:2359
 #, c-format
 msgid "Error making symbolic link %s: %s"
 msgstr "Error al crear el enlace simbólico %s: %s"
 
-#: gio/glocalfile.c:2406 gio/glocalfile.c:2441 gio/glocalfile.c:2498
+#: gio/glocalfile.c:2402 gio/glocalfile.c:2437 gio/glocalfile.c:2494
 #, c-format
 msgid "Error moving file %s: %s"
 msgstr "Error al mover el archivo %s: %s"
 
-#: gio/glocalfile.c:2429
+#: gio/glocalfile.c:2425
 msgid "Can’t move directory over directory"
 msgstr "No se puede mover una carpeta sobre una carpeta"
 
-#: gio/glocalfile.c:2455 gio/glocalfileoutputstream.c:1029
-#: gio/glocalfileoutputstream.c:1043 gio/glocalfileoutputstream.c:1058
-#: gio/glocalfileoutputstream.c:1075 gio/glocalfileoutputstream.c:1089
+#: gio/glocalfile.c:2451 gio/glocalfileoutputstream.c:1039
+#: gio/glocalfileoutputstream.c:1053 gio/glocalfileoutputstream.c:1068
+#: gio/glocalfileoutputstream.c:1085 gio/glocalfileoutputstream.c:1099
 msgid "Backup file creation failed"
 msgstr "Falló la creación del archivo de respaldo"
 
-#: gio/glocalfile.c:2474
+#: gio/glocalfile.c:2470
 #, c-format
 msgid "Error removing target file: %s"
 msgstr "Error al eliminar el archivo destino: %s"
 
-#: gio/glocalfile.c:2488
+#: gio/glocalfile.c:2484
 msgid "Move between mounts not supported"
 msgstr "No se soporta mover archivos entre puntos de montaje"
 
-#: gio/glocalfile.c:2662
+#: gio/glocalfile.c:2658
 #, c-format
 msgid "Could not determine the disk usage of %s: %s"
 msgstr "No se pudo determinar el uso de disco de %s: %s"
 
-#: gio/glocalfileinfo.c:765
+#: gio/glocalfileinfo.c:767
 msgid "Attribute value must be non-NULL"
 msgstr "El valor del atributo de ser no nulo"
 
-#: gio/glocalfileinfo.c:772
+#: gio/glocalfileinfo.c:774
 msgid "Invalid attribute type (string expected)"
 msgstr "Tipo de atributo no válido (se esperaba una cadena)"
 
-#: gio/glocalfileinfo.c:779
+#: gio/glocalfileinfo.c:781
 msgid "Invalid extended attribute name"
 msgstr "Nombre extendido del atributo no válido"
 
-#: gio/glocalfileinfo.c:819
+#: gio/glocalfileinfo.c:821
 #, c-format
 msgid "Error setting extended attribute “%s”: %s"
 msgstr "Error al establecer el atributo extendido «%s»: %s"
 
-#: gio/glocalfileinfo.c:1655
+#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191
 msgid " (invalid encoding)"
 msgstr " (codificación no válida)"
 
-#: gio/glocalfileinfo.c:1819 gio/glocalfileoutputstream.c:907
+#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:915
 #, c-format
 msgid "Error when getting information for file “%s”: %s"
 msgstr "Error al obtener la información del archivo «%s»: %s"
 
-#: gio/glocalfileinfo.c:2089
+#: gio/glocalfileinfo.c:2134
 #, c-format
 msgid "Error when getting information for file descriptor: %s"
 msgstr "Error al obtener la información del descriptor del archivo: %s"
 
-#: gio/glocalfileinfo.c:2134
+#: gio/glocalfileinfo.c:2179
 msgid "Invalid attribute type (uint32 expected)"
 msgstr "Tipo de atributo no válido (se esperaba uint32)"
 
-#: gio/glocalfileinfo.c:2152
+#: gio/glocalfileinfo.c:2197
 msgid "Invalid attribute type (uint64 expected)"
 msgstr "Tipo de atributo no válido (se esperaba uint64)"
 
-#: gio/glocalfileinfo.c:2171 gio/glocalfileinfo.c:2190
+#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235
 msgid "Invalid attribute type (byte string expected)"
 msgstr "Tipo de atributo no válido (se esperaba una cadena byte)"
 
-#: gio/glocalfileinfo.c:2237
+#: gio/glocalfileinfo.c:2282
 msgid "Cannot set permissions on symlinks"
 msgstr "No se pueden establecer permisos en enlaces simbólicos"
 
-#: gio/glocalfileinfo.c:2253
+#: gio/glocalfileinfo.c:2298
 #, c-format
 msgid "Error setting permissions: %s"
 msgstr "Error al establecer permisos: %s"
 
-#: gio/glocalfileinfo.c:2304
+#: gio/glocalfileinfo.c:2349
 #, c-format
 msgid "Error setting owner: %s"
 msgstr "Error al establecer el propietario: %s"
 
-#: gio/glocalfileinfo.c:2327
+#: gio/glocalfileinfo.c:2372
 msgid "symlink must be non-NULL"
 msgstr "el enlace simbólico debe ser no nulo"
 
-#: gio/glocalfileinfo.c:2337 gio/glocalfileinfo.c:2356
-#: gio/glocalfileinfo.c:2367
+#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401
+#: gio/glocalfileinfo.c:2412
 #, c-format
 msgid "Error setting symlink: %s"
 msgstr "Error al establecer el enlace simbólico: %s"
 
-#: gio/glocalfileinfo.c:2346
+#: gio/glocalfileinfo.c:2391
 msgid "Error setting symlink: file is not a symlink"
 msgstr ""
 "Error al establecer el enlace simbólico: el archivo no es un enlace simbólico"
 
-#: gio/glocalfileinfo.c:2418
+#: gio/glocalfileinfo.c:2463
 #, c-format
 msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative"
 msgstr ""
 "Los %d nanosegundos adicionales para la marca de tiempo UNIX %lld son "
 "negativos"
 
-#: gio/glocalfileinfo.c:2427
+#: gio/glocalfileinfo.c:2472
 #, c-format
 msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second"
 msgstr ""
 "Los %d nanosegundos adicionales para la marca de tiempo UNIX %lld alcanzan 1 "
 "segundo"
 
-#: gio/glocalfileinfo.c:2437
+#: gio/glocalfileinfo.c:2482
 #, c-format
 msgid "UNIX timestamp %lld does not fit into 64 bits"
 msgstr "La marca de tiempo UNIX %lld no cabe en 64 bits"
 
-#: gio/glocalfileinfo.c:2448
+#: gio/glocalfileinfo.c:2493
 #, c-format
 msgid "UNIX timestamp %lld is outside of the range supported by Windows"
 msgstr ""
 "La marca de tiempo UNIX %lld está fuera del rango soportado por Windows"
 
-#: gio/glocalfileinfo.c:2512
+#: gio/glocalfileinfo.c:2557
 #, c-format
 msgid "File name “%s” cannot be converted to UTF-16"
 msgstr "El nombre de archivo «%s» no se puede convertir a UTF-16"
 
-#: gio/glocalfileinfo.c:2531
+#: gio/glocalfileinfo.c:2576
 #, c-format
 msgid "File “%s” cannot be opened: Windows Error %lu"
 msgstr "No se puede abrir el archivo «%s»: error de Windows %lu"
 
-#: gio/glocalfileinfo.c:2544
+#: gio/glocalfileinfo.c:2589
 #, c-format
 msgid "Error setting modification or access time for file “%s”: %lu"
 msgstr ""
 "Error al establecer o modificar la hora de acceso para el archivo %s: %lu"
 
-#: gio/glocalfileinfo.c:2645
+#: gio/glocalfileinfo.c:2690
 #, c-format
 msgid "Error setting modification or access time: %s"
 msgstr "Error al establecer o modificar el tiempo de acceso: %s"
 
-#: gio/glocalfileinfo.c:2668
+#: gio/glocalfileinfo.c:2713
 msgid "SELinux context must be non-NULL"
 msgstr "El contexto SELinux debe ser no nulo"
 
-#: gio/glocalfileinfo.c:2683
+#: gio/glocalfileinfo.c:2728
 #, c-format
 msgid "Error setting SELinux context: %s"
 msgstr "Error al establecer el contexto SELinux: %s"
 
-#: gio/glocalfileinfo.c:2690
+#: gio/glocalfileinfo.c:2735
 msgid "SELinux is not enabled on this system"
 msgstr "SELinux no está activado en este sistema"
 
-#: gio/glocalfileinfo.c:2782
+#: gio/glocalfileinfo.c:2827
 #, c-format
 msgid "Setting attribute %s not supported"
 msgstr "Establecer el atributo %s no está soportado"
 
-#: gio/glocalfileinputstream.c:168 gio/glocalfileoutputstream.c:790
+#: gio/glocalfileinputstream.c:168 gio/glocalfileoutputstream.c:795
 #, c-format
 msgid "Error reading from file: %s"
 msgstr "Error al leer del archivo: %s"
 
 #: gio/glocalfileinputstream.c:199 gio/glocalfileinputstream.c:211
 #: gio/glocalfileinputstream.c:225 gio/glocalfileinputstream.c:333
-#: gio/glocalfileoutputstream.c:552 gio/glocalfileoutputstream.c:1107
+#: gio/glocalfileoutputstream.c:557 gio/glocalfileoutputstream.c:1117
 #, c-format
 msgid "Error seeking in file: %s"
 msgstr "Error al buscar en el archivo: %s"
 
-#: gio/glocalfileinputstream.c:255 gio/glocalfileoutputstream.c:342
-#: gio/glocalfileoutputstream.c:436
+#: gio/glocalfileinputstream.c:255 gio/glocalfileoutputstream.c:347
+#: gio/glocalfileoutputstream.c:441
 #, c-format
 msgid "Error closing file: %s"
 msgstr "Error al cerrar el archivo: %s"
@@ -3240,51 +3246,51 @@ msgstr ""
 "No se pudo encontrar el tipo de monitorización del archivo local "
 "predeterminado"
 
-#: gio/glocalfileoutputstream.c:209 gio/glocalfileoutputstream.c:287
-#: gio/glocalfileoutputstream.c:323 gio/glocalfileoutputstream.c:811
+#: gio/glocalfileoutputstream.c:214 gio/glocalfileoutputstream.c:292
+#: gio/glocalfileoutputstream.c:328 gio/glocalfileoutputstream.c:816
 #, c-format
 msgid "Error writing to file: %s"
 msgstr "Error al escribir en el archivo: %s"
 
-#: gio/glocalfileoutputstream.c:369
+#: gio/glocalfileoutputstream.c:374
 #, c-format
 msgid "Error removing old backup link: %s"
 msgstr "Error al eliminar el enlace de respaldo antiguo: %s"
 
-#: gio/glocalfileoutputstream.c:383 gio/glocalfileoutputstream.c:396
+#: gio/glocalfileoutputstream.c:388 gio/glocalfileoutputstream.c:401
 #, c-format
 msgid "Error creating backup copy: %s"
 msgstr "Error al crear una copia de respaldo: %s"
 
-#: gio/glocalfileoutputstream.c:414
+#: gio/glocalfileoutputstream.c:419
 #, c-format
 msgid "Error renaming temporary file: %s"
 msgstr "Error al renombrar el archivo temporal: %s"
 
-#: gio/glocalfileoutputstream.c:598 gio/glocalfileoutputstream.c:1158
+#: gio/glocalfileoutputstream.c:603 gio/glocalfileoutputstream.c:1168
 #, c-format
 msgid "Error truncating file: %s"
 msgstr "Error al truncar el archivo: %s"
 
-#: gio/glocalfileoutputstream.c:651 gio/glocalfileoutputstream.c:889
-#: gio/glocalfileoutputstream.c:1139 gio/gsubprocess.c:380
+#: gio/glocalfileoutputstream.c:656 gio/glocalfileoutputstream.c:894
+#: gio/glocalfileoutputstream.c:1149 gio/gsubprocess.c:380
 #, c-format
 msgid "Error opening file “%s”: %s"
 msgstr "Error al abrir el archivo %s: %s"
 
-#: gio/glocalfileoutputstream.c:920
+#: gio/glocalfileoutputstream.c:928
 msgid "Target file is a directory"
 msgstr "El archivo destino es una carpeta"
 
-#: gio/glocalfileoutputstream.c:925
+#: gio/glocalfileoutputstream.c:933
 msgid "Target file is not a regular file"
 msgstr "El archivo destino no es un archivo regular"
 
-#: gio/glocalfileoutputstream.c:937
+#: gio/glocalfileoutputstream.c:945
 msgid "The file was externally modified"
 msgstr "El archivo se modificó externamente"
 
-#: gio/glocalfileoutputstream.c:1123
+#: gio/glocalfileoutputstream.c:1133
 #, c-format
 msgid "Error removing old file: %s"
 msgstr "Error al eliminar el archivo antiguo: %s"
@@ -3444,15 +3450,15 @@ msgstr "%s no está implementado"
 msgid "Invalid domain"
 msgstr "Dominio no válido"
 
-#: gio/gresource.c:665 gio/gresource.c:924 gio/gresource.c:963
-#: gio/gresource.c:1087 gio/gresource.c:1159 gio/gresource.c:1232
-#: gio/gresource.c:1313 gio/gresourcefile.c:476 gio/gresourcefile.c:599
+#: gio/gresource.c:672 gio/gresource.c:931 gio/gresource.c:970
+#: gio/gresource.c:1094 gio/gresource.c:1166 gio/gresource.c:1239
+#: gio/gresource.c:1320 gio/gresourcefile.c:476 gio/gresourcefile.c:599
 #: gio/gresourcefile.c:736
 #, c-format
 msgid "The resource at “%s” does not exist"
 msgstr "El recurso en «%s» no existe"
 
-#: gio/gresource.c:830
+#: gio/gresource.c:837
 #, c-format
 msgid "The resource at “%s” failed to decompress"
 msgstr "El recurso en «%s» falló al descomprimir"
@@ -3990,30 +3996,26 @@ msgstr "No se pudieron leer las credenciales del socket: %s"
 msgid "g_socket_get_credentials not implemented for this OS"
 msgstr "g_socket_get_credentials no está implementado en este SO"
 
-#: gio/gsocketclient.c:182
+#: gio/gsocketclient.c:191
 #, c-format
 msgid "Could not connect to proxy server %s: "
 msgstr "No se pudo conectar al servidor proxy %s: "
 
-#: gio/gsocketclient.c:196
+#: gio/gsocketclient.c:205
 #, c-format
 msgid "Could not connect to %s: "
 msgstr "No se pudo conectar a %s: "
 
-#: gio/gsocketclient.c:198
+#: gio/gsocketclient.c:207
 msgid "Could not connect: "
 msgstr "No se pudo conectar: "
 
-#: gio/gsocketclient.c:1037 gio/gsocketclient.c:1866
-msgid "Unknown error on connect"
-msgstr "Error desconocido al conectar"
-
-#: gio/gsocketclient.c:1091 gio/gsocketclient.c:1668
+#: gio/gsocketclient.c:1162 gio/gsocketclient.c:1749
 msgid "Proxying over a non-TCP connection is not supported."
 msgstr ""
 "No se soporta intentar hacer de proxy sobre una conexión que no es TCP."
 
-#: gio/gsocketclient.c:1120 gio/gsocketclient.c:1698
+#: gio/gsocketclient.c:1194 gio/gsocketclient.c:1778
 #, c-format
 msgid "Proxy protocol “%s” is not supported."
 msgstr "El protocolo del proxy «%s» no está soportado."
@@ -4148,26 +4150,30 @@ msgstr "No se puede resolver «%s» temporalmente"
 msgid "Error resolving “%s”"
 msgstr "Error al resolver «%s»"
 
-#: gio/gtlscertificate.c:243
+#: gio/gtlscertificate.c:298
 msgid "No PEM-encoded private key found"
 msgstr "No se encontró ninguna clave privada codificada con PEM"
 
-#: gio/gtlscertificate.c:253
+#: gio/gtlscertificate.c:308
 msgid "Cannot decrypt PEM-encoded private key"
 msgstr "No se pudo descifrar la clave privada codificada con PEM"
 
-#: gio/gtlscertificate.c:264
+#: gio/gtlscertificate.c:319
 msgid "Could not parse PEM-encoded private key"
 msgstr "No se pudo analizar la clave privada codificada con PEM"
 
-#: gio/gtlscertificate.c:291
+#: gio/gtlscertificate.c:346
 msgid "No PEM-encoded certificate found"
 msgstr "No se encontró ningún certificado codificado con PEM"
 
-#: gio/gtlscertificate.c:300
+#: gio/gtlscertificate.c:355
 msgid "Could not parse PEM-encoded certificate"
 msgstr "No se pudo analizar el certificado codificado con PEM"
 
+#: gio/gtlscertificate.c:710
+msgid "This GTlsBackend does not support creating PKCS #11 certificates"
+msgstr "Este GTlsBackend no soporta crear certificados PKCS #11"
+
 #: gio/gtlspassword.c:111
 msgid ""
 "This is the last chance to enter the password correctly before your access "
@@ -5834,47 +5840,47 @@ msgstr "El proceso hijo se detuvo por la señal %ld"
 msgid "Child process exited abnormally"
 msgstr "El proceso hijo terminó de forma anormal"
 
-#: glib/gspawn.c:1532 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358
+#: glib/gspawn.c:1540 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358
 #, c-format
 msgid "Failed to read from child pipe (%s)"
 msgstr "Falló al leer desde el conducto hijo (%s)"
 
-#: glib/gspawn.c:1788
+#: glib/gspawn.c:1796
 #, c-format
 msgid "Failed to spawn child process “%s” (%s)"
 msgstr "Falló al ejecutar el proceso hijo «%s» (%s)"
 
-#: glib/gspawn.c:1871
+#: glib/gspawn.c:1879
 #, c-format
 msgid "Failed to fork (%s)"
 msgstr "Falló al bifurcar (fork) (%s)"
 
-#: glib/gspawn.c:2026 glib/gspawn-win32.c:381
+#: glib/gspawn.c:2034 glib/gspawn-win32.c:381
 #, c-format
 msgid "Failed to change to directory “%s” (%s)"
 msgstr "Falló al cambiar a la carpeta «%s» (%s)"
 
-#: glib/gspawn.c:2036
+#: glib/gspawn.c:2044
 #, c-format
 msgid "Failed to execute child process “%s” (%s)"
 msgstr "Falló al ejecutar el proceso hijo «%s» (%s)"
 
-#: glib/gspawn.c:2046
+#: glib/gspawn.c:2054
 #, c-format
 msgid "Failed to redirect output or input of child process (%s)"
 msgstr "Falló al redirigir la salida o la entrada del proceso hijo (%s)"
 
-#: glib/gspawn.c:2055
+#: glib/gspawn.c:2063
 #, c-format
 msgid "Failed to fork child process (%s)"
 msgstr "Falló al bifurcar el proceso hijo (%s)"
 
-#: glib/gspawn.c:2063
+#: glib/gspawn.c:2071
 #, c-format
 msgid "Unknown error executing child process “%s”"
 msgstr "Error desconocido al ejecutar el proceso hijo «%s»"
 
-#: glib/gspawn.c:2087
+#: glib/gspawn.c:2095
 #, c-format
 msgid "Failed to read enough data from child pid pipe (%s)"
 msgstr "Falló al leer suficientes datos desde el conducto del pid hijo (%s)"
@@ -5956,52 +5962,45 @@ msgstr "codificación %-e no válida en el URI"
 msgid "Illegal character in URI"
 msgstr "Caracter ilegal en el URI"
 
-#: glib/guri.c:358
+#: glib/guri.c:359
 msgid "Non-UTF-8 characters in URI"
 msgstr "Caracteres no UTF-8 en el URI"
 
-#: glib/guri.c:461
+#: glib/guri.c:538
 #, c-format
-#| msgid "Invalid IPv6 address '%.*s' in URI"
 msgid "Invalid IPv6 address ‘%.*s’ in URI"
 msgstr "Dirección IPv6 «%.*s» no válida en el URI"
 
-#: glib/guri.c:523
+#: glib/guri.c:593
 #, c-format
-#| msgid "Illegal encoded IP address '%.*s' in URI"
 msgid "Illegal encoded IP address ‘%.*s’ in URI"
 msgstr "Dirección IP codificada «%.*s» no válida en el URI"
 
-#: glib/guri.c:557 glib/guri.c:569
+#: glib/guri.c:625 glib/guri.c:637
 #, c-format
-#| msgid "Could not parse port '%.*s' in URI"
 msgid "Could not parse port ‘%.*s’ in URI"
 msgstr "No se pudo analizar el puerto «%.*s» en el URI"
 
-#: glib/guri.c:576
+#: glib/guri.c:644
 #, c-format
-#| msgid "Port '%.*s' in URI is out of range"
 msgid "Port ‘%.*s’ in URI is out of range"
 msgstr "Puerto «%.*s» en el URI fuera de rango"
 
-#: glib/guri.c:1054 glib/guri.c:1118
+#: glib/guri.c:1124 glib/guri.c:1188
 #, c-format
-#| msgid "URI '%s' is not an absolute URI"
 msgid "URI ‘%s’ is not an absolute URI"
 msgstr "El URI «%s» no es un URI absoluto"
 
-#: glib/guri.c:1060
+#: glib/guri.c:1130
 #, c-format
-#| msgid "URI '%s' has no host component"
 msgid "URI ‘%s’ has no host component"
 msgstr "El URI «%s» no tiene componente de equipo"
 
-#: glib/guri.c:1262
+#: glib/guri.c:1335
 msgid "URI is not absolute, and no base URI was provided"
 msgstr "El URI no es absoluto y no se ha proporcionado un URI base"
 
-#: glib/guri.c:2018
-#| msgid "Missing '=' and parameter value"
+#: glib/guri.c:2088
 msgid "Missing ‘=’ and parameter value"
 msgstr "Faltan el «=» y el valor del parámetro"
 
@@ -6023,157 +6022,157 @@ msgid "Character out of range for UTF-16"
 msgstr "El carácter se sale del rango para UTF-16"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2756
+#: glib/gutils.c:2759
 #, c-format
 msgid "%.1f kB"
 msgstr "%.1f kB"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2758
+#: glib/gutils.c:2761
 #, c-format
 msgid "%.1f MB"
 msgstr "%.1f MB"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2760
+#: glib/gutils.c:2763
 #, c-format
 msgid "%.1f GB"
 msgstr "%.1f GB"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2762
+#: glib/gutils.c:2765
 #, c-format
 msgid "%.1f TB"
 msgstr "%.1f TB"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2764
+#: glib/gutils.c:2767
 #, c-format
 msgid "%.1f PB"
 msgstr "%.1f PB"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2766
+#: glib/gutils.c:2769
 #, c-format
 msgid "%.1f EB"
 msgstr "%.1f EB"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2770
+#: glib/gutils.c:2773
 #, c-format
 msgid "%.1f KiB"
 msgstr "%.1f KiB"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2772
+#: glib/gutils.c:2775
 #, c-format
 msgid "%.1f MiB"
 msgstr "%.1f MiB"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2774
+#: glib/gutils.c:2777
 #, c-format
 msgid "%.1f GiB"
 msgstr "%.1f GiB"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2776
+#: glib/gutils.c:2779
 #, c-format
 msgid "%.1f TiB"
 msgstr "%.1f TiB"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2778
+#: glib/gutils.c:2781
 #, c-format
 msgid "%.1f PiB"
 msgstr "%.1f PiB"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2780
+#: glib/gutils.c:2783
 #, c-format
 msgid "%.1f EiB"
 msgstr "%.1f EiB"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2784
+#: glib/gutils.c:2787
 #, c-format
 msgid "%.1f kb"
 msgstr "%.1f kb"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2786
+#: glib/gutils.c:2789
 #, c-format
 msgid "%.1f Mb"
 msgstr "%.1f Mb"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2788
+#: glib/gutils.c:2791
 #, c-format
 msgid "%.1f Gb"
 msgstr "%.1f Gb"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2790
+#: glib/gutils.c:2793
 #, c-format
 msgid "%.1f Tb"
 msgstr "%.1f Tb"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2792
+#: glib/gutils.c:2795
 #, c-format
 msgid "%.1f Pb"
 msgstr "%.1f Pb"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2794
+#: glib/gutils.c:2797
 #, c-format
 msgid "%.1f Eb"
 msgstr "%.1f Eb"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2798
+#: glib/gutils.c:2801
 #, c-format
 msgid "%.1f Kib"
 msgstr "%.1f Kib"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2800
+#: glib/gutils.c:2803
 #, c-format
 msgid "%.1f Mib"
 msgstr "%.1f Mib"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2802
+#: glib/gutils.c:2805
 #, c-format
 msgid "%.1f Gib"
 msgstr "%.1f Gib"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2804
+#: glib/gutils.c:2807
 #, c-format
 msgid "%.1f Tib"
 msgstr "%.1f Tib"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2806
+#: glib/gutils.c:2809
 #, c-format
 msgid "%.1f Pib"
 msgstr "%.1f Pib"
 
 #. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2808
+#: glib/gutils.c:2811
 #, c-format
 msgid "%.1f Eib"
 msgstr "%.1f Eib"
 
-#: glib/gutils.c:2842 glib/gutils.c:2959
+#: glib/gutils.c:2845 glib/gutils.c:2962
 #, c-format
 msgid "%u byte"
 msgid_plural "%u bytes"
 msgstr[0] "%u byte"
 msgstr[1] "%u bytes"
 
-#: glib/gutils.c:2846
+#: glib/gutils.c:2849
 #, c-format
 msgid "%u bit"
 msgid_plural "%u bits"
@@ -6181,7 +6180,7 @@ msgstr[0] "%u bit"
 msgstr[1] "%u bits"
 
 #. Translators: the %s in "%s bytes" will always be replaced by a number.
-#: glib/gutils.c:2913
+#: glib/gutils.c:2916
 #, c-format
 msgid "%s byte"
 msgid_plural "%s bytes"
@@ -6189,7 +6188,7 @@ msgstr[0] "%s byte"
 msgstr[1] "%s bytes"
 
 #. Translators: the %s in "%s bits" will always be replaced by a number.
-#: glib/gutils.c:2918
+#: glib/gutils.c:2921
 #, c-format
 msgid "%s bit"
 msgid_plural "%s bits"
@@ -6201,38 +6200,38 @@ msgstr[1] "%s bits"
 #. * compatibility.  Users will not see this string unless a program is using this deprecated function.
 #. * Please translate as literally as possible.
 #.
-#: glib/gutils.c:2972
+#: glib/gutils.c:2975
 #, c-format
 msgid "%.1f KB"
 msgstr "%.1f KB"
 
-#: glib/gutils.c:2977
+#: glib/gutils.c:2980
 #, c-format
 msgid "%.1f MB"
 msgstr "%.1f MB"
 
-#: glib/gutils.c:2982
+#: glib/gutils.c:2985
 #, c-format
 msgid "%.1f GB"
 msgstr "%.1f GB"
 
-#: glib/gutils.c:2987
+#: glib/gutils.c:2990
 #, c-format
 msgid "%.1f TB"
 msgstr "%.1f TB"
 
-#: glib/gutils.c:2992
+#: glib/gutils.c:2995
 #, c-format
 msgid "%.1f PB"
 msgstr "%.1f PB"
 
-#: glib/gutils.c:2997
+#: glib/gutils.c:3000
 #, c-format
 msgid "%.1f EB"
 msgstr "%.1f EB"
 
-#~ msgid "This GTlsBackend does not support creating PKCS #11 certificates"
-#~ msgstr "Este GTlsBackend no soporta crear certificados PKCS #11"
+#~ msgid "Unknown error on connect"
+#~ msgstr "Error desconocido al conectar"
 
 #~ msgid "Mounted %s at %s\n"
 #~ msgstr "%s montado en %s\n"
index dde6c7c..61a7a45 100644 (file)
--- a/po/uk.po
+++ b/po/uk.po
@@ -10,8 +10,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: glib\n"
 "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n"
-"POT-Creation-Date: 2020-10-01 16:35+0000\n"
-"PO-Revision-Date: 2020-10-01 19:55+0300\n"
+"POT-Creation-Date: 2020-12-07 08:30+0000\n"
+"PO-Revision-Date: 2020-12-07 10:49+0200\n"
 "Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
 "Language-Team: Ukrainian <trans-uk@lists.fedoraproject.org>\n"
 "Language: uk\n"
@@ -107,7 +107,7 @@ msgstr "Вивести перелік статичних дій для прог
 msgid "APPID"
 msgstr "ІД_ПРОГРАМИ"
 
-#: gio/gapplication-tool.c:70 gio/gapplication-tool.c:133 gio/gdbus-tool.c:102
+#: gio/gapplication-tool.c:70 gio/gapplication-tool.c:133 gio/gdbus-tool.c:106
 #: gio/gio-tool.c:224
 msgid "COMMAND"
 msgstr "КОМАНДА"
@@ -285,7 +285,7 @@ msgstr "Потік вже закрито"
 msgid "Truncate not supported on base stream"
 msgstr "Урізання не підтримується у базовому потоці"
 
-#: gio/gcancellable.c:319 gio/gdbusconnection.c:1862 gio/gdbusprivate.c:1413
+#: gio/gcancellable.c:319 gio/gdbusconnection.c:1864 gio/gdbusprivate.c:1416
 #: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897
 #, c-format
 msgid "Operation was cancelled"
@@ -519,7 +519,7 @@ msgid "Cannot determine session bus address (not implemented for this OS)"
 msgstr ""
 "Не вдалося визначити адресу сеансової шини (не реалізовано для цієї ОС)"
 
-#: gio/gdbusaddress.c:1357 gio/gdbusconnection.c:7192
+#: gio/gdbusaddress.c:1357 gio/gdbusconnection.c:7223
 #, c-format
 msgid ""
 "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable "
@@ -528,7 +528,7 @@ msgstr ""
 "Не вдалося визначити адресу шини зі значення змінної середовища "
 "DBUS_STARTER_BUS_TYPE — невідоме значення «%s»"
 
-#: gio/gdbusaddress.c:1366 gio/gdbusconnection.c:7201
+#: gio/gdbusaddress.c:1366 gio/gdbusconnection.c:7232
 msgid ""
 "Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment "
 "variable is not set"
@@ -561,34 +561,44 @@ msgstr ""
 msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer"
 msgstr "Скасовано через GDBusAuthObserver::authorize-authenticated-peer"
 
-#: gio/gdbusauthmechanismsha1.c:296
+#: gio/gdbusauthmechanismsha1.c:298
 #, c-format
 msgid "Error when getting information for directory “%s”: %s"
 msgstr "Помилка при отриманні відомостей для каталогу «%s»: %s"
 
-#: gio/gdbusauthmechanismsha1.c:311
+#: gio/gdbusauthmechanismsha1.c:313
 #, c-format
 msgid ""
 "Permissions on directory “%s” are malformed. Expected mode 0700, got 0%o"
 msgstr "Помилкові права на каталог «%s». Очікуваний режим — 0700, отримано 0%o"
 
-#: gio/gdbusauthmechanismsha1.c:341
+#: gio/gdbusauthmechanismsha1.c:346 gio/gdbusauthmechanismsha1.c:357
 #, c-format
 msgid "Error creating directory “%s”: %s"
 msgstr "Сталася помилка при створенні каталогу «%s»: %s"
 
-#: gio/gdbusauthmechanismsha1.c:386
+#: gio/gdbusauthmechanismsha1.c:359 gio/gfile.c:1044 gio/gfile.c:1282
+#: gio/gfile.c:1420 gio/gfile.c:1658 gio/gfile.c:1713 gio/gfile.c:1771
+#: gio/gfile.c:1855 gio/gfile.c:1912 gio/gfile.c:1976 gio/gfile.c:2031
+#: gio/gfile.c:3745 gio/gfile.c:3800 gio/gfile.c:4093 gio/gfile.c:4563
+#: gio/gfile.c:4974 gio/gfile.c:5059 gio/gfile.c:5149 gio/gfile.c:5246
+#: gio/gfile.c:5333 gio/gfile.c:5434 gio/gfile.c:8144 gio/gfile.c:8234
+#: gio/gfile.c:8318 gio/win32/gwinhttpfile.c:453
+msgid "Operation not supported"
+msgstr "Операція не підтримується"
+
+#: gio/gdbusauthmechanismsha1.c:402
 #, c-format
 msgid "Error opening keyring “%s” for reading: "
 msgstr "Сталася помилка при відкриванні зв'язки ключів «%s» на читання: "
 
-#: gio/gdbusauthmechanismsha1.c:409 gio/gdbusauthmechanismsha1.c:731
+#: gio/gdbusauthmechanismsha1.c:425 gio/gdbusauthmechanismsha1.c:747
 #, c-format
 msgid "Line %d of the keyring at “%s” with content “%s” is malformed"
 msgstr ""
 "Некоректне форматування у рядку %d у зв'язці ключів у «%s» з вмістом «%s»"
 
-#: gio/gdbusauthmechanismsha1.c:423 gio/gdbusauthmechanismsha1.c:745
+#: gio/gdbusauthmechanismsha1.c:439 gio/gdbusauthmechanismsha1.c:761
 #, c-format
 msgid ""
 "First token of line %d of the keyring at “%s” with content “%s” is malformed"
@@ -596,7 +606,7 @@ msgstr ""
 "Некоректне форматування першої лексеми у рядку %d у зв'язці ключів у «%s» з "
 "вмістом «%s»"
 
-#: gio/gdbusauthmechanismsha1.c:437 gio/gdbusauthmechanismsha1.c:759
+#: gio/gdbusauthmechanismsha1.c:453 gio/gdbusauthmechanismsha1.c:775
 #, c-format
 msgid ""
 "Second token of line %d of the keyring at “%s” with content “%s” is malformed"
@@ -604,156 +614,156 @@ msgstr ""
 "Некоректне форматування другої лексеми у рядку %d у зв'язці ключів у «%s» з "
 "вмістом «%s»"
 
-#: gio/gdbusauthmechanismsha1.c:461
+#: gio/gdbusauthmechanismsha1.c:477
 #, c-format
 msgid "Didn’t find cookie with id %d in the keyring at “%s”"
 msgstr "Не вдалося знайти куки з ідентифікатором %d у зв'язці ключів «%s»"
 
-#: gio/gdbusauthmechanismsha1.c:507
+#: gio/gdbusauthmechanismsha1.c:523
 #, c-format
 msgid "Error creating lock file “%s”: %s"
 msgstr "Сталася помилка при створенні файла блокування «%s»: %s"
 
-#: gio/gdbusauthmechanismsha1.c:571
+#: gio/gdbusauthmechanismsha1.c:587
 #, c-format
 msgid "Error deleting stale lock file “%s”: %s"
 msgstr "Сталася помилка при вилученні застарілого файла блокування «%s»: %s"
 
-#: gio/gdbusauthmechanismsha1.c:610
+#: gio/gdbusauthmechanismsha1.c:626
 #, c-format
 msgid "Error closing (unlinked) lock file “%s”: %s"
 msgstr ""
 "Сталася помилка при закриванні (від'єднаного) файла блокування «%s»: %s"
 
-#: gio/gdbusauthmechanismsha1.c:621
+#: gio/gdbusauthmechanismsha1.c:637
 #, c-format
 msgid "Error unlinking lock file “%s”: %s"
 msgstr "Сталася помилка при вилученні файла блокування «%s»: %s"
 
-#: gio/gdbusauthmechanismsha1.c:698
+#: gio/gdbusauthmechanismsha1.c:714
 #, c-format
 msgid "Error opening keyring “%s” for writing: "
 msgstr "Сталася помилка при відкриванні зв'язки ключів «%s» для запису: "
 
-#: gio/gdbusauthmechanismsha1.c:892
+#: gio/gdbusauthmechanismsha1.c:908
 #, c-format
 msgid "(Additionally, releasing the lock for “%s” also failed: %s) "
 msgstr "(Також, не вдалося вивільнити блокування «%s»: %s) "
 
-#: gio/gdbusconnection.c:595 gio/gdbusconnection.c:2391
+#: gio/gdbusconnection.c:595 gio/gdbusconnection.c:2397
 msgid "The connection is closed"
 msgstr "З'єднання закрито"
 
-#: gio/gdbusconnection.c:1892
+#: gio/gdbusconnection.c:1894
 msgid "Timeout was reached"
 msgstr "Час очікування вичерпано"
 
-#: gio/gdbusconnection.c:2513
+#: gio/gdbusconnection.c:2519
 msgid ""
 "Unsupported flags encountered when constructing a client-side connection"
 msgstr "При створенні клієнтського з'єднання виявлено непідтримувані прапорці"
 
-#: gio/gdbusconnection.c:4163 gio/gdbusconnection.c:4510
+#: gio/gdbusconnection.c:4169 gio/gdbusconnection.c:4516
 #, c-format
 msgid ""
 "No such interface “org.freedesktop.DBus.Properties” on object at path %s"
 msgstr ""
 "Інтерфейс «org.freedesktop.DBus.Properties» для шляху об'єкта %s не знайдено"
 
-#: gio/gdbusconnection.c:4305
+#: gio/gdbusconnection.c:4311
 #, c-format
 msgid "No such property “%s”"
 msgstr "Немає властивості «%s»"
 
-#: gio/gdbusconnection.c:4317
+#: gio/gdbusconnection.c:4323
 #, c-format
 msgid "Property “%s” is not readable"
 msgstr "Властивість «%s» недоступна для читання"
 
-#: gio/gdbusconnection.c:4328
+#: gio/gdbusconnection.c:4334
 #, c-format
 msgid "Property “%s” is not writable"
 msgstr "Властивість «%s» недоступна для запису"
 
-#: gio/gdbusconnection.c:4348
+#: gio/gdbusconnection.c:4354
 #, c-format
 msgid "Error setting property “%s”: Expected type “%s” but got “%s”"
 msgstr ""
 "Помилка встановлення властивості «%s». Мало бути використано тип «%s», але "
 "отримано «%s»"
 
-#: gio/gdbusconnection.c:4453 gio/gdbusconnection.c:4661
-#: gio/gdbusconnection.c:6632
+#: gio/gdbusconnection.c:4459 gio/gdbusconnection.c:4667
+#: gio/gdbusconnection.c:6663
 #, c-format
 msgid "No such interface “%s”"
 msgstr "Немає інтерфейсу «%s»"
 
-#: gio/gdbusconnection.c:4879 gio/gdbusconnection.c:7141
+#: gio/gdbusconnection.c:4885 gio/gdbusconnection.c:7172
 #, c-format
 msgid "No such interface “%s” on object at path %s"
 msgstr "Немає інтерфейсу «%s» на об'єкті зі шляхом %s"
 
-#: gio/gdbusconnection.c:4977
+#: gio/gdbusconnection.c:4983
 #, c-format
 msgid "No such method “%s”"
 msgstr "Немає методу «%s»"
 
-#: gio/gdbusconnection.c:5008
+#: gio/gdbusconnection.c:5014
 #, c-format
 msgid "Type of message, “%s”, does not match expected type “%s”"
 msgstr "Тип повідомлення «%s» не збігається з очікуваним типом «%s»"
 
-#: gio/gdbusconnection.c:5206
+#: gio/gdbusconnection.c:5212
 #, c-format
 msgid "An object is already exported for the interface %s at %s"
 msgstr "Об'єкт інтерфейсу %s вже експортовано як %s"
 
-#: gio/gdbusconnection.c:5432
+#: gio/gdbusconnection.c:5438
 #, c-format
 msgid "Unable to retrieve property %s.%s"
 msgstr "Не вдалося отримати властивість %s.%s"
 
-#: gio/gdbusconnection.c:5488
+#: gio/gdbusconnection.c:5494
 #, c-format
 msgid "Unable to set property %s.%s"
 msgstr "Не вдалося встановити значення властивості %s.%s"
 
-#: gio/gdbusconnection.c:5666
+#: gio/gdbusconnection.c:5672
 #, c-format
 msgid "Method “%s” returned type “%s”, but expected “%s”"
 msgstr "Метод «%s» повернув тип «%s», але очікувалося «%s»"
 
-#: gio/gdbusconnection.c:6743
+#: gio/gdbusconnection.c:6774
 #, c-format
 msgid "Method “%s” on interface “%s” with signature “%s” does not exist"
 msgstr "Методу «%s» інтерфейсу «%s» з підписом «%s» не існує"
 
-#: gio/gdbusconnection.c:6864
+#: gio/gdbusconnection.c:6895
 #, c-format
 msgid "A subtree is already exported for %s"
 msgstr "Піддерево вже експортовано для %s"
 
-#: gio/gdbusmessage.c:1255
+#: gio/gdbusmessage.c:1266
 msgid "type is INVALID"
 msgstr "НЕПРАВИЛЬНИЙ тип"
 
-#: gio/gdbusmessage.c:1266
+#: gio/gdbusmessage.c:1277
 msgid "METHOD_CALL message: PATH or MEMBER header field is missing"
 msgstr "Повідомлення METHOD_CALL: немає поля заголовка PATH або MEMBER"
 
-#: gio/gdbusmessage.c:1277
+#: gio/gdbusmessage.c:1288
 msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing"
 msgstr "Повідомлення METHOD_RETURN: немає поля заголовка REPLY_SERIAL"
 
-#: gio/gdbusmessage.c:1289
+#: gio/gdbusmessage.c:1300
 msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing"
 msgstr "Повідомлення ERROR: немає поля заголовка REPLY_SERIAL або ERROR_NAME"
 
-#: gio/gdbusmessage.c:1302
+#: gio/gdbusmessage.c:1313
 msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing"
 msgstr "Повідомлення SIGNAL: немає поля заголовка PATH, INTERFACE або MEMBER"
 
-#: gio/gdbusmessage.c:1310
+#: gio/gdbusmessage.c:1321
 msgid ""
 "SIGNAL message: The PATH header field is using the reserved value /org/"
 "freedesktop/DBus/Local"
@@ -761,7 +771,7 @@ msgstr ""
 "Повідомлення SIGNAL: поле заголовка PATH використовує зарезервоване "
 "значення /org/freedesktop/DBus/Local"
 
-#: gio/gdbusmessage.c:1318
+#: gio/gdbusmessage.c:1329
 msgid ""
 "SIGNAL message: The INTERFACE header field is using the reserved value org."
 "freedesktop.DBus.Local"
@@ -769,7 +779,7 @@ msgstr ""
 "Повідомлення SIGNAL: поле заголовка INTERFACE використовує зарезервоване "
 "значення org.freedesktop.DBus.Local"
 
-#: gio/gdbusmessage.c:1366 gio/gdbusmessage.c:1426
+#: gio/gdbusmessage.c:1377 gio/gdbusmessage.c:1437
 #, c-format
 msgid "Wanted to read %lu byte but only got %lu"
 msgid_plural "Wanted to read %lu bytes but only got %lu"
@@ -777,12 +787,12 @@ msgstr[0] "Потрібно було прочитати %lu байт, але п
 msgstr[1] "Потрібно було прочитати %lu байти, але прочитано лише %lu"
 msgstr[2] "Потрібно було прочитати %lu байтів, але прочитано лише %lu"
 
-#: gio/gdbusmessage.c:1380
+#: gio/gdbusmessage.c:1391
 #, c-format
 msgid "Expected NUL byte after the string “%s” but found byte %d"
 msgstr "Мало бути використано байт NUL після рядка «%s», але знайдено байт %d"
 
-#: gio/gdbusmessage.c:1399
+#: gio/gdbusmessage.c:1410
 #, c-format
 msgid ""
 "Expected valid UTF-8 string but found invalid bytes at byte offset %d "
@@ -792,21 +802,21 @@ msgstr ""
 "(зміщення %d, довжина рядка %d). Коректний рядок UTF-8 аж до цієї миті був "
 "таким: «%s»"
 
-#: gio/gdbusmessage.c:1463 gio/gdbusmessage.c:1711 gio/gdbusmessage.c:1900
+#: gio/gdbusmessage.c:1474 gio/gdbusmessage.c:1722 gio/gdbusmessage.c:1911
 msgid "Value nested too deeply"
 msgstr "Рівень вкладеності значення є надто високим"
 
-#: gio/gdbusmessage.c:1609
+#: gio/gdbusmessage.c:1620
 #, c-format
 msgid "Parsed value “%s” is not a valid D-Bus object path"
 msgstr "Оброблене значення «%s» не є припустимим шляхом до об'єкта D-Bus"
 
-#: gio/gdbusmessage.c:1631
+#: gio/gdbusmessage.c:1642
 #, c-format
 msgid "Parsed value “%s” is not a valid D-Bus signature"
 msgstr "Оброблене значення «%s» не є припустимим підписом D-Bus"
 
-#: gio/gdbusmessage.c:1678
+#: gio/gdbusmessage.c:1689
 #, c-format
 msgid ""
 "Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)."
@@ -822,7 +832,7 @@ msgstr[2] ""
 "Виявлено масив довжиною %u байтів. Максимальна довжина дорівнює 2<<26 байт "
 "(64 МіБ)."
 
-#: gio/gdbusmessage.c:1698
+#: gio/gdbusmessage.c:1709
 #, c-format
 msgid ""
 "Encountered array of type “a%c”, expected to have a length a multiple of %u "
@@ -831,19 +841,19 @@ msgstr ""
 "Виявлено масив типу «a%c». Очікувалося, що довжина буде кратною до %u "
 "байтів, втім, виявлено довжину %u байтів"
 
-#: gio/gdbusmessage.c:1884
+#: gio/gdbusmessage.c:1895
 #, c-format
 msgid "Parsed value “%s” for variant is not a valid D-Bus signature"
 msgstr "Оброблене значення «%s» для варіанта не є припустимим підписом D-Bus"
 
-#: gio/gdbusmessage.c:1925
+#: gio/gdbusmessage.c:1936
 #, c-format
 msgid ""
 "Error deserializing GVariant with type string “%s” from the D-Bus wire format"
 msgstr ""
 "Помилка десеріалізації GVariant з типом рядка «%s» з формату D-Bus wire"
 
-#: gio/gdbusmessage.c:2110
+#: gio/gdbusmessage.c:2121
 #, c-format
 msgid ""
 "Invalid endianness value. Expected 0x6c (“l”) or 0x42 (“B”) but found value "
@@ -852,29 +862,29 @@ msgstr ""
 "Неправильний порядок байтів у значенні. Мало бути 0x6c («l») або 0x42 («B»), "
 "але знайдено значення 0x%02x"
 
-#: gio/gdbusmessage.c:2123
+#: gio/gdbusmessage.c:2134
 #, c-format
 msgid "Invalid major protocol version. Expected 1 but found %d"
 msgstr ""
 "Неправильний старший номер версії протоколу. Очікувався 1, але знайдено %d"
 
-#: gio/gdbusmessage.c:2177 gio/gdbusmessage.c:2773
+#: gio/gdbusmessage.c:2188 gio/gdbusmessage.c:2784
 msgid "Signature header found but is not of type signature"
 msgstr ""
 "Виявлено заголовок підпису, але цей заголовок не належить до типу підписів"
 
-#: gio/gdbusmessage.c:2189
+#: gio/gdbusmessage.c:2200
 #, c-format
 msgid "Signature header with signature “%s” found but message body is empty"
 msgstr ""
 "Знайдено заголовок підпису з підписом «%s», але вміст повідомлення є порожнім"
 
-#: gio/gdbusmessage.c:2204
+#: gio/gdbusmessage.c:2215
 #, c-format
 msgid "Parsed value “%s” is not a valid D-Bus signature (for body)"
 msgstr "Оброблене значення «%s» не є припустимим підписом D-Bus (для вмісту)"
 
-#: gio/gdbusmessage.c:2236
+#: gio/gdbusmessage.c:2247
 #, c-format
 msgid "No signature header in message but the message body is %u byte"
 msgid_plural "No signature header in message but the message body is %u bytes"
@@ -888,17 +898,17 @@ msgstr[2] ""
 "Відсутній заголовок підпису у повідомленні, але тіло повідомлення займає %u "
 "байтів"
 
-#: gio/gdbusmessage.c:2246
+#: gio/gdbusmessage.c:2257
 msgid "Cannot deserialize message: "
 msgstr "Не вдалося виконати десеріалізацію повідомлення:"
 
-#: gio/gdbusmessage.c:2590
+#: gio/gdbusmessage.c:2601
 #, c-format
 msgid ""
 "Error serializing GVariant with type string “%s” to the D-Bus wire format"
 msgstr "Помилка серіалізації GVariant з типом рядка «%s» у формат D-Bus wire"
 
-#: gio/gdbusmessage.c:2727
+#: gio/gdbusmessage.c:2738
 #, c-format
 msgid ""
 "Number of file descriptors in message (%d) differs from header field (%d)"
@@ -906,16 +916,16 @@ msgstr ""
 "Кількість дескрипторів файлів у повідомленні (%d) відрізняється від значення "
 "у полі заголовка (%d)"
 
-#: gio/gdbusmessage.c:2735
+#: gio/gdbusmessage.c:2746
 msgid "Cannot serialize message: "
 msgstr "Не вдалося серіалізувати повідомлення: "
 
-#: gio/gdbusmessage.c:2788
+#: gio/gdbusmessage.c:2799
 #, c-format
 msgid "Message body has signature “%s” but there is no signature header"
 msgstr "Вміст повідомлення має підпис «%s», але немає заголовка підпису"
 
-#: gio/gdbusmessage.c:2798
+#: gio/gdbusmessage.c:2809
 #, c-format
 msgid ""
 "Message body has type signature “%s” but signature in the header field is "
@@ -924,38 +934,38 @@ msgstr ""
 "Вміст повідомлення має тип підпису «%s», але значення підпису у полі "
 "заголовка дорівнює «%s»"
 
-#: gio/gdbusmessage.c:2814
+#: gio/gdbusmessage.c:2825
 #, c-format
 msgid "Message body is empty but signature in the header field is “(%s)”"
 msgstr ""
 "Вміст повідомлення порожній, але значення підпису у полі заголовка дорівнює "
 "«(%s)»"
 
-#: gio/gdbusmessage.c:3367
+#: gio/gdbusmessage.c:3378
 #, c-format
 msgid "Error return with body of type “%s”"
 msgstr "Повернуто помилку для вмісту типу «%s»"
 
-#: gio/gdbusmessage.c:3375
+#: gio/gdbusmessage.c:3386
 msgid "Error return with empty body"
 msgstr "Повернена помилка з порожнім тілом"
 
-#: gio/gdbusprivate.c:2244
+#: gio/gdbusprivate.c:2246
 #, c-format
 msgid "(Type any character to close this window)\n"
 msgstr "(Щоб закрити це вікно, уведіть будь-який символ)\n"
 
-#: gio/gdbusprivate.c:2418
+#: gio/gdbusprivate.c:2420
 #, c-format
 msgid "Session dbus not running, and autolaunch failed"
 msgstr "Сеанс dbus не запущений, і автозапуск не виконався"
 
-#: gio/gdbusprivate.c:2441
+#: gio/gdbusprivate.c:2443
 #, c-format
 msgid "Unable to get Hardware profile: %s"
 msgstr "Не вдалося отримати профіль апаратури: %s"
 
-#: gio/gdbusprivate.c:2486
+#: gio/gdbusprivate.c:2488
 msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: "
 msgstr "Не вдалося завантажити /var/lib/dbus/machine-id або /etc/machine-id: "
 
@@ -1002,7 +1012,7 @@ msgstr "Рядок «%s» не є припустимим GUID D-Bus"
 msgid "Cannot listen on unsupported transport “%s”"
 msgstr "Неможливо очікувати на дані на каналі передавання «%s», якого не існує"
 
-#: gio/gdbus-tool.c:107
+#: gio/gdbus-tool.c:111
 #, c-format
 msgid ""
 "Commands:\n"
@@ -1025,60 +1035,60 @@ msgstr ""
 "\n"
 "Для отримання довідки за командою використовуйте «%s КОМАНДА --help».\n"
 
-#: gio/gdbus-tool.c:197 gio/gdbus-tool.c:264 gio/gdbus-tool.c:336
-#: gio/gdbus-tool.c:360 gio/gdbus-tool.c:850 gio/gdbus-tool.c:1187
-#: gio/gdbus-tool.c:1672
+#: gio/gdbus-tool.c:201 gio/gdbus-tool.c:268 gio/gdbus-tool.c:340
+#: gio/gdbus-tool.c:364 gio/gdbus-tool.c:854 gio/gdbus-tool.c:1231
+#: gio/gdbus-tool.c:1719
 #, c-format
 msgid "Error: %s\n"
 msgstr "Помилка: %s\n"
 
-#: gio/gdbus-tool.c:208 gio/gdbus-tool.c:277 gio/gdbus-tool.c:1688
+#: gio/gdbus-tool.c:212 gio/gdbus-tool.c:281 gio/gdbus-tool.c:1735
 #, c-format
 msgid "Error parsing introspection XML: %s\n"
 msgstr "Сталася помилка під час обробки інтроспекції XML: %s\n"
 
-#: gio/gdbus-tool.c:246
+#: gio/gdbus-tool.c:250
 #, c-format
 msgid "Error: %s is not a valid name\n"
 msgstr "Помилка: %s не є припустимою назвою\n"
 
-#: gio/gdbus-tool.c:394
+#: gio/gdbus-tool.c:398
 msgid "Connect to the system bus"
 msgstr "Під'єднатися до системної шини"
 
-#: gio/gdbus-tool.c:395
+#: gio/gdbus-tool.c:399
 msgid "Connect to the session bus"
 msgstr "Під'єднатися до користувацької шини"
 
-#: gio/gdbus-tool.c:396
+#: gio/gdbus-tool.c:400
 msgid "Connect to given D-Bus address"
 msgstr "Під'єднатися до вказаної адреси D-Bus"
 
-#: gio/gdbus-tool.c:406
+#: gio/gdbus-tool.c:410
 msgid "Connection Endpoint Options:"
 msgstr "Параметри кінцевої точки з'єднання:"
 
-#: gio/gdbus-tool.c:407
+#: gio/gdbus-tool.c:411
 msgid "Options specifying the connection endpoint"
 msgstr "Параметри, що визначають кінцеву точку з'єднання"
 
-#: gio/gdbus-tool.c:430
+#: gio/gdbus-tool.c:434
 #, c-format
 msgid "No connection endpoint specified"
 msgstr "Кінцева точка з'єднання не вказана"
 
-#: gio/gdbus-tool.c:440
+#: gio/gdbus-tool.c:444
 #, c-format
 msgid "Multiple connection endpoints specified"
 msgstr "Вказано декілька кінцевих точок з'єднання"
 
-#: gio/gdbus-tool.c:513
+#: gio/gdbus-tool.c:517
 #, c-format
 msgid ""
 "Warning: According to introspection data, interface “%s” does not exist\n"
 msgstr "Попередження: згідно з даними інтроспекції, інтерфейсу «%s» не існує\n"
 
-#: gio/gdbus-tool.c:522
+#: gio/gdbus-tool.c:526
 #, c-format
 msgid ""
 "Warning: According to introspection data, method “%s” does not exist on "
@@ -1087,164 +1097,169 @@ msgstr ""
 "Попередження: згідно з даними інтроспекції, методу «%s» в інтерфейсі «%s» не "
 "існує\n"
 
-#: gio/gdbus-tool.c:584
+#: gio/gdbus-tool.c:588
 msgid "Optional destination for signal (unique name)"
 msgstr "Необов'язковий отримувач сигналу (унікальна назва)"
 
-#: gio/gdbus-tool.c:585
+#: gio/gdbus-tool.c:589
 msgid "Object path to emit signal on"
 msgstr "Об'єктний шлях, для випуску сигналу"
 
-#: gio/gdbus-tool.c:586
+#: gio/gdbus-tool.c:590
 msgid "Signal and interface name"
 msgstr "Назва сигналу і інтерфейсу"
 
-#: gio/gdbus-tool.c:619
+#: gio/gdbus-tool.c:623
 msgid "Emit a signal."
 msgstr "Послати сигнал."
 
-#: gio/gdbus-tool.c:674 gio/gdbus-tool.c:981 gio/gdbus-tool.c:1775
-#: gio/gdbus-tool.c:2007 gio/gdbus-tool.c:2227
+#: gio/gdbus-tool.c:678 gio/gdbus-tool.c:992 gio/gdbus-tool.c:1822
+#: gio/gdbus-tool.c:2054 gio/gdbus-tool.c:2274
 #, c-format
 msgid "Error connecting: %s\n"
 msgstr "Сталася помилка при з'єднанні: %s\n"
 
-#: gio/gdbus-tool.c:694
+#: gio/gdbus-tool.c:698
 #, c-format
 msgid "Error: %s is not a valid unique bus name.\n"
 msgstr "Помилка: %s не є припустимою унікальною назвою шини.\n"
 
-#: gio/gdbus-tool.c:713 gio/gdbus-tool.c:1024 gio/gdbus-tool.c:1818
+#: gio/gdbus-tool.c:717 gio/gdbus-tool.c:1035 gio/gdbus-tool.c:1865
 msgid "Error: Object path is not specified\n"
 msgstr "Помилка: не вказано об'єктний шлях\n"
 
-#: gio/gdbus-tool.c:736 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1838
-#: gio/gdbus-tool.c:2078
+#: gio/gdbus-tool.c:740 gio/gdbus-tool.c:1055 gio/gdbus-tool.c:1885
+#: gio/gdbus-tool.c:2125
 #, c-format
 msgid "Error: %s is not a valid object path\n"
 msgstr "Помилка: %s не є припустимим об'єктним шляхом\n"
 
-#: gio/gdbus-tool.c:756
+#: gio/gdbus-tool.c:760
 msgid "Error: Signal name is not specified\n"
 msgstr "Помилка: не вказано назви сигналу\n"
 
-#: gio/gdbus-tool.c:770
+#: gio/gdbus-tool.c:774
 #, c-format
 msgid "Error: Signal name “%s” is invalid\n"
 msgstr "Помилка: некоректна назва сигналу «%s»\n"
 
-#: gio/gdbus-tool.c:782
+#: gio/gdbus-tool.c:786
 #, c-format
 msgid "Error: %s is not a valid interface name\n"
 msgstr "Помилка: %s не є припустимою назвою інтерфейсу\n"
 
-#: gio/gdbus-tool.c:788
+#: gio/gdbus-tool.c:792
 #, c-format
 msgid "Error: %s is not a valid member name\n"
 msgstr "Помилка: %s не є припустимою назвою члену\n"
 
 #. Use the original non-"parse-me-harder" error
-#: gio/gdbus-tool.c:825 gio/gdbus-tool.c:1156
+#: gio/gdbus-tool.c:829 gio/gdbus-tool.c:1167
 #, c-format
 msgid "Error parsing parameter %d: %s\n"
 msgstr "Сталася помилка під час обробки параметра %d: %s\n"
 
-#: gio/gdbus-tool.c:857
+#: gio/gdbus-tool.c:861
 #, c-format
 msgid "Error flushing connection: %s\n"
 msgstr "Сталася помилка при скиданні під'єднання: %s\n"
 
-#: gio/gdbus-tool.c:884
+#: gio/gdbus-tool.c:888
 msgid "Destination name to invoke method on"
 msgstr "Назва призначення, для якого викликається метод"
 
-#: gio/gdbus-tool.c:885
+#: gio/gdbus-tool.c:889
 msgid "Object path to invoke method on"
 msgstr "Об'єктний шлях, для якого викликається метод"
 
-#: gio/gdbus-tool.c:886
+#: gio/gdbus-tool.c:890
 msgid "Method and interface name"
 msgstr "Назва методу або інтерфейсу"
 
-#: gio/gdbus-tool.c:887
+#: gio/gdbus-tool.c:891
 msgid "Timeout in seconds"
 msgstr "Час очікування у секундах"
 
-#: gio/gdbus-tool.c:926
+#: gio/gdbus-tool.c:937
 msgid "Invoke a method on a remote object."
 msgstr "Викликає метод на віддаленому об'єкті."
 
-#: gio/gdbus-tool.c:998 gio/gdbus-tool.c:1792 gio/gdbus-tool.c:2032
+#: gio/gdbus-tool.c:1009 gio/gdbus-tool.c:1839 gio/gdbus-tool.c:2079
 msgid "Error: Destination is not specified\n"
 msgstr "Помилка: не вказано призначення\n"
 
-#: gio/gdbus-tool.c:1009 gio/gdbus-tool.c:1809 gio/gdbus-tool.c:2043
+#: gio/gdbus-tool.c:1020 gio/gdbus-tool.c:1856 gio/gdbus-tool.c:2090
 #, c-format
 msgid "Error: %s is not a valid bus name\n"
 msgstr "Помилка: %s не є припустимою назвою шини\n"
 
-#: gio/gdbus-tool.c:1059
+#: gio/gdbus-tool.c:1070
 msgid "Error: Method name is not specified\n"
 msgstr "Помилка: не вказано назви методу\n"
 
-#: gio/gdbus-tool.c:1070
+#: gio/gdbus-tool.c:1081
 #, c-format
 msgid "Error: Method name “%s” is invalid\n"
 msgstr "Помилка: некоректна назва методу «%s»\n"
 
-#: gio/gdbus-tool.c:1148
+#: gio/gdbus-tool.c:1159
 #, c-format
 msgid "Error parsing parameter %d of type “%s”: %s\n"
 msgstr "Сталася помилка під час обробки параметра %d типу «%s»: %s\n"
 
-#: gio/gdbus-tool.c:1634
+#: gio/gdbus-tool.c:1185
+#, c-format
+msgid "Error adding handle %d: %s\n"
+msgstr "Помилка під час додавання елемента керування %d: %s\n"
+
+#: gio/gdbus-tool.c:1681
 msgid "Destination name to introspect"
 msgstr "Назва призначення для інтроспекції"
 
-#: gio/gdbus-tool.c:1635
+#: gio/gdbus-tool.c:1682
 msgid "Object path to introspect"
 msgstr "Об'єктний шлях для інтроспекції"
 
-#: gio/gdbus-tool.c:1636
+#: gio/gdbus-tool.c:1683
 msgid "Print XML"
 msgstr "Надрукувати XML"
 
-#: gio/gdbus-tool.c:1637
+#: gio/gdbus-tool.c:1684
 msgid "Introspect children"
 msgstr "Інтроспекція нащадка"
 
-#: gio/gdbus-tool.c:1638
+#: gio/gdbus-tool.c:1685
 msgid "Only print properties"
 msgstr "Лише властивості друку"
 
-#: gio/gdbus-tool.c:1727
+#: gio/gdbus-tool.c:1774
 msgid "Introspect a remote object."
 msgstr "Виконати інтроспекцію віддаленого об'єкту."
 
-#: gio/gdbus-tool.c:1933
+#: gio/gdbus-tool.c:1980
 msgid "Destination name to monitor"
 msgstr "Назва призначення для спостерігання"
 
-#: gio/gdbus-tool.c:1934
+#: gio/gdbus-tool.c:1981
 msgid "Object path to monitor"
 msgstr "Об'єктний шлях для спостерігання"
 
-#: gio/gdbus-tool.c:1959
+#: gio/gdbus-tool.c:2006
 msgid "Monitor a remote object."
 msgstr "Спостерігати за віддаленим об'єктом."
 
-#: gio/gdbus-tool.c:2017
+#: gio/gdbus-tool.c:2064
 msgid "Error: can’t monitor a non-message-bus connection\n"
 msgstr ""
 "Помилка: спостереження за з'єднанням, яке не належить до типу message-bus, є "
 "неможливим\n"
 
-#: gio/gdbus-tool.c:2141
+#: gio/gdbus-tool.c:2188
 msgid "Service to activate before waiting for the other one (well-known name)"
 msgstr ""
 "Служба, яку слід активувати, перш ніж очікувати на іншу (добре відома назва)"
 
-#: gio/gdbus-tool.c:2144
+#: gio/gdbus-tool.c:2191
 msgid ""
 "Timeout to wait for before exiting with an error (seconds); 0 for no timeout "
 "(default)"
@@ -1252,27 +1267,27 @@ msgstr ""
 "Час очікування до виходу із станом помилки (у секундах); 0 — не очікувати "
 "(типова поведінка)"
 
-#: gio/gdbus-tool.c:2192
+#: gio/gdbus-tool.c:2239
 msgid "[OPTION…] BUS-NAME"
 msgstr "[ПАРАМЕТР…] НАЗВА-ШИНИ"
 
-#: gio/gdbus-tool.c:2193
+#: gio/gdbus-tool.c:2240
 msgid "Wait for a bus name to appear."
 msgstr "Очікувати на появу назви шини."
 
-#: gio/gdbus-tool.c:2269
+#: gio/gdbus-tool.c:2316
 msgid "Error: A service to activate for must be specified.\n"
 msgstr "Помилка: має бути вказано службу для активації.\n"
 
-#: gio/gdbus-tool.c:2274
+#: gio/gdbus-tool.c:2321
 msgid "Error: A service to wait for must be specified.\n"
 msgstr "Помилка: має бути вказано службу для очікування.\n"
 
-#: gio/gdbus-tool.c:2279
+#: gio/gdbus-tool.c:2326
 msgid "Error: Too many arguments.\n"
 msgstr "Помилка: забагато аргументів.\n"
 
-#: gio/gdbus-tool.c:2287 gio/gdbus-tool.c:2294
+#: gio/gdbus-tool.c:2334 gio/gdbus-tool.c:2341
 #, c-format
 msgid "Error: %s is not a valid well-known bus name.\n"
 msgstr "Помилка: %s не є припустимим добре відомою назвою шини.\n"
@@ -1373,16 +1388,6 @@ msgstr "Неправильна кількість лексем (%d) у коду
 msgid "Expected a GEmblem for GEmblemedIcon"
 msgstr "Очікується GEmblem для GEmblemedIcon"
 
-#: gio/gfile.c:1044 gio/gfile.c:1282 gio/gfile.c:1420 gio/gfile.c:1658
-#: gio/gfile.c:1713 gio/gfile.c:1771 gio/gfile.c:1855 gio/gfile.c:1912
-#: gio/gfile.c:1976 gio/gfile.c:2031 gio/gfile.c:3722 gio/gfile.c:3777
-#: gio/gfile.c:4070 gio/gfile.c:4540 gio/gfile.c:4951 gio/gfile.c:5036
-#: gio/gfile.c:5126 gio/gfile.c:5223 gio/gfile.c:5310 gio/gfile.c:5411
-#: gio/gfile.c:8121 gio/gfile.c:8211 gio/gfile.c:8295
-#: gio/win32/gwinhttpfile.c:453
-msgid "Operation not supported"
-msgstr "Операція не підтримується"
-
 #. Translators: This is an error message when
 #. * trying to find the enclosing (user visible)
 #. * mount of a file, but none exists.
@@ -1391,7 +1396,7 @@ msgstr "Операція не підтримується"
 msgid "Containing mount does not exist"
 msgstr "Вкладена точка монтування не існує"
 
-#: gio/gfile.c:2590 gio/glocalfile.c:2430
+#: gio/gfile.c:2590 gio/glocalfile.c:2449
 msgid "Can’t copy over directory"
 msgstr "Не можна копіювати із заміною каталогу"
 
@@ -1407,54 +1412,54 @@ msgstr "Цільовий файл існує"
 msgid "Can’t recursively copy directory"
 msgstr "Не вдалося скопіювати каталог рекурсивно"
 
-#: gio/gfile.c:2952
+#: gio/gfile.c:2978
 msgid "Splice not supported"
 msgstr "З'єднання не підтримується"
 
-#: gio/gfile.c:2956 gio/gfile.c:3001
+#: gio/gfile.c:2982 gio/gfile.c:3027
 #, c-format
 msgid "Error splicing file: %s"
 msgstr "Помилка при розрізанні файла: %s"
 
-#: gio/gfile.c:3117
+#: gio/gfile.c:3143
 msgid "Copy (reflink/clone) between mounts is not supported"
 msgstr "Копіювання (reflink/clone) між точками монтування не підтримується"
 
-#: gio/gfile.c:3121
+#: gio/gfile.c:3147
 msgid "Copy (reflink/clone) is not supported or invalid"
 msgstr "Копіювання (reflink/clone) не підтримується або некоректне"
 
-#: gio/gfile.c:3126
+#: gio/gfile.c:3152
 msgid "Copy (reflink/clone) is not supported or didn’t work"
 msgstr ""
 "Підтримки копіювання (reflink/clone) не передбачено або копіювання не працює"
 
-#: gio/gfile.c:3190
+#: gio/gfile.c:3217
 msgid "Can’t copy special file"
 msgstr "Не вдалося скопіювати спеціальний файл"
 
-#: gio/gfile.c:4003
+#: gio/gfile.c:4026
 msgid "Invalid symlink value given"
 msgstr "Неправильне значення символьного посилання"
 
-#: gio/gfile.c:4013 glib/gfileutils.c:2349
+#: gio/gfile.c:4036 glib/gfileutils.c:2349
 msgid "Symbolic links not supported"
 msgstr "Символічні посилання не підтримуються"
 
-#: gio/gfile.c:4181
+#: gio/gfile.c:4204
 msgid "Trash not supported"
 msgstr "Смітник не підтримується"
 
-#: gio/gfile.c:4293
+#: gio/gfile.c:4316
 #, c-format
 msgid "File names cannot contain “%c”"
 msgstr "Назви файлів не можуть містити символу «%c»"
 
-#: gio/gfile.c:6774 gio/gvolume.c:364
+#: gio/gfile.c:6797 gio/gvolume.c:364
 msgid "volume doesn’t implement mount"
 msgstr "для тому не реалізовано операцію монтування"
 
-#: gio/gfile.c:6888 gio/gfile.c:6936
+#: gio/gfile.c:6911 gio/gfile.c:6959
 msgid "No application is registered as handling this file"
 msgstr "Програм для обробки таких файлів не зареєстровано"
 
@@ -1471,12 +1476,12 @@ msgstr "Лічильник файлів має невиконані операц
 msgid "File enumerator is already closed"
 msgstr "Лічильник файлів вже закритий"
 
-#: gio/gfileicon.c:236
+#: gio/gfileicon.c:250
 #, c-format
 msgid "Can’t handle version %d of GFileIcon encoding"
 msgstr "Підтримки версії %d кодування GFileIcon не передбачено"
 
-#: gio/gfileicon.c:246
+#: gio/gfileicon.c:260
 msgid "Malformed input data for GFileIcon"
 msgstr "Неправильні вхідні дані GFileIcon"
 
@@ -2939,8 +2944,8 @@ msgstr "Помилка при перейменуванні файла %s: %s"
 msgid "Can’t rename file, filename already exists"
 msgstr "Не вдалося перейменувати файл, файл із також назвою вже існує"
 
-#: gio/glocalfile.c:1182 gio/glocalfile.c:2324 gio/glocalfile.c:2352
-#: gio/glocalfile.c:2491 gio/glocalfileoutputstream.c:650
+#: gio/glocalfile.c:1182 gio/glocalfile.c:2343 gio/glocalfile.c:2371
+#: gio/glocalfile.c:2510 gio/glocalfileoutputstream.c:650
 msgid "Invalid filename"
 msgstr "Некоректна назва файла"
 
@@ -2954,94 +2959,94 @@ msgstr "Помилка при відкритті файла «%s»: %s"
 msgid "Error removing file %s: %s"
 msgstr "Помилка під час спроби вилучити файл %s: %s"
 
-#: gio/glocalfile.c:1969
+#: gio/glocalfile.c:1980 gio/glocalfile.c:1991
 #, c-format
 msgid "Error trashing file %s: %s"
 msgstr "Помилка під час спроби надіслати файл %s до смітника: %s"
 
-#: gio/glocalfile.c:2010
+#: gio/glocalfile.c:2029
 #, c-format
 msgid "Unable to create trash dir %s: %s"
 msgstr "Помилка при створенні каталогу смітника %s: %s"
 
-#: gio/glocalfile.c:2030
+#: gio/glocalfile.c:2049
 #, c-format
 msgid "Unable to find toplevel directory to trash %s"
 msgstr "Не вдалося знайти каталог верхнього рівня для смітника %s"
 
-#: gio/glocalfile.c:2038
+#: gio/glocalfile.c:2057
 #, c-format
 msgid "Trashing on system internal mounts is not supported"
 msgstr ""
 "Підтримки надсилання до смітника на внутрішніх точках монтування системи не "
 "передбачено"
 
-#: gio/glocalfile.c:2118 gio/glocalfile.c:2138
+#: gio/glocalfile.c:2137 gio/glocalfile.c:2157
 #, c-format
 msgid "Unable to find or create trash directory for %s"
 msgstr "Не вдалося знайти або створити каталог смітника для %s"
 
-#: gio/glocalfile.c:2173
+#: gio/glocalfile.c:2192
 #, c-format
 msgid "Unable to create trashing info file for %s: %s"
 msgstr ""
 "Не вдалося створити файл відомостей щодо надсилання до смітника для %s: %s"
 
-#: gio/glocalfile.c:2235
+#: gio/glocalfile.c:2254
 #, c-format
 msgid "Unable to trash file %s across filesystem boundaries"
 msgstr "Не вдалося надіслати файл %s до смітника за межами файлової системи"
 
-#: gio/glocalfile.c:2239 gio/glocalfile.c:2295
+#: gio/glocalfile.c:2258 gio/glocalfile.c:2314
 #, c-format
 msgid "Unable to trash file %s: %s"
 msgstr "Не вдалося перемістити файл до смітника %s: %s"
 
-#: gio/glocalfile.c:2301
+#: gio/glocalfile.c:2320
 #, c-format
 msgid "Unable to trash file %s"
 msgstr "Не вдалося перемістити файл до смітника %s"
 
-#: gio/glocalfile.c:2327
+#: gio/glocalfile.c:2346
 #, c-format
 msgid "Error creating directory %s: %s"
 msgstr "Сталася помилка при створенні каталогу «%s»: %s"
 
-#: gio/glocalfile.c:2356
+#: gio/glocalfile.c:2375
 #, c-format
 msgid "Filesystem does not support symbolic links"
 msgstr "Файлова система не підтримує символічні посилання"
 
-#: gio/glocalfile.c:2359
+#: gio/glocalfile.c:2378
 #, c-format
 msgid "Error making symbolic link %s: %s"
 msgstr "Помилка при створенні символічного посилання %s: %s"
 
-#: gio/glocalfile.c:2402 gio/glocalfile.c:2437 gio/glocalfile.c:2494
+#: gio/glocalfile.c:2421 gio/glocalfile.c:2456 gio/glocalfile.c:2513
 #, c-format
 msgid "Error moving file %s: %s"
 msgstr "Помилка при переміщенні файла %s: %s"
 
-#: gio/glocalfile.c:2425
+#: gio/glocalfile.c:2444
 msgid "Can’t move directory over directory"
 msgstr "Не вдалося перемістити каталог поверх каталогу"
 
-#: gio/glocalfile.c:2451 gio/glocalfileoutputstream.c:1039
+#: gio/glocalfile.c:2470 gio/glocalfileoutputstream.c:1039
 #: gio/glocalfileoutputstream.c:1053 gio/glocalfileoutputstream.c:1068
 #: gio/glocalfileoutputstream.c:1085 gio/glocalfileoutputstream.c:1099
 msgid "Backup file creation failed"
 msgstr "Помилка при створенні файла резервної копії"
 
-#: gio/glocalfile.c:2470
+#: gio/glocalfile.c:2489
 #, c-format
 msgid "Error removing target file: %s"
 msgstr "Помилка при зчитуванні файла призначення: %s"
 
-#: gio/glocalfile.c:2484
+#: gio/glocalfile.c:2503
 msgid "Move between mounts not supported"
 msgstr "Переміщення між різними точками монтування не підтримується"
 
-#: gio/glocalfile.c:2658
+#: gio/glocalfile.c:2677
 #, c-format
 msgid "Could not determine the disk usage of %s: %s"
 msgstr "Не вдалося визначити використання диска %s: %s"
@@ -3063,120 +3068,120 @@ msgstr "Неправильна назва розширеного атрибут
 msgid "Error setting extended attribute “%s”: %s"
 msgstr "Помилка при встановленні розширеного атрибута «%s»: %s"
 
-#: gio/glocalfileinfo.c:1666 gio/win32/gwinhttpfile.c:191
+#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191
 msgid " (invalid encoding)"
 msgstr " (неправильне кодування)"
 
-#: gio/glocalfileinfo.c:1825 gio/glocalfileoutputstream.c:915
+#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:915
 #, c-format
 msgid "Error when getting information for file “%s”: %s"
 msgstr "Помилка при отриманні інформації про файл «%s»: %s"
 
-#: gio/glocalfileinfo.c:2091
+#: gio/glocalfileinfo.c:2134
 #, c-format
 msgid "Error when getting information for file descriptor: %s"
 msgstr "Помилка при отриманні інформації про файловий дескриптор: %s"
 
-#: gio/glocalfileinfo.c:2136
+#: gio/glocalfileinfo.c:2179
 msgid "Invalid attribute type (uint32 expected)"
 msgstr "Неправильний тип атрибута (очікувався uint32)"
 
-#: gio/glocalfileinfo.c:2154
+#: gio/glocalfileinfo.c:2197
 msgid "Invalid attribute type (uint64 expected)"
 msgstr "Неправильний тип атрибута (очікувався uint64)"
 
-#: gio/glocalfileinfo.c:2173 gio/glocalfileinfo.c:2192
+#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235
 msgid "Invalid attribute type (byte string expected)"
 msgstr "Неправильний тип атрибута (очікувався рядок байтів)"
 
-#: gio/glocalfileinfo.c:2239
+#: gio/glocalfileinfo.c:2282
 msgid "Cannot set permissions on symlinks"
 msgstr "Помилка при встановленні прав доступу на символічне посилання"
 
-#: gio/glocalfileinfo.c:2255
+#: gio/glocalfileinfo.c:2298
 #, c-format
 msgid "Error setting permissions: %s"
 msgstr "Помилка встановлення прав доступу: %s"
 
-#: gio/glocalfileinfo.c:2306
+#: gio/glocalfileinfo.c:2349
 #, c-format
 msgid "Error setting owner: %s"
 msgstr "Помилка встановлення власник: %s"
 
-#: gio/glocalfileinfo.c:2329
+#: gio/glocalfileinfo.c:2372
 msgid "symlink must be non-NULL"
 msgstr "символьне посилання не може мати значення NULL"
 
-#: gio/glocalfileinfo.c:2339 gio/glocalfileinfo.c:2358
-#: gio/glocalfileinfo.c:2369
+#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401
+#: gio/glocalfileinfo.c:2412
 #, c-format
 msgid "Error setting symlink: %s"
 msgstr "Помилка при встановленні символічного посилання: %s"
 
-#: gio/glocalfileinfo.c:2348
+#: gio/glocalfileinfo.c:2391
 msgid "Error setting symlink: file is not a symlink"
 msgstr ""
 "помилка при встановленні символічного посилання: файл не є символічним "
 "посиланням"
 
-#: gio/glocalfileinfo.c:2420
+#: gio/glocalfileinfo.c:2463
 #, c-format
 msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative"
 msgstr "Зайві наносекунди %d у часовій позначці UNIX %lld є від'ємними"
 
-#: gio/glocalfileinfo.c:2429
+#: gio/glocalfileinfo.c:2472
 #, c-format
 msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second"
 msgstr ""
 "Зайві наносекунди %d у часовій позначці UNIX %lld досягли значення у одну "
 "секунду"
 
-#: gio/glocalfileinfo.c:2439
+#: gio/glocalfileinfo.c:2482
 #, c-format
 msgid "UNIX timestamp %lld does not fit into 64 bits"
 msgstr "Часова позначка UNIX %lld не вкладається у 64 біти"
 
-#: gio/glocalfileinfo.c:2450
+#: gio/glocalfileinfo.c:2493
 #, c-format
 msgid "UNIX timestamp %lld is outside of the range supported by Windows"
 msgstr ""
 "Часова позначка UNIX %lld лежить поза діапазоном, підтримку якого "
 "передбачено у Windows"
 
-#: gio/glocalfileinfo.c:2514
+#: gio/glocalfileinfo.c:2557
 #, c-format
 msgid "File name “%s” cannot be converted to UTF-16"
 msgstr "Назву файла «%s» неможливо перетворити на назву у кодуванні UTF-16"
 
-#: gio/glocalfileinfo.c:2533
+#: gio/glocalfileinfo.c:2576
 #, c-format
 msgid "File “%s” cannot be opened: Windows Error %lu"
 msgstr "Не вдалося відкрити файл «%s»: помилка Windows %lu"
 
-#: gio/glocalfileinfo.c:2546
+#: gio/glocalfileinfo.c:2589
 #, c-format
 msgid "Error setting modification or access time for file “%s”: %lu"
 msgstr "Помилка при встановленні часу зміни або доступу для файла «%s»: %lu"
 
-#: gio/glocalfileinfo.c:2647
+#: gio/glocalfileinfo.c:2690
 #, c-format
 msgid "Error setting modification or access time: %s"
 msgstr "Помилка при встановленні часу зміни або доступу: %s"
 
-#: gio/glocalfileinfo.c:2670
+#: gio/glocalfileinfo.c:2713
 msgid "SELinux context must be non-NULL"
 msgstr "Контекст SELinux не може значення NULL"
 
-#: gio/glocalfileinfo.c:2685
+#: gio/glocalfileinfo.c:2720
+msgid "SELinux is not enabled on this system"
+msgstr "SELinux не увімкнено у цій системі"
+
+#: gio/glocalfileinfo.c:2730
 #, c-format
 msgid "Error setting SELinux context: %s"
 msgstr "Помилка при встановленні контексту SELinux: %s"
 
-#: gio/glocalfileinfo.c:2692
-msgid "SELinux is not enabled on this system"
-msgstr "SELinux не увімкнено у цій системі"
-
-#: gio/glocalfileinfo.c:2784
+#: gio/glocalfileinfo.c:2823
 #, c-format
 msgid "Setting attribute %s not supported"
 msgstr "Підтримки встановлення атрибута %s не передбачено"
@@ -3407,15 +3412,15 @@ msgstr "%s не реалізовано"
 msgid "Invalid domain"
 msgstr "Некоректний домен"
 
-#: gio/gresource.c:672 gio/gresource.c:931 gio/gresource.c:970
-#: gio/gresource.c:1094 gio/gresource.c:1166 gio/gresource.c:1239
-#: gio/gresource.c:1320 gio/gresourcefile.c:476 gio/gresourcefile.c:599
+#: gio/gresource.c:672 gio/gresource.c:933 gio/gresource.c:972
+#: gio/gresource.c:1096 gio/gresource.c:1168 gio/gresource.c:1241
+#: gio/gresource.c:1322 gio/gresourcefile.c:476 gio/gresourcefile.c:599
 #: gio/gresourcefile.c:736
 #, c-format
 msgid "The resource at “%s” does not exist"
 msgstr "Ресурсу у «%s» не існує"
 
-#: gio/gresource.c:837
+#: gio/gresource.c:839
 #, c-format
 msgid "The resource at “%s” failed to decompress"
 msgstr "Не вдалося розпакувати ресурс з «%s»"
@@ -3955,31 +3960,27 @@ msgstr "Не вдалося прочитати повноваження соке
 msgid "g_socket_get_credentials not implemented for this OS"
 msgstr "Функція g_socket_get_credentials не реалізована у цій ОС"
 
-#: gio/gsocketclient.c:182
+#: gio/gsocketclient.c:191
 #, c-format
 msgid "Could not connect to proxy server %s: "
 msgstr "Не вдалося під'єднатися до проксі-сервера %s: "
 
-#: gio/gsocketclient.c:196
+#: gio/gsocketclient.c:205
 #, c-format
 msgid "Could not connect to %s: "
 msgstr "Не вдалося під'єднатися до %s: "
 
-#: gio/gsocketclient.c:198
+#: gio/gsocketclient.c:207
 msgid "Could not connect: "
 msgstr "Не вдалося під'єднатися до: "
 
-#: gio/gsocketclient.c:1037 gio/gsocketclient.c:1866
-msgid "Unknown error on connect"
-msgstr "Невідома помилка при з'єднанні"
-
-#: gio/gsocketclient.c:1091 gio/gsocketclient.c:1668
+#: gio/gsocketclient.c:1162 gio/gsocketclient.c:1749
 msgid "Proxying over a non-TCP connection is not supported."
 msgstr ""
 "Підтримки передавання даних за допомогою проксі-сервера через не-TCP "
 "з'єднання не передбачено."
 
-#: gio/gsocketclient.c:1120 gio/gsocketclient.c:1698
+#: gio/gsocketclient.c:1194 gio/gsocketclient.c:1778
 #, c-format
 msgid "Proxy protocol “%s” is not supported."
 msgstr "Підтримки протоколу проксі «%s» не передбачено."
@@ -5787,47 +5788,47 @@ msgstr "Дочірній процес зупинений за сигналом %
 msgid "Child process exited abnormally"
 msgstr "Дочірній процес аварійно закінчив роботу"
 
-#: glib/gspawn.c:1532 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358
+#: glib/gspawn.c:1548 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358
 #, c-format
 msgid "Failed to read from child pipe (%s)"
 msgstr "Помилка зчитування з дочірнього каналу (%s)"
 
-#: glib/gspawn.c:1788
+#: glib/gspawn.c:1804
 #, c-format
 msgid "Failed to spawn child process “%s” (%s)"
 msgstr "Не вдалося запустити дочірній процес «%s» (%s)"
 
-#: glib/gspawn.c:1871
+#: glib/gspawn.c:1887
 #, c-format
 msgid "Failed to fork (%s)"
 msgstr "Помилка створення процесу (%s)"
 
-#: glib/gspawn.c:2026 glib/gspawn-win32.c:381
+#: glib/gspawn.c:2042 glib/gspawn-win32.c:381
 #, c-format
 msgid "Failed to change to directory “%s” (%s)"
 msgstr "Не вдалося змінити каталог на «%s» (%s)"
 
-#: glib/gspawn.c:2036
+#: glib/gspawn.c:2052
 #, c-format
 msgid "Failed to execute child process “%s” (%s)"
 msgstr "Не вдалося виконати дочірній процес «%s» (%s)"
 
-#: glib/gspawn.c:2046
+#: glib/gspawn.c:2062
 #, c-format
 msgid "Failed to redirect output or input of child process (%s)"
 msgstr "Помилка перенаправлення виводу чи вводу дочірнього процесу (%s)"
 
-#: glib/gspawn.c:2055
+#: glib/gspawn.c:2071
 #, c-format
 msgid "Failed to fork child process (%s)"
 msgstr "Помилка запуску дочірнього процесу (%s)"
 
-#: glib/gspawn.c:2063
+#: glib/gspawn.c:2079
 #, c-format
 msgid "Unknown error executing child process “%s”"
 msgstr "Невідома помилка виконання дочірнього процесу «%s»"
 
-#: glib/gspawn.c:2087
+#: glib/gspawn.c:2103
 #, c-format
 msgid "Failed to read enough data from child pid pipe (%s)"
 msgstr "Не вдалося зчитати достатню кількість даних з дочірнього каналу (%s)"
@@ -5898,54 +5899,60 @@ msgstr "Число «%s» не належить до діапазону [%s, %s]
 msgid "“%s” is not an unsigned number"
 msgstr "«%s» не є числом без знаку"
 
-#: glib/guri.c:313
+#: glib/guri.c:315
 #, no-c-format
 msgid "Invalid %-encoding in URI"
 msgstr "Некоректне %-eкодування в адресі"
 
-#: glib/guri.c:330
+#: glib/guri.c:332
 msgid "Illegal character in URI"
 msgstr "Некоректний символ в адресі"
 
-#: glib/guri.c:359
+#: glib/guri.c:366
 msgid "Non-UTF-8 characters in URI"
 msgstr "Символи поза UTF-8 в адресі"
 
-#: glib/guri.c:533
+#: glib/guri.c:546
 #, c-format
 msgid "Invalid IPv6 address ‘%.*s’ in URI"
 msgstr "Некоректна IPv6-адреса «%.*s» в адресі"
 
-#: glib/guri.c:588
+#: glib/guri.c:601
 #, c-format
 msgid "Illegal encoded IP address ‘%.*s’ in URI"
 msgstr "Помилкове кодування IP-адреси «%.*s» в адресі"
 
-#: glib/guri.c:620 glib/guri.c:632
+#: glib/guri.c:613
+#, c-format
+#| msgid "Illegal encoded IP address ‘%.*s’ in URI"
+msgid "Illegal internationalized hostname ‘%.*s’ in URI"
+msgstr "Назва вузла із некоректними символами «%.*s» у адресі"
+
+#: glib/guri.c:645 glib/guri.c:657
 #, c-format
 msgid "Could not parse port ‘%.*s’ in URI"
 msgstr "Не вдалося обробити запис порту «%.*s» в адресі"
 
-#: glib/guri.c:639
+#: glib/guri.c:664
 #, c-format
 msgid "Port ‘%.*s’ in URI is out of range"
 msgstr "Порт «%.*s» в адресі не належить до припустимого діапазону"
 
-#: glib/guri.c:1119 glib/guri.c:1183
+#: glib/guri.c:1224 glib/guri.c:1288
 #, c-format
 msgid "URI ‘%s’ is not an absolute URI"
 msgstr "Адреса «%s» не є абсолютною адресою"
 
-#: glib/guri.c:1125
+#: glib/guri.c:1230
 #, c-format
 msgid "URI ‘%s’ has no host component"
 msgstr "В адресі «%s» немає компонента вузла"
 
-#: glib/guri.c:1330
+#: glib/guri.c:1435
 msgid "URI is not absolute, and no base URI was provided"
 msgstr "Адреса не є абсолютною, і не вказано базової адреси"
 
-#: glib/guri.c:2082
+#: glib/guri.c:2209
 msgid "Missing ‘=’ and parameter value"
 msgstr "Пропущено «=» і значення параметра"
 
@@ -6178,3 +6185,6 @@ msgstr "%.1f ПБ"
 #, c-format
 msgid "%.1f EB"
 msgstr "%.1f ЕБ"
+
+#~ msgid "Unknown error on connect"
+#~ msgstr "Невідома помилка при з'єднанні"
diff --git a/sanity_check b/sanity_check
deleted file mode 100755 (executable)
index 44ae7f1..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/bin/sh
-
-VERSION=$1
-
-if [ ! -f glib-$VERSION.tar.gz ]; then
-       echo "ERROR: glib-$VERSION.tar.gz does not exist..."
-       exit 1
-fi
-
-echo ""
-
-echo "Checking glib-$VERSION.tar.gz..."
-tar xfz glib-$VERSION.tar.gz
-
-
-for file in INSTALL NEWS
-do
-       echo -n "$file... "
-       if [ "x`grep $VERSION glib-$VERSION/$file | wc -l | awk -F' ' '{print $1}'`" = "x0" ]; then
-               echo "failed."
-               #exit 1
-       else
-               echo "ok"
-       fi
-done
-
-echo -n "INSTALL..."
-if [ "x`grep $VERSION glib-$VERSION/INSTALL | wc -l | awk -F' ' '{print $1}'`" = "x2" ]; then 
-       echo "ok" 
-else
-       echo "failed."
-       exit 1
-fi
-
-echo ""
-echo "Number of lines in created documentation files:"
-
-wc -l glib-$VERSION/docs/reference/*/html/*.html | grep total 
-
-rm -rf glib-$VERSION
index fb66946..7ae489c 100644 (file)
@@ -1,5 +1,5 @@
 [wrap-git]
 directory=sysprof
 url=https://gitlab.gnome.org/GNOME/sysprof.git
-revision=6b1cd7a722fcebae1ac392562c47957477ade8bf
+revision=3.38.0
 depth=1
index 3c55828..e7bafa0 100755 (executable)
@@ -29,14 +29,16 @@ import argparse
 
 def main(argv):
     parser = argparse.ArgumentParser(
-        description="Generate test cases for casefolding from Unicode data")
+        description="Generate test cases for casefolding from Unicode data"
+    )
     parser.add_argument("UNICODE-VERSION")
     parser.add_argument("CaseFolding.txt")
     args = parser.parse_args(argv[1:])
     version = getattr(args, "UNICODE-VERSION")
     filename = getattr(args, "CaseFolding.txt")
 
-    print("""\
+    print(
+        """\
 # Test cases generated from Unicode {} data
 # by gen-casefold-txt.py. Do not edit.
 #
@@ -45,7 +47,10 @@ def main(argv):
 AaBbCc@@\taabbcc@@
 #
 # Now the automatic tests
-#""".format(version))
+#""".format(
+            version
+        )
+    )
 
     # Names of fields in the CaseFolding table
     CODE, STATUS, MAPPING = range(3)
@@ -60,8 +65,9 @@ AaBbCc@@\taabbcc@@
             fields = [f.strip() for f in line.split(";", 3)[:3]]
             if len(fields) != 3:
                 raise SystemExit(
-                    "Entry for %s has wrong number of fields (%d)" % (
-                        fields[CODE], len(fields)))
+                    "Entry for %s has wrong number of fields (%d)"
+                    % (fields[CODE], len(fields))
+                )
 
             status = fields[STATUS]
             # skip simple and Turkic mappings
@@ -69,8 +75,7 @@ AaBbCc@@\taabbcc@@
                 continue
 
             code = chr(int(fields[CODE], 16))
-            values = "".join(
-                [chr(int(v, 16)) for v in fields[MAPPING].split()])
+            values = "".join([chr(int(v, 16)) for v in fields[MAPPING].split()])
             print("{}\t{}".format(code, values))
 
 
index 98f6bc9..62d5963 100755 (executable)
@@ -27,9 +27,14 @@ import sys
 import argparse
 
 
+# Disable line length warnings as wrapping the test templates would be hard
+# flake8: noqa: E501
+
+
 def main(argv):
     parser = argparse.ArgumentParser(
-        description="Generate test cases for case mapping from Unicode data")
+        description="Generate test cases for case mapping from Unicode data"
+    )
     parser.add_argument("UNICODE-VERSION")
     parser.add_argument("UnicodeData.txt")
     parser.add_argument("SpecialCasing.txt")
@@ -39,9 +44,23 @@ def main(argv):
     filename_casing = getattr(args, "SpecialCasing.txt")
 
     # Names of fields in Unicode data table.
-    CODE, NAME, CATEGORY, COMBINING_CLASSES, BIDI_CATEGORY, DECOMPOSITION, \
-        DECIMAL_VALUE, DIGIT_VALUE, NUMERIC_VALUE, MIRRORED, OLD_NAME, \
-        COMMENT, UPPER, LOWER, TITLE = range(15)
+    (
+        CODE,
+        NAME,
+        CATEGORY,
+        COMBINING_CLASSES,
+        BIDI_CATEGORY,
+        DECOMPOSITION,
+        DECIMAL_VALUE,
+        DIGIT_VALUE,
+        NUMERIC_VALUE,
+        MIRRORED,
+        OLD_NAME,
+        COMMENT,
+        UPPER,
+        LOWER,
+        TITLE,
+    ) = range(15)
 
     # Names of fields in the SpecialCasing table
     CASE_CODE, CASE_LOWER, CASE_TITLE, CASE_UPPER, CASE_CONDITION = range(5)
@@ -78,8 +97,9 @@ def main(argv):
             fields = [f.strip() for f in line.split(";")]
             if len(fields) != 15:
                 raise SystemExit(
-                    "Entry for %s has wrong number of fields (%d)" % (
-                        fields[CODE], len(fields)))
+                    "Entry for %s has wrong number of fields (%d)"
+                    % (fields[CODE], len(fields))
+                )
 
             code = int(fields[CODE], 16)
 
@@ -92,8 +112,23 @@ def main(argv):
                 else:
                     # The gap represents undefined characters.  Only the type
                     # matters.
-                    gfields = ['', '', 'Cn', '0', '', '', '', '', '', '', '',
-                               '', '', '', '']
+                    gfields = [
+                        "",
+                        "",
+                        "Cn",
+                        "0",
+                        "",
+                        "",
+                        "",
+                        "",
+                        "",
+                        "",
+                        "",
+                        "",
+                        "",
+                        "",
+                        "",
+                    ]
 
                 last_code += 1
                 while last_code < code:
@@ -117,8 +152,9 @@ def main(argv):
             fields = [f.strip() for f in line.split(";")]
             if len(fields) not in (4, 5):
                 raise SystemExit(
-                    "Entry for %s has wrong number of fields (%d)" % (
-                        fields[CASE_CODE], len(fields)))
+                    "Entry for %s has wrong number of fields (%d)"
+                    % (fields[CASE_CODE], len(fields))
+                )
 
             if len(fields) == 5:
                 # Ignore conditional special cases - we'll handle them manually
@@ -134,7 +170,8 @@ def main(argv):
 
 
 def print_tests(version, upper, title, lower):
-    print("""\
+    print(
+        """\
 # Test cases generated from Unicode {} data
 # by gen-casemap-txt.py. Do not edit.
 #
@@ -150,9 +187,9 @@ tr_TR.UTF-8\tI\u0307\ti\tI\u0307\tI\u0307\t# I => LATIN SMALL LETTER DOTLESS I
 \t\u03b1\u0345\u0314\t\u03b1\u0345\u0314\t\u0391\u0345\u0314\t\u0391\u0314\u0399\t
 \t\u03b1\u0314\u0345\t\u03b1\u0314\u0345\t\u0391\u0314\u0345\t\u0391\u0314\u0399\t
 # Handling of final and nonfinal sigma
-\tΜΆΙΟΣ   μάιος      Μάιος      ΜΆΙΟΣ      
-\tΜΆΙΟΣ   μάιος      Μάιος      ΜΆΙΟΣ      
-\tΣΙΓΜΑ   σιγμα      Σιγμα      ΣΙΓΜΑ      
+\tΜΆΙΟΣ   μάιος      Μάιος      ΜΆΙΟΣ \t
+\tΜΆΙΟΣ   μάιος      Μάιος      ΜΆΙΟΣ\t
+\tΣΙΓΜΑ   σιγμα      Σιγμα      ΣΙΓΜΑ\t
 # Lithuanian rule of i followed by letter with dot. Not at all sure
 # about the titlecase part here
 lt_LT\ti\u0117\ti\u0117\tIe\tIE\t
@@ -181,9 +218,12 @@ lt_LT.UTF-8\t\u012e\u0301\t\u012f\u0307\u0301\t\u012e\u0301\t\u012e\u0301\t # LA
 \ta\ufb04\ta\ufb04\tAffl\tAFFL\t# FB04
 #
 # Now the automatic tests
-#""".format(version))
+#""".format(
+            version
+        )
+    )
 
-    for i in range(0x10ffff):
+    for i in range(0x10FFFF):
         if i == 0x3A3:
             # Greek sigma needs special tests
             continue
index 30ea5bd..c98541d 100644 (file)
@@ -52,7 +52,7 @@ static GType liststore_interfaces[6];
 static gpointer 
 register_types (void)
 {
-  static volatile gsize inited = 0;
+  static gsize inited = 0;
   if (g_once_init_enter (&inited))
     {
       liststore_interfaces[0] = simple_register_class ("GtkBuildable", G_TYPE_INTERFACE, 0);
index 236ffae..163be58 100644 (file)
@@ -575,8 +575,8 @@ test_type_check_run (PerformanceTest *test,
                     gpointer _data)
 {
   struct TypeCheckTest *data = _data;
-  volatile GObject *object = data->object;
-  volatile GType type, types[5];
+  GObject *object = data->object;
+  GType type, types[5];
   int i, j;
 
   types[0] = test_iface1_get_type ();
index 89ba6a1..9788efc 100644 (file)
 
 static GMutex       tmutex;
 static GCond        tcond;
-static volatile int thread_call_count = 0;
+static int thread_call_count = 0;  /* (atomic) */
 static char         dummy_value = 'x';
 
 static void
 assert_singleton_execution1 (void)
 {
-  static volatile int seen_execution = 0;
+  static int seen_execution = 0;  /* (atomic) */
   int old_seen_execution = g_atomic_int_add (&seen_execution, 1);
   if (old_seen_execution != 0)
     g_error ("%s: function executed more than once", G_STRFUNC);
@@ -40,7 +40,7 @@ assert_singleton_execution1 (void)
 static void
 assert_singleton_execution2 (void)
 {
-  static volatile int seen_execution = 0;
+  static int seen_execution = 0;  /* (atomic) */
   int old_seen_execution = g_atomic_int_add (&seen_execution, 1);
   if (old_seen_execution != 0)
     g_error ("%s: function executed more than once", G_STRFUNC);
@@ -49,7 +49,7 @@ assert_singleton_execution2 (void)
 static void
 assert_singleton_execution3 (void)
 {
-  static volatile int seen_execution = 0;
+  static int seen_execution = 0;  /* (atomic) */
   int old_seen_execution = g_atomic_int_add (&seen_execution, 1);
   if (old_seen_execution != 0)
     g_error ("%s: function executed more than once", G_STRFUNC);
@@ -58,7 +58,7 @@ assert_singleton_execution3 (void)
 static void
 initializer1 (void)
 {
-  static volatile gsize initialized = 0;
+  static gsize initialized = 0;
   if (g_once_init_enter (&initialized))
     {
       gsize initval = 42;
@@ -70,7 +70,7 @@ initializer1 (void)
 static gpointer
 initializer2 (void)
 {
-  static volatile gsize initialized = 0;
+  static gsize initialized = 0;
   if (g_once_init_enter (&initialized))
     {
       void *pointer_value = &dummy_value;
@@ -83,7 +83,7 @@ initializer2 (void)
 static void
 initializer3 (void)
 {
-  static volatile gsize initialized = 0;
+  static gsize initialized = 0;
   if (g_once_init_enter (&initialized))
     {
       gsize initval = 42;
@@ -163,7 +163,7 @@ main (int   argc,
       static void                                       \
       test_initializer_##N (void)                       \
       {                                                 \
-        static volatile gsize initialized = 0;          \
+        static gsize initialized = 0;                   \
         if (g_once_init_enter (&initialized))           \
           {                                             \
             g_free (g_strdup_printf ("cpuhog%5d", 1));  \
index 963766d..0c471a4 100644 (file)
@@ -26,7 +26,7 @@ struct _GTestClass
 };
 
 static GType my_test_get_type (void);
-static volatile gboolean stopping;
+static gint stopping;  /* (atomic) */
 
 static void my_test_class_init (GTestClass * klass);
 static void my_test_init (GTest * test);
@@ -101,7 +101,7 @@ run_thread (GTest * test)
 {
   gint i = 1;
 
-  while (!stopping) {
+  while (!g_atomic_int_get (&stopping)) {
     my_test_do_refcount (test);
     if ((i++ % 10000) == 0) {
       g_print (".");
@@ -128,7 +128,7 @@ main (int argc, char **argv)
 
   test_threads = g_array_new (FALSE, FALSE, sizeof (GThread *));
 
-  stopping = FALSE;
+  g_atomic_int_set (&stopping, 0);
 
   for (i = 0; i < n_threads; i++) {
     GThread *thread;
@@ -141,7 +141,7 @@ main (int argc, char **argv)
   }
   g_usleep (5000000);
 
-  stopping = TRUE;
+  g_atomic_int_set (&stopping, 1);
 
   g_print ("\nstopping\n");
 
index bc88206..31f26a4 100644 (file)
@@ -34,7 +34,7 @@ struct _GTestClass
 static GType my_test_get_type (void);
 G_DEFINE_TYPE (GTest, my_test, G_TYPE_OBJECT)
 
-static volatile gboolean stopping;
+static gint stopping;  /* (atomic) */
 
 static void my_test_get_property (GObject    *object,
                                  guint       prop_id,
@@ -140,7 +140,7 @@ run_thread (GTest * test)
 {
   gint i = 1;
 
-  while (!stopping) {
+  while (!g_atomic_int_get (&stopping)) {
     my_test_do_property (test);
     if ((i++ % 10000) == 0)
       {
@@ -170,7 +170,7 @@ main (int argc, char **argv)
 
   test_threads = g_array_new (FALSE, FALSE, sizeof (GThread *));
 
-  stopping = FALSE;
+  g_atomic_int_set (&stopping, 0);
 
   for (i = 0; i < n_threads; i++) {
     GThread *thread;
@@ -180,7 +180,7 @@ main (int argc, char **argv)
   }
   g_usleep (30000000);
 
-  stopping = TRUE;
+  g_atomic_int_set (&stopping, 1);
   g_print ("\nstopping\n");
 
   /* join all threads */
index 526c75a..88f86f1 100755 (executable)
@@ -41,6 +41,7 @@ echo_v "Running gdb on assert-msg-test"
 OUT=$($LIBTOOL --mode=execute gdb --batch -x "${srcdir:-.}/assert-msg-test.gdb" ./assert-msg-test 2> $error_out) || fail "failed to run gdb"
 
 echo_v "Checking if assert message is in __glib_assert_msg"
+# shellcheck disable=SC2016
 if ! echo "$OUT" | grep -q '^$1.*"GLib:ERROR:.*assert-msg-test.c:.*:.*main.*: assertion failed: (42 < 0)"'; then
   fail "__glib_assert_msg does not have assertion message"
 fi