vppapigen: add parser support for enumflags
Type: improvement
Change-Id: I0f15862cc8399a4f7c8a81fe44ba8b27d8772278
Signed-off-by: Paul Vinciguerra <pvinci@vinciconsulting.com>
Signed-off-by: Ole Troan <ot@cisco.com>
(cherry picked from commit e15523297b
)
This commit is contained in:

committed by
Ole Tr�an

parent
86ffb6b232
commit
a51f9b3747
@ -1,9 +1,11 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import unittest
|
||||
from vppapigen import VPPAPI, Option, ParseError, Union, foldup_crcs, global_types
|
||||
from vppapigen import VPPAPI, Option, ParseError, Union, foldup_crcs, \
|
||||
global_types
|
||||
import vppapigen
|
||||
|
||||
|
||||
# TODO
|
||||
# - test parsing of options, typedefs, enums, defines
|
||||
# - test JSON, C output
|
||||
@ -19,6 +21,7 @@ class TestVersion(unittest.TestCase):
|
||||
r = self.parser.parse_string(version_string)
|
||||
self.assertTrue(isinstance(r[0], Option))
|
||||
|
||||
|
||||
class TestUnion(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
@ -49,7 +52,6 @@ class TestUnion(unittest.TestCase):
|
||||
self.assertTrue(r[0].vla)
|
||||
s = self.parser.process(r)
|
||||
|
||||
|
||||
test_string2 = '''
|
||||
union foo_union_vla2 {
|
||||
u32 a;
|
||||
@ -74,6 +76,7 @@ class TestUnion(unittest.TestCase):
|
||||
'''
|
||||
self.assertRaises(ValueError, self.parser.parse_string, test_string3)
|
||||
|
||||
|
||||
class TestTypedef(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
@ -169,7 +172,7 @@ class TestCRC(unittest.TestCase):
|
||||
'''
|
||||
crc = get_crc(test_string, 'foo')
|
||||
|
||||
# modify underlaying type
|
||||
# modify underlying type
|
||||
test_string = '''
|
||||
typedef list { u8 foo2; };
|
||||
autoreply define foo { u8 foo; vl_api_list_t l;};
|
||||
@ -255,5 +258,97 @@ autoreply define sr_policy_add
|
||||
|
||||
self.assertNotEqual(crc, crc2)
|
||||
|
||||
|
||||
class TestEnum(unittest.TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.parser = VPPAPI()
|
||||
|
||||
def test_enum_as_enum(self):
|
||||
test_string = """\
|
||||
enum tunnel_mode : u8
|
||||
{
|
||||
/** point-to-point */
|
||||
TUNNEL_API_MODE_P2P = 0,
|
||||
/** multi-point */
|
||||
TUNNEL_API_MODE_MP,
|
||||
};
|
||||
"""
|
||||
r = self.parser.parse_string(test_string)
|
||||
self.assertIsNotNone(r)
|
||||
s = self.parser.process(r)
|
||||
for o in s['types']:
|
||||
if o.type == 'Enum':
|
||||
self.assertEqual(o.name, "tunnel_mode")
|
||||
break
|
||||
else:
|
||||
self.fail()
|
||||
|
||||
def test_enumflag_as_enum(self):
|
||||
test_string = """\
|
||||
enum virtio_flags {
|
||||
VIRTIO_API_FLAG_GSO = 1, /* enable gso on the interface */
|
||||
VIRTIO_API_FLAG_CSUM_OFFLOAD = 2, /* enable checksum offload without gso on the interface */
|
||||
VIRTIO_API_FLAG_GRO_COALESCE = 4, /* enable packet coalescing on tx side, provided gso enabled */
|
||||
VIRTIO_API_FLAG_PACKED = 8, /* enable packed ring support, provided it is available from backend */
|
||||
VIRTIO_API_FLAG_IN_ORDER = 16, /* enable in order support, provided it is available from backend */
|
||||
VIRTIO_API_FLAG_BUFFERING = 32 [backwards_compatible], /* enable buffering to handle backend jitter/delays */
|
||||
};"""
|
||||
r = self.parser.parse_string(test_string)
|
||||
self.assertIsNotNone(r)
|
||||
s = self.parser.process(r)
|
||||
for o in s['types']:
|
||||
if o.type == 'Enum':
|
||||
self.assertEqual(o.name, "virtio_flags")
|
||||
break
|
||||
else:
|
||||
self.fail()
|
||||
|
||||
|
||||
class TestEnumFlag(unittest.TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.parser = VPPAPI()
|
||||
|
||||
def test_enum_as_enumflag(self):
|
||||
test_string = """\
|
||||
enumflag tunnel_mode_ef : u8
|
||||
{
|
||||
/** point-to-point */
|
||||
TUNNEL_API_MODE_P2P = 0,
|
||||
/** multi-point */
|
||||
TUNNEL_API_MODE_MP,
|
||||
TUNNEL_API_MODE_FOO,
|
||||
TUNNEL_API_MODE_BAR,
|
||||
};"""
|
||||
with self.assertRaises(TypeError) as ctx:
|
||||
r = self.parser.parse_string(test_string)
|
||||
|
||||
self.assertTrue(str(ctx.exception).startswith(
|
||||
'tunnel_mode_ef is not a flag enum.'))
|
||||
|
||||
def test_enumflag_as_enumflag(self):
|
||||
test_string = """\
|
||||
enumflag virtio_flags_ef {
|
||||
VIRTIO_API_FLAG_GSO = 1, /* enable gso on the interface */
|
||||
VIRTIO_API_FLAG_CSUM_OFFLOAD = 2, /* enable checksum offload without gso on the interface */
|
||||
VIRTIO_API_FLAG_GRO_COALESCE = 4, /* enable packet coalescing on tx side, provided gso enabled */
|
||||
VIRTIO_API_FLAG_PACKED = 8, /* enable packed ring support, provided it is available from backend */
|
||||
VIRTIO_API_FLAG_IN_ORDER = 16, /* enable in order support, provided it is available from backend */
|
||||
VIRTIO_API_FLAG_BUFFERING = 32 [backwards_compatible], /* enable buffering to handle backend jitter/delays */
|
||||
};"""
|
||||
r = self.parser.parse_string(test_string)
|
||||
self.assertIsNotNone(r)
|
||||
s = self.parser.process(r)
|
||||
for o in s['types']:
|
||||
if o.type == 'EnumFlag':
|
||||
self.assertEqual(o.name, "virtio_flags_ef")
|
||||
break
|
||||
else:
|
||||
self.fail()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(verbosity=2)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -32,6 +32,7 @@ import shutil
|
||||
|
||||
process_imports = False
|
||||
|
||||
|
||||
###############################################################################
|
||||
class ToJSON():
|
||||
'''Class to generate functions converting from VPP binary API to JSON.'''
|
||||
@ -89,7 +90,7 @@ class ToJSON():
|
||||
return 'cJSON_AddBoolToObject', '', False
|
||||
|
||||
# Lookup type name check if it's enum
|
||||
if vt.type == 'Enum':
|
||||
if vt.type == 'Enum' or vt.type == 'EnumFlag':
|
||||
return '{t}_tojson'.format(t=t), '', True
|
||||
return '{t}_tojson'.format(t=t), '&', True
|
||||
|
||||
@ -186,6 +187,7 @@ class ToJSON():
|
||||
write('}\n')
|
||||
|
||||
_dispatch['Enum'] = print_enum
|
||||
_dispatch['EnumFlag'] = print_enum
|
||||
|
||||
def print_typedef(self, o):
|
||||
'''Create cJSON (dictionary) object from VPP API typedef'''
|
||||
@ -454,6 +456,7 @@ class FromJSON():
|
||||
write('}\n')
|
||||
|
||||
_dispatch['Enum'] = print_enum
|
||||
_dispatch['EnumFlag'] = print_enum
|
||||
|
||||
def print_typedef(self, o):
|
||||
'''Convert from JSON object to VPP API binary representation'''
|
||||
@ -845,6 +848,7 @@ class Printfun():
|
||||
write(' }\n')
|
||||
|
||||
_dispatch['Enum'] = print_enum
|
||||
_dispatch['EnumFlag'] = print_enum
|
||||
|
||||
def print_obj(self, o, stream):
|
||||
'''Entry point'''
|
||||
@ -935,7 +939,7 @@ static inline u8 *format_vl_api_{name}_t (u8 *s, va_list * args)
|
||||
'''
|
||||
|
||||
for t in objs:
|
||||
if t.__class__.__name__ == 'Enum':
|
||||
if t.__class__.__name__ == 'Enum' or t.__class__.__name__ == 'EnumFlag':
|
||||
write(signature.format(name=t.name))
|
||||
pp.print_enum(t.block, stream)
|
||||
write(' return s;\n')
|
||||
@ -1071,7 +1075,7 @@ static inline void vl_api_{name}_t_endian (vl_api_{name}_t *a)
|
||||
'''
|
||||
|
||||
for t in objs:
|
||||
if t.__class__.__name__ == 'Enum':
|
||||
if t.__class__.__name__ == 'Enum' or t.__class__.__name__ == 'EnumFlag' :
|
||||
output += signature.format(name=t.name)
|
||||
if t.enumtype in ENDIAN_STRINGS:
|
||||
output += (' *a = {}(*a);\n'
|
||||
@ -1191,7 +1195,7 @@ def generate_include_types(s, module, stream):
|
||||
(o.alias['type'], o.name, o.alias['length']))
|
||||
else:
|
||||
write('typedef %s vl_api_%s_t;\n' % (o.alias['type'], o.name))
|
||||
elif tname == 'Enum':
|
||||
elif tname == 'Enum' or tname == 'EnumFlag':
|
||||
if o.enumtype == 'u32':
|
||||
write("typedef enum {\n")
|
||||
else:
|
||||
|
@ -96,6 +96,8 @@ def run(args, filename, s):
|
||||
if o.__class__.__name__ == 'Union']))
|
||||
j['enums'] = (walk_enums([o for o in s['types']
|
||||
if o.__class__.__name__ == 'Enum']))
|
||||
j['enumflags'] = (walk_enums([o for o in s['types']
|
||||
if o.__class__.__name__ == 'EnumFlag']))
|
||||
j['services'] = walk_services(s['Service'])
|
||||
j['options'] = s['Option']
|
||||
j['aliases'] = {o.name:o.alias for o in s['types'] if o.__class__.__name__ == 'Using'}
|
||||
|
Reference in New Issue
Block a user