← Back
Editing: introspection.py
# systemd_ctypes # # Copyright (C) 2022 Allison Karlitskaya <allison.karlitskaya@redhat.com> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. import xml.etree.ElementTree as ET from typing import Any def parse_method(method: ET.Element) -> 'dict[str, list[str]]': return { "in": [tag.attrib['type'] for tag in method.findall("arg") if tag.get('direction', 'in') == 'in'], "out": [tag.attrib['type'] for tag in method.findall("arg[@direction='out']")] } def parse_property(prop: ET.Element) -> 'dict[str, str]': return { "flags": 'w' if prop.attrib.get('access') == 'write' else 'r', "type": prop.attrib['type'] } def parse_signal(signal: ET.Element) -> 'dict[str, list[str]]': return {"in": [tag.attrib['type'] for tag in signal.findall("arg")]} def parse_interface(interface: ET.Element) -> 'dict[str, dict[str, Any]]': return { "methods": {tag.attrib['name']: parse_method(tag) for tag in interface.findall('method')}, "properties": {tag.attrib['name']: parse_property(tag) for tag in interface.findall('property')}, "signals": {tag.attrib['name']: parse_signal(tag) for tag in interface.findall('signal')} } def parse_xml(xml: str): et = ET.fromstring(xml) return {tag.attrib['name']: parse_interface(tag) for tag in et.findall('interface')} # Pretend like this is a little bit functional def element(tag, children=(), **kwargs) -> ET.Element: tag = ET.Element(tag, kwargs) tag.extend(children) return tag def method_to_xml(name, method_info): return element('method', name=name, children=[ element('arg', type=arg_type, direction=direction) for direction in ['in', 'out'] for arg_type in method_info[direction] ]) def property_to_xml(name, property_info): return element('property', name=name, access='write' if property_info['flags'] == 'w' else 'read', type=property_info['type']) def signal_to_xml(name, signal_info): return element('signal', name=name, children=[ element('arg', type=arg_type) for arg_type in signal_info['in'] ]) def interface_to_xml(name, interface_info): return element('interface', name=name, children=[ *(method_to_xml(name, info) for name, info in interface_info['methods'].items()), *(property_to_xml(name, info) for name, info in interface_info['properties'].items()), *(signal_to_xml(name, info) for name, info in interface_info['signals'].items()), ]) def to_xml(interfaces): node = element('node', children=(interface_to_xml(name, members) for name, members in interfaces.items())) return ET.tostring(node, encoding='unicode')
Save File
Cancel