aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKlement Sekera <ksekera@cisco.com>2018-05-03 14:27:42 +0200
committerOle Trøan <otroan@employees.org>2018-05-04 07:22:12 +0000
commit8b6b5ab7dba7cb5fe738c887e27c65bee6a2f600 (patch)
treefd01e7c690d260eda1794b145c4cfb15384dd757
parentdbc38ee7e53ca9bf7e6912a950a802c2db87f47d (diff)
VAPI: support VLAs in type definitions
Change-Id: I8d54415972d6644190857175b0e895c5319ce7b6 Signed-off-by: Klement Sekera <ksekera@cisco.com>
-rwxr-xr-xsrc/vpp-api/vapi/vapi_c_gen.py18
-rwxr-xr-xsrc/vpp-api/vapi/vapi_cpp_gen.py24
-rw-r--r--src/vpp-api/vapi/vapi_json_parser.py74
3 files changed, 57 insertions, 59 deletions
diff --git a/src/vpp-api/vapi/vapi_c_gen.py b/src/vpp-api/vapi/vapi_c_gen.py
index eaa22c5bc03..b85f1e9d248 100755
--- a/src/vpp-api/vapi/vapi_c_gen.py
+++ b/src/vpp-api/vapi/vapi_c_gen.py
@@ -9,15 +9,6 @@ from vapi_json_parser import Field, Struct, Message, JsonParser,\
class CField(Field):
- def __init__(
- self,
- field_name,
- field_type,
- array_len=None,
- nelem_field=None):
- super(CField, self).__init__(
- field_name, field_type, array_len, nelem_field)
-
def get_c_def(self):
if self.len is not None:
return "%s %s[%d]" % (self.type.get_c_name(), self.name, self.len)
@@ -67,9 +58,6 @@ class CField(Field):
class CStruct(Struct):
- def __init__(self, name, fields):
- super(CStruct, self).__init__(name, fields)
-
def duplicate_barrier(func):
def func_wrapper(self):
name = self.get_c_name()
@@ -99,9 +87,6 @@ class CSimpleType (SimpleType):
'i64': 'be64toh', 'u64': 'be64toh',
}
- def __init__(self, name):
- super(CSimpleType, self).__init__(name)
-
def get_c_name(self):
return self.name
@@ -129,9 +114,6 @@ class CSimpleType (SimpleType):
class CStructType (StructType, CStruct):
- def __init__(self, definition, typedict, field_class):
- super(CStructType, self).__init__(definition, typedict, field_class)
-
def get_c_name(self):
return "vapi_type_%s" % self.name
diff --git a/src/vpp-api/vapi/vapi_cpp_gen.py b/src/vpp-api/vapi/vapi_cpp_gen.py
index 3010f3e1919..e83e151a879 100755
--- a/src/vpp-api/vapi/vapi_cpp_gen.py
+++ b/src/vpp-api/vapi/vapi_cpp_gen.py
@@ -10,38 +10,22 @@ from vapi_json_parser import JsonParser
class CppField(CField):
- def __init__(
- self,
- field_name,
- field_type,
- array_len=None,
- nelem_field=None):
- super(CppField, self).__init__(
- field_name, field_type, array_len, nelem_field)
+ pass
class CppStruct(CStruct):
- def __init__(self, name, fields):
- super(CppStruct, self).__init__(name, fields)
+ pass
class CppSimpleType (CSimpleType):
- def __init__(self, name):
- super(CppSimpleType, self).__init__(name)
+ pass
class CppStructType (CStructType, CppStruct):
- def __init__(self, definition, typedict, field_class):
- super(CppStructType, self).__init__(definition, typedict, field_class)
+ pass
class CppMessage (CMessage):
- def __init__(self, logger, definition, typedict,
- struct_type_class, simple_type_class, field_class):
- super(CppMessage, self).__init__(
- logger, definition, typedict, struct_type_class,
- simple_type_class, field_class)
-
def get_swap_to_be_template_instantiation(self):
return "\n".join([
"template <> inline void vapi_swap_to_be<%s>(%s *msg)" %
diff --git a/src/vpp-api/vapi/vapi_json_parser.py b/src/vpp-api/vapi/vapi_json_parser.py
index b52b95be6dc..0da2a5e32b3 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,8 +188,9 @@ 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:]:
@@ -207,6 +209,7 @@ class StructType (Type, Struct):
"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=field_type)
@@ -217,10 +220,25 @@ class StructType (Type, Struct):
p = field_class(field_name=field[1],
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)
@@ -283,7 +301,8 @@ class JsonParser(object):
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:
@@ -292,19 +311,32 @@ class JsonParser(object):
self.types[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():