diff --git a/gio/gdbus-2.0/codegen/codegen_main.py b/gio/gdbus-2.0/codegen/codegen_main.py index a9dfe0428..aecacc76d 100644 --- a/gio/gdbus-2.0/codegen/codegen_main.py +++ b/gio/gdbus-2.0/codegen/codegen_main.py @@ -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)) diff --git a/gio/gdbus-2.0/codegen/dbustypes.py b/gio/gdbus-2.0/codegen/dbustypes.py index 16364f9b7..415a5cc7a 100644 --- a/gio/gdbus-2.0/codegen/dbustypes.py +++ b/gio/gdbus-2.0/codegen/dbustypes.py @@ -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 diff --git a/gio/gdbus-2.0/codegen/parser.py b/gio/gdbus-2.0/codegen/parser.py index f49136d6e..7dcc73558 100644 --- a/gio/gdbus-2.0/codegen/parser.py +++ b/gio/gdbus-2.0/codegen/parser.py @@ -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 diff --git a/gio/tests/codegen.py b/gio/tests/codegen.py index 6a01b2f00..dc2c9ff1a 100644 --- a/gio/tests/codegen.py +++ b/gio/tests/codegen.py @@ -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 = ''' + + + + + + + + + + + + + + + + + + ''' + + # 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())