X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvpp-api%2Fvapi%2Fvapi_json_parser.py;h=58a75777f11535d9e3f894ceb90d7c4032abd6fd;hb=d0df49f26eabf2f534b567f3370e50c4e804aeea;hp=a9186a15334d7b06733764e9c7526db82134cd84;hpb=32a9d7bf63015aeeb6dee4a2342933be58871176;p=vpp.git diff --git a/src/vpp-api/vapi/vapi_json_parser.py b/src/vpp-api/vapi/vapi_json_parser.py index a9186a15334..58a75777f11 100644 --- a/src/vpp-api/vapi/vapi_json_parser.py +++ b/src/vpp-api/vapi/vapi_json_parser.py @@ -63,20 +63,20 @@ class SimpleType (Type): return self.name -def get_msg_header_defs(struct_type_class, field_class, typedict): +def get_msg_header_defs(struct_type_class, field_class, typedict, logger): return [ struct_type_class(['msg_header1_t', ['u16', '_vl_msg_id'], ['u32', 'context'], ], - typedict, field_class + typedict, field_class, logger ), struct_type_class(['msg_header2_t', ['u16', '_vl_msg_id'], ['u32', 'client_index'], ['u32', 'context'], ], - typedict, field_class + typedict, field_class, logger ), ] @@ -107,7 +107,7 @@ class Message(object): self.header = None fields = [] for header in get_msg_header_defs(struct_type_class, field_class, - typedict): + typedict, logger): logger.debug("Probing header `%s'" % header.name) if header.is_part_of_def(m[1:]): self.header = header @@ -137,6 +137,7 @@ class Message(object): "While parsing message `%s': could not find " "type by magic name `%s' nor by mundane name " "`%s'" % (name, field_type, mundane_field_type)) + logger.debug("Parsing message field `%s'" % field) if len(field) == 2: if self.header is not None and\ self.header.has_field(field[1]): @@ -187,28 +188,57 @@ class Message(object): class StructType (Type, Struct): - def __init__(self, definition, typedict, field_class): + def __init__(self, definition, typedict, field_class, logger): t = definition + logger.debug("Parsing struct definition `%s'" % t) name = t[0] fields = [] for field in t[1:]: if len(field) == 1 and 'crc' in field: self.crc = field['crc'] continue - elif len(field) == 2: + field_type = field[0] + if field_type in typedict: + field_type = typedict[field_type] + else: + mundane_field_type = remove_magic(field_type) + if mundane_field_type in typedict: + field_type = typedict[mundane_field_type] + else: + raise ParseError( + "While parsing message `%s': could not find " + "type by magic name `%s' nor by mundane name " + "`%s'" % (name, field_type, mundane_field_type)) + logger.debug("Parsing type field `%s'" % field) + if len(field) == 2: p = field_class(field_name=field[1], - field_type=typedict[field[0]]) + field_type=field_type) elif len(field) == 3: if field[2] == 0: raise ParseError("While parsing type `%s': array `%s' has " "variable length" % (name, field[1])) p = field_class(field_name=field[1], - field_type=typedict[field[0]], + field_type=field_type, array_len=field[2]) + elif len(field) == 4: + nelem_field = None + for f in fields: + if f.name == field[3]: + nelem_field = f + if nelem_field is None: + raise ParseError( + "While parsing message `%s': couldn't find " + "variable length array `%s' member containing " + "the actual length `%s'" % ( + name, field[1], field[3])) + p = field_class(field_name=field[1], + field_type=field_type, + array_len=field[2], + nelem_field=nelem_field) else: raise ParseError( - "Don't know how to parse type definition for " - "type `%s': `%s'" % (t, t[1:])) + "Don't know how to parse field `%s' of type definition " + "for type `%s'" % (field, t)) fields.append(p) Type.__init__(self, name) Struct.__init__(self, name, fields) @@ -264,35 +294,49 @@ class JsonParser(object): def parse_json_file(self, path): self.logger.info("Parsing json api file: `%s'" % path) self.json_files.append(path) - self.types_by_json[path] = {} + self.types_by_json[path] = [] self.messages_by_json[path] = {} with open(path) as f: j = json.load(f) for t in j['types']: try: type_ = self.struct_type_class(t, self.types, - self.field_class) + self.field_class, + self.logger) if type_.name in self.types: raise ParseError("Duplicate type `%s'" % type_.name) except ParseError as e: self.exceptions.append(e) continue self.types[type_.name] = type_ - self.types_by_json[path][type_.name] = type_ + self.types_by_json[path].append(type_) self.logger.debug("Parsed type: %s" % type_) - for m in j['messages']: - try: - msg = self.message_class(self.logger, m, self.types, - self.struct_type_class, - self.simple_type_class, - self.field_class) - if msg.name in self.messages: - raise ParseError("Duplicate message `%s'" % msg.name) - except ParseError as e: - self.exceptions.append(e) - continue - self.messages[msg.name] = msg - self.messages_by_json[path][msg.name] = msg + prev_length = len(self.messages) + processed = [] + while True: + exceptions = [] + for m in j['messages']: + if m in processed: + continue + try: + msg = self.message_class(self.logger, m, self.types, + self.struct_type_class, + self.simple_type_class, + self.field_class) + if msg.name in self.messages: + raise ParseError( + "Duplicate message `%s'" % msg.name) + except ParseError as e: + exceptions.append(e) + continue + self.messages[msg.name] = msg + self.messages_by_json[path][msg.name] = msg + processed.append(m) + if prev_length == len(self.messages): + # cannot make forward progress ... + self.exceptions.extend(exceptions) + break + prev_length = len(self.messages) def get_reply(self, message): if self.messages[message].is_dump(): @@ -303,7 +347,6 @@ class JsonParser(object): if len(self.messages) == 0: for e in self.exceptions: self.logger.error(e) - raise Exception("No messages parsed.") for jn, j in self.messages_by_json.items(): remove = [] for n, m in j.items():