mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-12 05:39:21 +01:00
gdbus-codegen: Emit GUnixFDLists if an arg has type h
w/ min-version
This is a reimplementation of commit 4aba03562bc1526a1baf70ad068a9395ec64bf64 from Will Thompson, but conditional on the caller passing `--glib-min-version 2.64` to `gdbus-codegen` to explicitly opt-in to the new behaviour. From the commit message for that commit: Previously, if a method was not annotated with org.gtk.GDBus.C.UnixFD then the generated code would never contain GUnixFDList parameters, even if the method has 'h' (file descriptor) parameters. However, in this case, the generated code is essentially useless: the method cannot be called or handled except in degenerate cases where the file descriptors are missing or ignored. Check the argument types for 'h', and if present, generate code as if org.gtk.GDBus.C.UnixFD annotation were specified. Includes a unit test too. Signed-off-by: Philip Withnall <withnall@endlessm.com> Fixes: #1726
This commit is contained in:
parent
90f0733858
commit
e3f80b9254
@ -256,12 +256,17 @@ def codegen_main():
|
||||
else:
|
||||
glib_min_version = (2, 30)
|
||||
|
||||
glib_min_version_is_2_64 = (glib_min_version[0] > 2 or
|
||||
(glib_min_version[0] == 2 and
|
||||
glib_min_version[1] >= 64))
|
||||
|
||||
all_ifaces = []
|
||||
input_files_basenames = []
|
||||
for fname in sorted(args.files + args.xml_files):
|
||||
with open(fname, 'rb') as f:
|
||||
xml_data = f.read()
|
||||
parsed_ifaces = parser.parse_dbus_xml(xml_data)
|
||||
parsed_ifaces = parser.parse_dbus_xml(xml_data,
|
||||
h_type_implies_unix_fd=glib_min_version_is_2_64)
|
||||
all_ifaces.extend(parsed_ifaces)
|
||||
input_files_basenames.append(os.path.basename(fname))
|
||||
|
||||
|
@ -252,8 +252,9 @@ class Arg:
|
||||
a.post_process(interface_prefix, cns, cns_upper, cns_lower, self)
|
||||
|
||||
class Method:
|
||||
def __init__(self, name):
|
||||
def __init__(self, name, h_type_implies_unix_fd=True):
|
||||
self.name = name
|
||||
self.h_type_implies_unix_fd = h_type_implies_unix_fd
|
||||
self.in_args = []
|
||||
self.out_args = []
|
||||
self.annotations = []
|
||||
@ -284,10 +285,14 @@ class Method:
|
||||
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:
|
||||
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:
|
||||
self.unix_fd = True
|
||||
|
||||
if utils.lookup_annotation(self.annotations, 'org.freedesktop.DBus.Deprecated') == 'true':
|
||||
self.deprecated = True
|
||||
|
@ -36,7 +36,7 @@ class DBusXMLParser:
|
||||
STATE_ANNOTATION = 'annotation'
|
||||
STATE_IGNORED = 'ignored'
|
||||
|
||||
def __init__(self, xml_data):
|
||||
def __init__(self, xml_data, h_type_implies_unix_fd=True):
|
||||
self._parser = xml.parsers.expat.ParserCreate()
|
||||
self._parser.CommentHandler = self.handle_comment
|
||||
self._parser.CharacterDataHandler = self.handle_char_data
|
||||
@ -53,6 +53,8 @@ class DBusXMLParser:
|
||||
|
||||
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'
|
||||
@ -163,7 +165,8 @@ class DBusXMLParser:
|
||||
elif self.state == DBusXMLParser.STATE_INTERFACE:
|
||||
if name == DBusXMLParser.STATE_METHOD:
|
||||
self.state = DBusXMLParser.STATE_METHOD
|
||||
method = dbustypes.Method(attrs['name'])
|
||||
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:
|
||||
@ -288,6 +291,6 @@ class DBusXMLParser:
|
||||
self.state = self.state_stack.pop()
|
||||
self._cur_object = self._cur_object_stack.pop()
|
||||
|
||||
def parse_dbus_xml(xml_data):
|
||||
parser = DBusXMLParser(xml_data)
|
||||
def parse_dbus_xml(xml_data, h_type_implies_unix_fd):
|
||||
parser = DBusXMLParser(xml_data, h_type_implies_unix_fd)
|
||||
return parser.parsed_interfaces
|
||||
|
@ -397,6 +397,56 @@ G_END_DECLS
|
||||
self.assertEqual('', result.err)
|
||||
self.assertNotEqual('', result.out.strip())
|
||||
|
||||
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 = '''
|
||||
<node>
|
||||
<interface name="FDPassing">
|
||||
<method name="HelloFD">
|
||||
<annotation name="org.gtk.GDBus.C.UnixFD" value="1"/>
|
||||
<arg name="greeting" direction="in" type="s"/>
|
||||
<arg name="response" direction="out" type="s"/>
|
||||
</method>
|
||||
<method name="NoAnnotation">
|
||||
<arg name="greeting" direction="in" type="h"/>
|
||||
<arg name="greeting_locale" direction="in" type="s"/>
|
||||
<arg name="response" direction="out" type="h"/>
|
||||
<arg name="response_locale" direction="out" type="s"/>
|
||||
</method>
|
||||
<method name="NoAnnotationNested">
|
||||
<arg name="files" type="a{sh}" direction="in"/>
|
||||
</method>
|
||||
</interface>
|
||||
</node>'''
|
||||
|
||||
# Try without specifying --glib-min-version.
|
||||
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-version.
|
||||
result = self.runCodegenWithInterface(interface_xml,
|
||||
'--output', '/dev/stdout',
|
||||
'--header',
|
||||
'--glib-min-version', '2.32')
|
||||
self.assertEqual('', result.err)
|
||||
self.assertEqual(result.out.strip().count('GUnixFDList'), 6)
|
||||
|
||||
# Specify a --glib-min-version ≥ 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-version', '2.64')
|
||||
self.assertEqual('', result.err)
|
||||
self.assertEqual(result.out.strip().count('GUnixFDList'), 18)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(testRunner=taptestrunner.TAPTestRunner())
|
||||
|
Loading…
x
Reference in New Issue
Block a user