1*2668dc7bSMarc-André Lureau# Based from "GDBus - GLib D-Bus Library": 2*2668dc7bSMarc-André Lureau# 3*2668dc7bSMarc-André Lureau# Copyright (C) 2008-2011 Red Hat, Inc. 4*2668dc7bSMarc-André Lureau# 5*2668dc7bSMarc-André Lureau# This library is free software; you can redistribute it and/or 6*2668dc7bSMarc-André Lureau# modify it under the terms of the GNU Lesser General Public 7*2668dc7bSMarc-André Lureau# License as published by the Free Software Foundation; either 8*2668dc7bSMarc-André Lureau# version 2.1 of the License, or (at your option) any later version. 9*2668dc7bSMarc-André Lureau# 10*2668dc7bSMarc-André Lureau# This library is distributed in the hope that it will be useful, 11*2668dc7bSMarc-André Lureau# but WITHOUT ANY WARRANTY; without even the implied warranty of 12*2668dc7bSMarc-André Lureau# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13*2668dc7bSMarc-André Lureau# Lesser General Public License for more details. 14*2668dc7bSMarc-André Lureau# 15*2668dc7bSMarc-André Lureau# You should have received a copy of the GNU Lesser General 16*2668dc7bSMarc-André Lureau# Public License along with this library; if not, see <http://www.gnu.org/licenses/>. 17*2668dc7bSMarc-André Lureau# 18*2668dc7bSMarc-André Lureau# Author: David Zeuthen <davidz@redhat.com> 19*2668dc7bSMarc-André Lureau 20*2668dc7bSMarc-André Lureauimport xml.parsers.expat 21*2668dc7bSMarc-André Lureau 22*2668dc7bSMarc-André Lureau 23*2668dc7bSMarc-André Lureauclass Annotation: 24*2668dc7bSMarc-André Lureau def __init__(self, key, value): 25*2668dc7bSMarc-André Lureau self.key = key 26*2668dc7bSMarc-André Lureau self.value = value 27*2668dc7bSMarc-André Lureau self.annotations = [] 28*2668dc7bSMarc-André Lureau self.since = "" 29*2668dc7bSMarc-André Lureau 30*2668dc7bSMarc-André Lureau 31*2668dc7bSMarc-André Lureauclass Arg: 32*2668dc7bSMarc-André Lureau def __init__(self, name, signature): 33*2668dc7bSMarc-André Lureau self.name = name 34*2668dc7bSMarc-André Lureau self.signature = signature 35*2668dc7bSMarc-André Lureau self.annotations = [] 36*2668dc7bSMarc-André Lureau self.doc_string = "" 37*2668dc7bSMarc-André Lureau self.since = "" 38*2668dc7bSMarc-André Lureau 39*2668dc7bSMarc-André Lureau 40*2668dc7bSMarc-André Lureauclass Method: 41*2668dc7bSMarc-André Lureau def __init__(self, name, h_type_implies_unix_fd=True): 42*2668dc7bSMarc-André Lureau self.name = name 43*2668dc7bSMarc-André Lureau self.h_type_implies_unix_fd = h_type_implies_unix_fd 44*2668dc7bSMarc-André Lureau self.in_args = [] 45*2668dc7bSMarc-André Lureau self.out_args = [] 46*2668dc7bSMarc-André Lureau self.annotations = [] 47*2668dc7bSMarc-André Lureau self.doc_string = "" 48*2668dc7bSMarc-André Lureau self.since = "" 49*2668dc7bSMarc-André Lureau self.deprecated = False 50*2668dc7bSMarc-André Lureau self.unix_fd = False 51*2668dc7bSMarc-André Lureau 52*2668dc7bSMarc-André Lureau 53*2668dc7bSMarc-André Lureauclass Signal: 54*2668dc7bSMarc-André Lureau def __init__(self, name): 55*2668dc7bSMarc-André Lureau self.name = name 56*2668dc7bSMarc-André Lureau self.args = [] 57*2668dc7bSMarc-André Lureau self.annotations = [] 58*2668dc7bSMarc-André Lureau self.doc_string = "" 59*2668dc7bSMarc-André Lureau self.since = "" 60*2668dc7bSMarc-André Lureau self.deprecated = False 61*2668dc7bSMarc-André Lureau 62*2668dc7bSMarc-André Lureau 63*2668dc7bSMarc-André Lureauclass Property: 64*2668dc7bSMarc-André Lureau def __init__(self, name, signature, access): 65*2668dc7bSMarc-André Lureau self.name = name 66*2668dc7bSMarc-André Lureau self.signature = signature 67*2668dc7bSMarc-André Lureau self.access = access 68*2668dc7bSMarc-André Lureau self.annotations = [] 69*2668dc7bSMarc-André Lureau self.arg = Arg("value", self.signature) 70*2668dc7bSMarc-André Lureau self.arg.annotations = self.annotations 71*2668dc7bSMarc-André Lureau self.readable = False 72*2668dc7bSMarc-André Lureau self.writable = False 73*2668dc7bSMarc-André Lureau if self.access == "readwrite": 74*2668dc7bSMarc-André Lureau self.readable = True 75*2668dc7bSMarc-André Lureau self.writable = True 76*2668dc7bSMarc-André Lureau elif self.access == "read": 77*2668dc7bSMarc-André Lureau self.readable = True 78*2668dc7bSMarc-André Lureau elif self.access == "write": 79*2668dc7bSMarc-André Lureau self.writable = True 80*2668dc7bSMarc-André Lureau else: 81*2668dc7bSMarc-André Lureau raise ValueError('Invalid access type "{}"'.format(self.access)) 82*2668dc7bSMarc-André Lureau self.doc_string = "" 83*2668dc7bSMarc-André Lureau self.since = "" 84*2668dc7bSMarc-André Lureau self.deprecated = False 85*2668dc7bSMarc-André Lureau self.emits_changed_signal = True 86*2668dc7bSMarc-André Lureau 87*2668dc7bSMarc-André Lureau 88*2668dc7bSMarc-André Lureauclass Interface: 89*2668dc7bSMarc-André Lureau def __init__(self, name): 90*2668dc7bSMarc-André Lureau self.name = name 91*2668dc7bSMarc-André Lureau self.methods = [] 92*2668dc7bSMarc-André Lureau self.signals = [] 93*2668dc7bSMarc-André Lureau self.properties = [] 94*2668dc7bSMarc-André Lureau self.annotations = [] 95*2668dc7bSMarc-André Lureau self.doc_string = "" 96*2668dc7bSMarc-André Lureau self.doc_string_brief = "" 97*2668dc7bSMarc-André Lureau self.since = "" 98*2668dc7bSMarc-André Lureau self.deprecated = False 99*2668dc7bSMarc-André Lureau 100*2668dc7bSMarc-André Lureau 101*2668dc7bSMarc-André Lureauclass DBusXMLParser: 102*2668dc7bSMarc-André Lureau STATE_TOP = "top" 103*2668dc7bSMarc-André Lureau STATE_NODE = "node" 104*2668dc7bSMarc-André Lureau STATE_INTERFACE = "interface" 105*2668dc7bSMarc-André Lureau STATE_METHOD = "method" 106*2668dc7bSMarc-André Lureau STATE_SIGNAL = "signal" 107*2668dc7bSMarc-André Lureau STATE_PROPERTY = "property" 108*2668dc7bSMarc-André Lureau STATE_ARG = "arg" 109*2668dc7bSMarc-André Lureau STATE_ANNOTATION = "annotation" 110*2668dc7bSMarc-André Lureau STATE_IGNORED = "ignored" 111*2668dc7bSMarc-André Lureau 112*2668dc7bSMarc-André Lureau def __init__(self, xml_data, h_type_implies_unix_fd=True): 113*2668dc7bSMarc-André Lureau self._parser = xml.parsers.expat.ParserCreate() 114*2668dc7bSMarc-André Lureau self._parser.CommentHandler = self.handle_comment 115*2668dc7bSMarc-André Lureau self._parser.CharacterDataHandler = self.handle_char_data 116*2668dc7bSMarc-André Lureau self._parser.StartElementHandler = self.handle_start_element 117*2668dc7bSMarc-André Lureau self._parser.EndElementHandler = self.handle_end_element 118*2668dc7bSMarc-André Lureau 119*2668dc7bSMarc-André Lureau self.parsed_interfaces = [] 120*2668dc7bSMarc-André Lureau self._cur_object = None 121*2668dc7bSMarc-André Lureau 122*2668dc7bSMarc-André Lureau self.state = DBusXMLParser.STATE_TOP 123*2668dc7bSMarc-André Lureau self.state_stack = [] 124*2668dc7bSMarc-André Lureau self._cur_object = None 125*2668dc7bSMarc-André Lureau self._cur_object_stack = [] 126*2668dc7bSMarc-André Lureau 127*2668dc7bSMarc-André Lureau self.doc_comment_last_symbol = "" 128*2668dc7bSMarc-André Lureau 129*2668dc7bSMarc-André Lureau self._h_type_implies_unix_fd = h_type_implies_unix_fd 130*2668dc7bSMarc-André Lureau 131*2668dc7bSMarc-André Lureau self._parser.Parse(xml_data) 132*2668dc7bSMarc-André Lureau 133*2668dc7bSMarc-André Lureau COMMENT_STATE_BEGIN = "begin" 134*2668dc7bSMarc-André Lureau COMMENT_STATE_PARAMS = "params" 135*2668dc7bSMarc-André Lureau COMMENT_STATE_BODY = "body" 136*2668dc7bSMarc-André Lureau COMMENT_STATE_SKIP = "skip" 137*2668dc7bSMarc-André Lureau 138*2668dc7bSMarc-André Lureau def handle_comment(self, data): 139*2668dc7bSMarc-André Lureau comment_state = DBusXMLParser.COMMENT_STATE_BEGIN 140*2668dc7bSMarc-André Lureau lines = data.split("\n") 141*2668dc7bSMarc-André Lureau symbol = "" 142*2668dc7bSMarc-André Lureau body = "" 143*2668dc7bSMarc-André Lureau in_para = False 144*2668dc7bSMarc-André Lureau params = {} 145*2668dc7bSMarc-André Lureau for line in lines: 146*2668dc7bSMarc-André Lureau orig_line = line 147*2668dc7bSMarc-André Lureau line = line.lstrip() 148*2668dc7bSMarc-André Lureau if comment_state == DBusXMLParser.COMMENT_STATE_BEGIN: 149*2668dc7bSMarc-André Lureau if len(line) > 0: 150*2668dc7bSMarc-André Lureau colon_index = line.find(": ") 151*2668dc7bSMarc-André Lureau if colon_index == -1: 152*2668dc7bSMarc-André Lureau if line.endswith(":"): 153*2668dc7bSMarc-André Lureau symbol = line[0 : len(line) - 1] 154*2668dc7bSMarc-André Lureau comment_state = DBusXMLParser.COMMENT_STATE_PARAMS 155*2668dc7bSMarc-André Lureau else: 156*2668dc7bSMarc-André Lureau comment_state = DBusXMLParser.COMMENT_STATE_SKIP 157*2668dc7bSMarc-André Lureau else: 158*2668dc7bSMarc-André Lureau symbol = line[0:colon_index] 159*2668dc7bSMarc-André Lureau rest_of_line = line[colon_index + 2 :].strip() 160*2668dc7bSMarc-André Lureau if len(rest_of_line) > 0: 161*2668dc7bSMarc-André Lureau body += rest_of_line + "\n" 162*2668dc7bSMarc-André Lureau comment_state = DBusXMLParser.COMMENT_STATE_PARAMS 163*2668dc7bSMarc-André Lureau elif comment_state == DBusXMLParser.COMMENT_STATE_PARAMS: 164*2668dc7bSMarc-André Lureau if line.startswith("@"): 165*2668dc7bSMarc-André Lureau colon_index = line.find(": ") 166*2668dc7bSMarc-André Lureau if colon_index == -1: 167*2668dc7bSMarc-André Lureau comment_state = DBusXMLParser.COMMENT_STATE_BODY 168*2668dc7bSMarc-André Lureau if not in_para: 169*2668dc7bSMarc-André Lureau in_para = True 170*2668dc7bSMarc-André Lureau body += orig_line + "\n" 171*2668dc7bSMarc-André Lureau else: 172*2668dc7bSMarc-André Lureau param = line[1:colon_index] 173*2668dc7bSMarc-André Lureau docs = line[colon_index + 2 :] 174*2668dc7bSMarc-André Lureau params[param] = docs 175*2668dc7bSMarc-André Lureau else: 176*2668dc7bSMarc-André Lureau comment_state = DBusXMLParser.COMMENT_STATE_BODY 177*2668dc7bSMarc-André Lureau if len(line) > 0: 178*2668dc7bSMarc-André Lureau if not in_para: 179*2668dc7bSMarc-André Lureau in_para = True 180*2668dc7bSMarc-André Lureau body += orig_line + "\n" 181*2668dc7bSMarc-André Lureau elif comment_state == DBusXMLParser.COMMENT_STATE_BODY: 182*2668dc7bSMarc-André Lureau if len(line) > 0: 183*2668dc7bSMarc-André Lureau if not in_para: 184*2668dc7bSMarc-André Lureau in_para = True 185*2668dc7bSMarc-André Lureau body += orig_line + "\n" 186*2668dc7bSMarc-André Lureau else: 187*2668dc7bSMarc-André Lureau if in_para: 188*2668dc7bSMarc-André Lureau body += "\n" 189*2668dc7bSMarc-André Lureau in_para = False 190*2668dc7bSMarc-André Lureau if in_para: 191*2668dc7bSMarc-André Lureau body += "\n" 192*2668dc7bSMarc-André Lureau 193*2668dc7bSMarc-André Lureau if symbol != "": 194*2668dc7bSMarc-André Lureau self.doc_comment_last_symbol = symbol 195*2668dc7bSMarc-André Lureau self.doc_comment_params = params 196*2668dc7bSMarc-André Lureau self.doc_comment_body = body 197*2668dc7bSMarc-André Lureau 198*2668dc7bSMarc-André Lureau def handle_char_data(self, data): 199*2668dc7bSMarc-André Lureau # print 'char_data=%s'%data 200*2668dc7bSMarc-André Lureau pass 201*2668dc7bSMarc-André Lureau 202*2668dc7bSMarc-André Lureau def handle_start_element(self, name, attrs): 203*2668dc7bSMarc-André Lureau old_state = self.state 204*2668dc7bSMarc-André Lureau old_cur_object = self._cur_object 205*2668dc7bSMarc-André Lureau if self.state == DBusXMLParser.STATE_IGNORED: 206*2668dc7bSMarc-André Lureau self.state = DBusXMLParser.STATE_IGNORED 207*2668dc7bSMarc-André Lureau elif self.state == DBusXMLParser.STATE_TOP: 208*2668dc7bSMarc-André Lureau if name == DBusXMLParser.STATE_NODE: 209*2668dc7bSMarc-André Lureau self.state = DBusXMLParser.STATE_NODE 210*2668dc7bSMarc-André Lureau else: 211*2668dc7bSMarc-André Lureau self.state = DBusXMLParser.STATE_IGNORED 212*2668dc7bSMarc-André Lureau elif self.state == DBusXMLParser.STATE_NODE: 213*2668dc7bSMarc-André Lureau if name == DBusXMLParser.STATE_INTERFACE: 214*2668dc7bSMarc-André Lureau self.state = DBusXMLParser.STATE_INTERFACE 215*2668dc7bSMarc-André Lureau iface = Interface(attrs["name"]) 216*2668dc7bSMarc-André Lureau self._cur_object = iface 217*2668dc7bSMarc-André Lureau self.parsed_interfaces.append(iface) 218*2668dc7bSMarc-André Lureau elif name == DBusXMLParser.STATE_ANNOTATION: 219*2668dc7bSMarc-André Lureau self.state = DBusXMLParser.STATE_ANNOTATION 220*2668dc7bSMarc-André Lureau anno = Annotation(attrs["name"], attrs["value"]) 221*2668dc7bSMarc-André Lureau self._cur_object.annotations.append(anno) 222*2668dc7bSMarc-André Lureau self._cur_object = anno 223*2668dc7bSMarc-André Lureau else: 224*2668dc7bSMarc-André Lureau self.state = DBusXMLParser.STATE_IGNORED 225*2668dc7bSMarc-André Lureau 226*2668dc7bSMarc-André Lureau # assign docs, if any 227*2668dc7bSMarc-André Lureau if "name" in attrs and self.doc_comment_last_symbol == attrs["name"]: 228*2668dc7bSMarc-André Lureau self._cur_object.doc_string = self.doc_comment_body 229*2668dc7bSMarc-André Lureau if "short_description" in self.doc_comment_params: 230*2668dc7bSMarc-André Lureau short_description = self.doc_comment_params["short_description"] 231*2668dc7bSMarc-André Lureau self._cur_object.doc_string_brief = short_description 232*2668dc7bSMarc-André Lureau if "since" in self.doc_comment_params: 233*2668dc7bSMarc-André Lureau self._cur_object.since = self.doc_comment_params["since"].strip() 234*2668dc7bSMarc-André Lureau 235*2668dc7bSMarc-André Lureau elif self.state == DBusXMLParser.STATE_INTERFACE: 236*2668dc7bSMarc-André Lureau if name == DBusXMLParser.STATE_METHOD: 237*2668dc7bSMarc-André Lureau self.state = DBusXMLParser.STATE_METHOD 238*2668dc7bSMarc-André Lureau method = Method( 239*2668dc7bSMarc-André Lureau attrs["name"], h_type_implies_unix_fd=self._h_type_implies_unix_fd 240*2668dc7bSMarc-André Lureau ) 241*2668dc7bSMarc-André Lureau self._cur_object.methods.append(method) 242*2668dc7bSMarc-André Lureau self._cur_object = method 243*2668dc7bSMarc-André Lureau elif name == DBusXMLParser.STATE_SIGNAL: 244*2668dc7bSMarc-André Lureau self.state = DBusXMLParser.STATE_SIGNAL 245*2668dc7bSMarc-André Lureau signal = Signal(attrs["name"]) 246*2668dc7bSMarc-André Lureau self._cur_object.signals.append(signal) 247*2668dc7bSMarc-André Lureau self._cur_object = signal 248*2668dc7bSMarc-André Lureau elif name == DBusXMLParser.STATE_PROPERTY: 249*2668dc7bSMarc-André Lureau self.state = DBusXMLParser.STATE_PROPERTY 250*2668dc7bSMarc-André Lureau prop = Property(attrs["name"], attrs["type"], attrs["access"]) 251*2668dc7bSMarc-André Lureau self._cur_object.properties.append(prop) 252*2668dc7bSMarc-André Lureau self._cur_object = prop 253*2668dc7bSMarc-André Lureau elif name == DBusXMLParser.STATE_ANNOTATION: 254*2668dc7bSMarc-André Lureau self.state = DBusXMLParser.STATE_ANNOTATION 255*2668dc7bSMarc-André Lureau anno = Annotation(attrs["name"], attrs["value"]) 256*2668dc7bSMarc-André Lureau self._cur_object.annotations.append(anno) 257*2668dc7bSMarc-André Lureau self._cur_object = anno 258*2668dc7bSMarc-André Lureau else: 259*2668dc7bSMarc-André Lureau self.state = DBusXMLParser.STATE_IGNORED 260*2668dc7bSMarc-André Lureau 261*2668dc7bSMarc-André Lureau # assign docs, if any 262*2668dc7bSMarc-André Lureau if "name" in attrs and self.doc_comment_last_symbol == attrs["name"]: 263*2668dc7bSMarc-André Lureau self._cur_object.doc_string = self.doc_comment_body 264*2668dc7bSMarc-André Lureau if "since" in self.doc_comment_params: 265*2668dc7bSMarc-André Lureau self._cur_object.since = self.doc_comment_params["since"].strip() 266*2668dc7bSMarc-André Lureau 267*2668dc7bSMarc-André Lureau elif self.state == DBusXMLParser.STATE_METHOD: 268*2668dc7bSMarc-André Lureau if name == DBusXMLParser.STATE_ARG: 269*2668dc7bSMarc-André Lureau self.state = DBusXMLParser.STATE_ARG 270*2668dc7bSMarc-André Lureau arg_name = None 271*2668dc7bSMarc-André Lureau if "name" in attrs: 272*2668dc7bSMarc-André Lureau arg_name = attrs["name"] 273*2668dc7bSMarc-André Lureau arg = Arg(arg_name, attrs["type"]) 274*2668dc7bSMarc-André Lureau direction = attrs.get("direction", "in") 275*2668dc7bSMarc-André Lureau if direction == "in": 276*2668dc7bSMarc-André Lureau self._cur_object.in_args.append(arg) 277*2668dc7bSMarc-André Lureau elif direction == "out": 278*2668dc7bSMarc-André Lureau self._cur_object.out_args.append(arg) 279*2668dc7bSMarc-André Lureau else: 280*2668dc7bSMarc-André Lureau raise ValueError('Invalid direction "{}"'.format(direction)) 281*2668dc7bSMarc-André Lureau self._cur_object = arg 282*2668dc7bSMarc-André Lureau elif name == DBusXMLParser.STATE_ANNOTATION: 283*2668dc7bSMarc-André Lureau self.state = DBusXMLParser.STATE_ANNOTATION 284*2668dc7bSMarc-André Lureau anno = Annotation(attrs["name"], attrs["value"]) 285*2668dc7bSMarc-André Lureau self._cur_object.annotations.append(anno) 286*2668dc7bSMarc-André Lureau self._cur_object = anno 287*2668dc7bSMarc-André Lureau else: 288*2668dc7bSMarc-André Lureau self.state = DBusXMLParser.STATE_IGNORED 289*2668dc7bSMarc-André Lureau 290*2668dc7bSMarc-André Lureau # assign docs, if any 291*2668dc7bSMarc-André Lureau if self.doc_comment_last_symbol == old_cur_object.name: 292*2668dc7bSMarc-André Lureau if "name" in attrs and attrs["name"] in self.doc_comment_params: 293*2668dc7bSMarc-André Lureau doc_string = self.doc_comment_params[attrs["name"]] 294*2668dc7bSMarc-André Lureau if doc_string is not None: 295*2668dc7bSMarc-André Lureau self._cur_object.doc_string = doc_string 296*2668dc7bSMarc-André Lureau if "since" in self.doc_comment_params: 297*2668dc7bSMarc-André Lureau self._cur_object.since = self.doc_comment_params[ 298*2668dc7bSMarc-André Lureau "since" 299*2668dc7bSMarc-André Lureau ].strip() 300*2668dc7bSMarc-André Lureau 301*2668dc7bSMarc-André Lureau elif self.state == DBusXMLParser.STATE_SIGNAL: 302*2668dc7bSMarc-André Lureau if name == DBusXMLParser.STATE_ARG: 303*2668dc7bSMarc-André Lureau self.state = DBusXMLParser.STATE_ARG 304*2668dc7bSMarc-André Lureau arg_name = None 305*2668dc7bSMarc-André Lureau if "name" in attrs: 306*2668dc7bSMarc-André Lureau arg_name = attrs["name"] 307*2668dc7bSMarc-André Lureau arg = Arg(arg_name, attrs["type"]) 308*2668dc7bSMarc-André Lureau self._cur_object.args.append(arg) 309*2668dc7bSMarc-André Lureau self._cur_object = arg 310*2668dc7bSMarc-André Lureau elif name == DBusXMLParser.STATE_ANNOTATION: 311*2668dc7bSMarc-André Lureau self.state = DBusXMLParser.STATE_ANNOTATION 312*2668dc7bSMarc-André Lureau anno = Annotation(attrs["name"], attrs["value"]) 313*2668dc7bSMarc-André Lureau self._cur_object.annotations.append(anno) 314*2668dc7bSMarc-André Lureau self._cur_object = anno 315*2668dc7bSMarc-André Lureau else: 316*2668dc7bSMarc-André Lureau self.state = DBusXMLParser.STATE_IGNORED 317*2668dc7bSMarc-André Lureau 318*2668dc7bSMarc-André Lureau # assign docs, if any 319*2668dc7bSMarc-André Lureau if self.doc_comment_last_symbol == old_cur_object.name: 320*2668dc7bSMarc-André Lureau if "name" in attrs and attrs["name"] in self.doc_comment_params: 321*2668dc7bSMarc-André Lureau doc_string = self.doc_comment_params[attrs["name"]] 322*2668dc7bSMarc-André Lureau if doc_string is not None: 323*2668dc7bSMarc-André Lureau self._cur_object.doc_string = doc_string 324*2668dc7bSMarc-André Lureau if "since" in self.doc_comment_params: 325*2668dc7bSMarc-André Lureau self._cur_object.since = self.doc_comment_params[ 326*2668dc7bSMarc-André Lureau "since" 327*2668dc7bSMarc-André Lureau ].strip() 328*2668dc7bSMarc-André Lureau 329*2668dc7bSMarc-André Lureau elif self.state == DBusXMLParser.STATE_PROPERTY: 330*2668dc7bSMarc-André Lureau if name == DBusXMLParser.STATE_ANNOTATION: 331*2668dc7bSMarc-André Lureau self.state = DBusXMLParser.STATE_ANNOTATION 332*2668dc7bSMarc-André Lureau anno = Annotation(attrs["name"], attrs["value"]) 333*2668dc7bSMarc-André Lureau self._cur_object.annotations.append(anno) 334*2668dc7bSMarc-André Lureau self._cur_object = anno 335*2668dc7bSMarc-André Lureau else: 336*2668dc7bSMarc-André Lureau self.state = DBusXMLParser.STATE_IGNORED 337*2668dc7bSMarc-André Lureau 338*2668dc7bSMarc-André Lureau elif self.state == DBusXMLParser.STATE_ARG: 339*2668dc7bSMarc-André Lureau if name == DBusXMLParser.STATE_ANNOTATION: 340*2668dc7bSMarc-André Lureau self.state = DBusXMLParser.STATE_ANNOTATION 341*2668dc7bSMarc-André Lureau anno = Annotation(attrs["name"], attrs["value"]) 342*2668dc7bSMarc-André Lureau self._cur_object.annotations.append(anno) 343*2668dc7bSMarc-André Lureau self._cur_object = anno 344*2668dc7bSMarc-André Lureau else: 345*2668dc7bSMarc-André Lureau self.state = DBusXMLParser.STATE_IGNORED 346*2668dc7bSMarc-André Lureau 347*2668dc7bSMarc-André Lureau elif self.state == DBusXMLParser.STATE_ANNOTATION: 348*2668dc7bSMarc-André Lureau if name == DBusXMLParser.STATE_ANNOTATION: 349*2668dc7bSMarc-André Lureau self.state = DBusXMLParser.STATE_ANNOTATION 350*2668dc7bSMarc-André Lureau anno = Annotation(attrs["name"], attrs["value"]) 351*2668dc7bSMarc-André Lureau self._cur_object.annotations.append(anno) 352*2668dc7bSMarc-André Lureau self._cur_object = anno 353*2668dc7bSMarc-André Lureau else: 354*2668dc7bSMarc-André Lureau self.state = DBusXMLParser.STATE_IGNORED 355*2668dc7bSMarc-André Lureau 356*2668dc7bSMarc-André Lureau else: 357*2668dc7bSMarc-André Lureau raise ValueError( 358*2668dc7bSMarc-André Lureau 'Unhandled state "{}" while entering element with name "{}"'.format( 359*2668dc7bSMarc-André Lureau self.state, name 360*2668dc7bSMarc-André Lureau ) 361*2668dc7bSMarc-André Lureau ) 362*2668dc7bSMarc-André Lureau 363*2668dc7bSMarc-André Lureau self.state_stack.append(old_state) 364*2668dc7bSMarc-André Lureau self._cur_object_stack.append(old_cur_object) 365*2668dc7bSMarc-André Lureau 366*2668dc7bSMarc-André Lureau def handle_end_element(self, name): 367*2668dc7bSMarc-André Lureau self.state = self.state_stack.pop() 368*2668dc7bSMarc-André Lureau self._cur_object = self._cur_object_stack.pop() 369*2668dc7bSMarc-André Lureau 370*2668dc7bSMarc-André Lureau 371*2668dc7bSMarc-André Lureaudef parse_dbus_xml(xml_data): 372*2668dc7bSMarc-André Lureau parser = DBusXMLParser(xml_data, True) 373*2668dc7bSMarc-André Lureau return parser.parsed_interfaces 374