xref: /btstack/tool/python_generator.py (revision b1f6df3b39134c33d506bab33d95fb138f6ea695)
173a17974SMatthias Ringwald#!/usr/bin/env python
273a17974SMatthias Ringwald# BlueKitchen GmbH (c) 2018
373a17974SMatthias Ringwald
473a17974SMatthias Ringwaldimport glob
573a17974SMatthias Ringwaldimport re
673a17974SMatthias Ringwaldimport sys
773a17974SMatthias Ringwaldimport os
873a17974SMatthias Ringwald
973a17974SMatthias Ringwaldimport btstack_parser as parser
1073a17974SMatthias Ringwald
1173a17974SMatthias Ringwaldprint('''
1273a17974SMatthias RingwaldPython binding generator for BTstack Server
1373a17974SMatthias RingwaldCopyright 2018, BlueKitchen GmbH
1473a17974SMatthias Ringwald''')
1573a17974SMatthias Ringwald
1673a17974SMatthias Ringwald# com.bluekitchen.btstack.BTstack.java templates
1773a17974SMatthias Ringwaldcommand_builder_header = \
1873a17974SMatthias Ringwald'''#!/usr/bin/env python3
1973a17974SMatthias Ringwald
2073a17974SMatthias Ringwaldimport struct
2173a17974SMatthias Ringwald
2201aeeea2SMatthias Ringwalddef opcode(ogf, ocf):
2301aeeea2SMatthias Ringwald    return ocf | (ogf << 10)
2473a17974SMatthias Ringwald
2573a17974SMatthias Ringwalddef pack24(value):
2673a17974SMatthias Ringwald    return struct.pack("B", value & 0xff) + struct.pack("<H", value >> 8)
2773a17974SMatthias Ringwald
2873a17974SMatthias Ringwalddef name248(str):
2973a17974SMatthias Ringwald    arg = str.encode('utf-8')
3073a17974SMatthias Ringwald    return arg[:248] + bytes(248-len(arg))
3173a17974SMatthias Ringwald
3201aeeea2SMatthias Ringwald# Command Builder
3301aeeea2SMatthias Ringwald
3401aeeea2SMatthias Ringwaldclass CommandBuilder(object):
35760c6692SMatthias Ringwald
3601aeeea2SMatthias Ringwald    def __init__(self):
3701aeeea2SMatthias Ringwald        pass
3801aeeea2SMatthias Ringwald
3973a17974SMatthias Ringwald    def send_command(command):
4073a17974SMatthias Ringwald        return FALSE
4173a17974SMatthias Ringwald
4273a17974SMatthias Ringwald'''
43760c6692SMatthias Ringwald
4473a17974SMatthias Ringwaldcommand_builder_command = '''
4501aeeea2SMatthias Ringwald    def {name}(self, {args}):
4673a17974SMatthias Ringwald        cmd_args = bytes()
4773a17974SMatthias Ringwald{args_builder}
4801aeeea2SMatthias Ringwald        cmd = struct.pack("<HB", opcode(self.{ogf}, self.{ocf}), len(cmd_args)) + cmd_args
4973a17974SMatthias Ringwald        return self.send_hci_command(cmd)
5073a17974SMatthias Ringwald'''
5173a17974SMatthias Ringwald
5273a17974SMatthias Ringwald# com.bluekitchen.btstack.EventFactory template
53760c6692SMatthias Ringwaldevent_factory_template = \
54dbd33601SMatthias Ringwald'''
5573a17974SMatthias Ringwald
56760c6692SMatthias Ringwald# dictionary to map hci event types to event classes
57760c6692SMatthias Ringwaldevent_class_for_type = {{
58760c6692SMatthias Ringwald{1}}}
5973a17974SMatthias Ringwald
60760c6692SMatthias Ringwald# dictionary to map hci le event types to event classes
61760c6692SMatthias Ringwaldle_event_class_for_type = {{
62760c6692SMatthias Ringwald{2}}}
6373a17974SMatthias Ringwald
64760c6692SMatthias Ringwald# list of all event types - not actually used
65dbd33601SMatthias Ringwald{0}
6673a17974SMatthias Ringwald
67760c6692SMatthias Ringwalddef event_for_payload(payload):
68760c6692SMatthias Ringwald    event_type  = payload[0]
69760c6692SMatthias Ringwald    event_class = btstack.btstack_types.Event
70760c6692SMatthias Ringwald    # LE Subevent
71760c6692SMatthias Ringwald    if event_type == 0x3e:
72760c6692SMatthias Ringwald        subevent_type = payload[2]
73*b1f6df3bSMatthias Ringwald        event_class = le_event_class_for_type.get(subevent_type, event_class)
74760c6692SMatthias Ringwald    else:
75*b1f6df3bSMatthias Ringwald        event_class = event_class_for_type.get(event_type, event_class)
76760c6692SMatthias Ringwald    return event_class(payload)
7773a17974SMatthias Ringwald'''
78760c6692SMatthias Ringwaldevent_factory_event =  \
79760c6692SMatthias Ringwald'''    {0} : {1},
8073a17974SMatthias Ringwald'''
81760c6692SMatthias Ringwaldevent_factory_subevent = \
82760c6692SMatthias Ringwald'''    {0} : {1},
8373a17974SMatthias Ringwald'''
8473a17974SMatthias Ringwald
85760c6692SMatthias Ringwaldevent_header = '''
86*b1f6df3bSMatthias Ringwaldimport struct
87760c6692SMatthias Ringwaldimport btstack.btstack_types
88*b1f6df3bSMatthias Ringwald
89*b1f6df3bSMatthias Ringwalddef hex_string(bytes):
90*b1f6df3bSMatthias Ringwald    return " ".join([('%02x' % a) for a in bytes])
91*b1f6df3bSMatthias Ringwald
92dbd33601SMatthias Ringwald'''
9373a17974SMatthias Ringwald
94760c6692SMatthias Ringwaldevent_template = \
95760c6692SMatthias Ringwald'''
9673a17974SMatthias Ringwald
97760c6692SMatthias Ringwaldclass {0}(btstack.btstack_types.Event):
98760c6692SMatthias Ringwald
99760c6692SMatthias Ringwald    def __init__(self, payload):
100760c6692SMatthias Ringwald        super().__init__(payload)
101dbd33601SMatthias Ringwald    {1}
10273a17974SMatthias Ringwald    {2}
10373a17974SMatthias Ringwald'''
10473a17974SMatthias Ringwald
105760c6692SMatthias Ringwaldevent_getter = \
10673a17974SMatthias Ringwald'''
107760c6692SMatthias Ringwald    def get_{0}(self):
108dbd33601SMatthias Ringwald        {1}
109760c6692SMatthias Ringwald'''
110760c6692SMatthias Ringwald
111*b1f6df3bSMatthias Ringwaldevent_getter_data = '''return self.payload[{offset}:{offset}+self.get_{length_name}()]
112760c6692SMatthias Ringwald'''
113760c6692SMatthias Ringwald
114760c6692SMatthias Ringwaldevent_getter_data_fixed = \
115*b1f6df3bSMatthias Ringwald'''return self.payload[{offset}:{offset}+{size}]
116760c6692SMatthias Ringwald'''
117760c6692SMatthias Ringwald
118760c6692SMatthias Ringwaldevent_to_string = \
119760c6692SMatthias Ringwald'''def __repr__(self):
120760c6692SMatthias Ringwald        repr  = '{0} < type=0x%02x' % self.get_event_type()
121760c6692SMatthias Ringwald{1}
122760c6692SMatthias Ringwald        repr += " >"
123760c6692SMatthias Ringwald        return repr
12473a17974SMatthias Ringwald'''
12573a17974SMatthias Ringwald
12673a17974SMatthias Ringwald
12773a17974SMatthias Ringwald# global variables/defines
12873a17974SMatthias Ringwaldpackage  ='com.bluekitchen.btstack'
12973a17974SMatthias Ringwaldgen_path = 'gen/' + package.replace('.', '/')
13073a17974SMatthias Ringwald
13173a17974SMatthias Ringwalddefines = dict()
13273a17974SMatthias Ringwalddefines_used = set()
13373a17974SMatthias Ringwald
13473a17974SMatthias Ringwalddef size_for_type(type):
13573a17974SMatthias Ringwald    param_sizes = { '1' : 1, '2' : 2, '3' : 3, '4' : 4, 'H' : 2, 'B' : 6, 'D' : 8, 'E' : 240, 'N' : 248, 'P' : 16,
13673a17974SMatthias Ringwald                    'A' : 31, 'S' : -1, 'V': -1, 'J' : 1, 'L' : 2, 'Q' : 32, 'U' : 16, 'X' : 20, 'Y' : 24, 'Z' : 18, 'T':-1}
13773a17974SMatthias Ringwald    return param_sizes[type]
13873a17974SMatthias Ringwald
13973a17974SMatthias Ringwalddef create_command_python(fout, name, ogf, ocf, format, params):
14073a17974SMatthias Ringwald    global command_builder_command
14173a17974SMatthias Ringwald
14273a17974SMatthias Ringwald    ind = '        '
14373a17974SMatthias Ringwald    param_store = {
14473a17974SMatthias Ringwald     '1' : 'cmd_args += struct.pack("B", %s)',
14573a17974SMatthias Ringwald     'J' : 'cmd_args += struct.pack("B", %s)',
14673a17974SMatthias Ringwald     '2' : 'cmd_args += struct.pack("<H", %s)',
14773a17974SMatthias Ringwald     'H' : 'cmd_args += struct.pack("<H", %s)',
14873a17974SMatthias Ringwald     'L' : 'cmd_args += struct.pack("<H", %s)',
14901aeeea2SMatthias Ringwald     '3' : 'cmd_args += pack24(%s)',
15073a17974SMatthias Ringwald     '4' : 'cmd_args += struct.pack("<H", %s)',
15101aeeea2SMatthias Ringwald     'N' : 'cmd_args += name248(%s)',
15273a17974SMatthias Ringwald     'B' : 'cmd_args += %s.get_bytes()',
15373a17974SMatthias Ringwald     'U' : 'cmd_args += %s.get_bytes()',
15473a17974SMatthias Ringwald     'X' : 'cmd_args += %s.get_bytes()',
15573a17974SMatthias Ringwald     'Y' : 'cmd_args += %s.get_bytes()',
15673a17974SMatthias Ringwald     'Z' : 'cmd_args += %s.get_bytes()',
15773a17974SMatthias Ringwald     'S' : 'cmd_args += %s',
15873a17974SMatthias Ringwald     # TODO: support serialization for these
15973a17974SMatthias Ringwald     'D' : '# D / TODO Util.storeBytes(command, offset, %s, 8)',
16073a17974SMatthias Ringwald     'E' : '# E / TODO Util.storeBytes(command, offset, %s, 240)',
16173a17974SMatthias Ringwald     'P' : '# P / TODO Util.storeBytes(command, offset, %s, 16)',
16273a17974SMatthias Ringwald     'Q' : '# Q / TODO Util.storeBytes(command, offset, %s, 32)',
16373a17974SMatthias Ringwald     'A' : '# A / TODO Util.storeBytes(command, offset, %s, 31)',
16473a17974SMatthias Ringwald     }
16573a17974SMatthias Ringwald    # method arguments
16673a17974SMatthias Ringwald    arg_counter = 1
16773a17974SMatthias Ringwald    args = []
16873a17974SMatthias Ringwald    for param_type, arg_name in zip(format, params):
16973a17974SMatthias Ringwald        arg_size = size_for_type(param_type)
17073a17974SMatthias Ringwald        arg = (param_type, arg_size, arg_name)
17173a17974SMatthias Ringwald        args.append(arg)
17273a17974SMatthias Ringwald        arg_counter += 1
17373a17974SMatthias Ringwald
17473a17974SMatthias Ringwald    # method argument declaration
17573a17974SMatthias Ringwald    args2 = []
17673a17974SMatthias Ringwald    for arg in args:
17773a17974SMatthias Ringwald        args2.append(arg[2])
17873a17974SMatthias Ringwald    args_string = ', '.join(args2)
17973a17974SMatthias Ringwald
18073a17974SMatthias Ringwald    # command size (opcode, len)
18173a17974SMatthias Ringwald    size_fixed = 3
18273a17974SMatthias Ringwald    size_var = ''
18373a17974SMatthias Ringwald    for arg in args:
18473a17974SMatthias Ringwald        size = arg[1]
18573a17974SMatthias Ringwald        if size > 0:
18673a17974SMatthias Ringwald            size_fixed += size
18773a17974SMatthias Ringwald        else:
18873a17974SMatthias Ringwald            size_var += ' + %s.length' % arg[2]
18973a17974SMatthias Ringwald    size_string = '%u%s' % (size_fixed, size_var)
19073a17974SMatthias Ringwald
19173a17974SMatthias Ringwald    store_params = ''
19273a17974SMatthias Ringwald
19373a17974SMatthias Ringwald    length_name = ''
19473a17974SMatthias Ringwald    for (param_type, arg_size, arg_name) in args:
19573a17974SMatthias Ringwald        if param_type in ['L', 'J']:
19673a17974SMatthias Ringwald            length_name = arg_name
19773a17974SMatthias Ringwald        if param_type == 'V':
19873a17974SMatthias Ringwald            store_params += ind + 'Util.storeBytes(command, offset, %s, %s);' % (arg_name, length_name) + '\n';
19973a17974SMatthias Ringwald            length_name = ''
20073a17974SMatthias Ringwald        else:
20173a17974SMatthias Ringwald            store_params += ind + (param_store[param_type] % arg_name) + '\n';
20273a17974SMatthias Ringwald            size = arg_size
20373a17974SMatthias Ringwald
20473a17974SMatthias Ringwald    fout.write( command_builder_command.format(name=name, args=args_string, ogf=ogf, ocf=ocf, args_builder=store_params))
20573a17974SMatthias Ringwald
20673a17974SMatthias Ringwalddef mark_define_as_used(term):
20773a17974SMatthias Ringwald    if term.startswith('0'):
20873a17974SMatthias Ringwald        return
20973a17974SMatthias Ringwald    defines_used.add(term)
21073a17974SMatthias Ringwald
21101aeeea2SMatthias Ringwalddef python_define_string(key):
21273a17974SMatthias Ringwald    global defines
21373a17974SMatthias Ringwald    if key in defines:
21401aeeea2SMatthias Ringwald        return '    %s = %s\n' % (key, defines[key])
21573a17974SMatthias Ringwald    else:
21601aeeea2SMatthias Ringwald        return '    # defines[%s] not set\n' % key
21773a17974SMatthias Ringwald
218b2929115SMatthias Ringwalddef python_defines_string(keys):
21901aeeea2SMatthias Ringwald    return '\n'.join( map(python_define_string, sorted(keys)))
22073a17974SMatthias Ringwald
22173a17974SMatthias Ringwalddef create_command_builder(commands):
22273a17974SMatthias Ringwald    global gen_path
22373a17974SMatthias Ringwald    parser.assert_dir(gen_path)
22473a17974SMatthias Ringwald
22573a17974SMatthias Ringwald    outfile = '%s/command_builder.py' % gen_path
22673a17974SMatthias Ringwald
22773a17974SMatthias Ringwald    with open(outfile, 'wt') as fout:
22873a17974SMatthias Ringwald
22973a17974SMatthias Ringwald        fout.write(command_builder_header)
23073a17974SMatthias Ringwald
23173a17974SMatthias Ringwald        for command in commands:
23273a17974SMatthias Ringwald                (command_name, ogf, ocf, format, params) = command
23373a17974SMatthias Ringwald                create_command_python(fout, command_name, ogf, ocf, format, params);
23473a17974SMatthias Ringwald                mark_define_as_used(ogf)
23573a17974SMatthias Ringwald                mark_define_as_used(ocf)
23673a17974SMatthias Ringwald
23701aeeea2SMatthias Ringwald        fout.write('\n    # defines used\n\n')
23801aeeea2SMatthias Ringwald        for key in sorted(defines_used):
23901aeeea2SMatthias Ringwald            fout.write(python_define_string(key))
24073a17974SMatthias Ringwald
241b2929115SMatthias Ringwalddef create_event(fout, event_name, format, args):
24273a17974SMatthias Ringwald    global gen_path
243760c6692SMatthias Ringwald    global event_template
24473a17974SMatthias Ringwald
24573a17974SMatthias Ringwald    param_read = {
246dbd33601SMatthias Ringwald     '1' : 'return self.payload[{offset}]',
247dbd33601SMatthias Ringwald     'J' : 'return self.payload[{offset}]',
248*b1f6df3bSMatthias Ringwald     '2' : 'return struct.unpack("<H", self.payload[{offset} : {offset}+2])',
249*b1f6df3bSMatthias Ringwald     'H' : 'return struct.unpack("<H", self.payload[{offset} : {offset}+2])',
250*b1f6df3bSMatthias Ringwald     'L' : 'return struct.unpack("<H", self.payload[{offset} : {offset}+2])',
251dbd33601SMatthias Ringwald     '3' : 'return btstack.btstack_types.unpack24(self.payload[{offset}:3])',
252*b1f6df3bSMatthias Ringwald     '4' : 'return struct.unpack("<I", self.payload[{offset} : {offset}+4])',
253dbd33601SMatthias Ringwald     'B' : 'return btstack.btstack_types.BD_ADDR(self.payload[{offset}:6])',
254dbd33601SMatthias Ringwald     'X' : 'return btstack.btstack_types.GATTService(self.payload[{offset}:20])',
255dbd33601SMatthias Ringwald     'Y' : 'return btstack.btstack_types.GATTCharacteristic(self.payload[{offset}:24])',
256dbd33601SMatthias Ringwald     'Z' : 'return btstack.btstack_types.GATTCharacteristicDescriptor(self.payload[{offset}:18])',
257760c6692SMatthias Ringwald     'T' : 'return self.payload[{offset}:].decode("utf-8")',
258760c6692SMatthias Ringwald     'N' : 'return self.payload[{offset}:{offset}+248].decode("utf-8")',
259dbd33601SMatthias Ringwald     # 'D' : 'Util.storeBytes(self.payload, %u, 8);',
260dbd33601SMatthias Ringwald     # 'Q' : 'Util.storeBytes(self.payload, %u, 32);',
26173a17974SMatthias Ringwald     # 'E' : 'Util.storeBytes(data, %u, 240);',
26273a17974SMatthias Ringwald     # 'P' : 'Util.storeBytes(data, %u, 16);',
26373a17974SMatthias Ringwald     # 'A' : 'Util.storeBytes(data, %u, 31);',
26473a17974SMatthias Ringwald     # 'S' : 'Util.storeBytes(data, %u);'
265760c6692SMatthias Ringwald     'R' : 'return self.payload[{offset}:]',
26673a17974SMatthias Ringwald     }
26773a17974SMatthias Ringwald
26873a17974SMatthias Ringwald    offset = 2
26973a17974SMatthias Ringwald    getters = ''
27073a17974SMatthias Ringwald    length_name = ''
27173a17974SMatthias Ringwald    for f, arg in zip(format, args):
27273a17974SMatthias Ringwald        # just remember name
27373a17974SMatthias Ringwald        if f in ['L','J']:
274dbd33601SMatthias Ringwald            length_name = arg.lower()
27573a17974SMatthias Ringwald        if f == 'R':
27673a17974SMatthias Ringwald            # remaining data
277760c6692SMatthias Ringwald            access = param_read[f].format(offset=offset)
27873a17974SMatthias Ringwald            size = 0
27973a17974SMatthias Ringwald        elif f == 'V':
280760c6692SMatthias Ringwald            access = event_getter_data.format(length_name=length_name, offset=offset)
28173a17974SMatthias Ringwald            size = 0
28273a17974SMatthias Ringwald        elif f in ['D', 'Q']:
28373a17974SMatthias Ringwald            size = size_for_type(f)
284760c6692SMatthias Ringwald            access = event_getter_data_fixed.format(size=size, offset=offset)
28573a17974SMatthias Ringwald        else:
286dbd33601SMatthias Ringwald            access = param_read[f].format(offset=offset)
28773a17974SMatthias Ringwald            size = size_for_type(f)
288760c6692SMatthias Ringwald        getters += event_getter.format(arg.lower(), access)
28973a17974SMatthias Ringwald        offset += size
29073a17974SMatthias Ringwald    to_string_args = ''
29173a17974SMatthias Ringwald    for arg in args:
292760c6692SMatthias Ringwald        to_string_args += '        repr += ", %s = "\n' % arg
293760c6692SMatthias Ringwald        to_string_args += '        repr += str(self.get_%s())\n' % arg.lower()
294760c6692SMatthias Ringwald    to_string_method = event_to_string.format(event_name, to_string_args)
295760c6692SMatthias Ringwald    fout.write(event_template.format(event_name, getters, to_string_method))
29673a17974SMatthias Ringwald
29773a17974SMatthias Ringwalddef event_supported(event_name):
29873a17974SMatthias Ringwald    parts = event_name.split('_')
29973a17974SMatthias Ringwald    return parts[0] in ['ATT', 'BTSTACK', 'DAEMON', 'L2CAP', 'RFCOMM', 'SDP', 'GATT', 'GAP', 'HCI', 'SM', 'BNEP']
30073a17974SMatthias Ringwald
30173a17974SMatthias Ringwalddef class_name_for_event(event_name):
30273a17974SMatthias Ringwald    return parser.camel_case(event_name.replace('SUBEVENT','EVENT'))
30373a17974SMatthias Ringwald
304b2929115SMatthias Ringwalddef create_events(fout, events):
30573a17974SMatthias Ringwald    global gen_path
30673a17974SMatthias Ringwald    gen_path_events = gen_path + '/event'
30773a17974SMatthias Ringwald    parser.assert_dir(gen_path_events)
30873a17974SMatthias Ringwald
30973a17974SMatthias Ringwald    for event_type, event_name, format, args in events:
31073a17974SMatthias Ringwald        if not event_supported(event_name):
31173a17974SMatthias Ringwald            continue
31273a17974SMatthias Ringwald        class_name = class_name_for_event(event_name)
313b2929115SMatthias Ringwald        create_event(fout, class_name, format, args)
31473a17974SMatthias Ringwald
31573a17974SMatthias Ringwald
31673a17974SMatthias Ringwalddef create_event_factory(events, subevents, defines):
31773a17974SMatthias Ringwald    global gen_path
318760c6692SMatthias Ringwald    global event_factory_event
319760c6692SMatthias Ringwald    global event_factory_template
32073a17974SMatthias Ringwald
321b2929115SMatthias Ringwald    outfile = '%s/event_factory.py' % gen_path
32273a17974SMatthias Ringwald
323760c6692SMatthias Ringwald
32473a17974SMatthias Ringwald    cases = ''
32573a17974SMatthias Ringwald    for event_type, event_name, format, args in events:
32673a17974SMatthias Ringwald        event_name = parser.camel_case(event_name)
327760c6692SMatthias Ringwald        cases += event_factory_event.format(event_type, event_name)
32873a17974SMatthias Ringwald    subcases = ''
32973a17974SMatthias Ringwald    for event_type, event_name, format, args in subevents:
33073a17974SMatthias Ringwald        if not event_supported(event_name):
33173a17974SMatthias Ringwald            continue
33273a17974SMatthias Ringwald        class_name = class_name_for_event(event_name)
333760c6692SMatthias Ringwald        subcases += event_factory_subevent.format(event_type, class_name)
33473a17974SMatthias Ringwald
33573a17974SMatthias Ringwald    with open(outfile, 'wt') as fout:
336760c6692SMatthias Ringwald        # header
337760c6692SMatthias Ringwald        fout.write(event_header)
338b2929115SMatthias Ringwald        # event classes
339b2929115SMatthias Ringwald        create_events(fout, events)
340b2929115SMatthias Ringwald        create_events(fout, subevents)
341b2929115SMatthias Ringwald        #
342760c6692SMatthias Ringwald        defines_text = ''
343760c6692SMatthias Ringwald        # python_defines_string(,defines)
344760c6692SMatthias Ringwald        fout.write(event_factory_template.format(defines_text, cases, subcases))
34573a17974SMatthias Ringwald
34673a17974SMatthias Ringwald# find root
34773a17974SMatthias Ringwaldbtstack_root = os.path.abspath(os.path.dirname(sys.argv[0]) + '/..')
34873a17974SMatthias Ringwaldgen_path = btstack_root + '/platform/daemon/binding/python/btstack/'
34973a17974SMatthias Ringwald
35073a17974SMatthias Ringwald
35173a17974SMatthias Ringwald# read defines from hci_cmds.h and hci.h
35273a17974SMatthias Ringwalddefines = parser.parse_defines()
35373a17974SMatthias Ringwald
35473a17974SMatthias Ringwald# parse commands
3559fb9416bSMatthias Ringwaldcommands = parser.parse_commands(camel_case=False)
35673a17974SMatthias Ringwald
35773a17974SMatthias Ringwald# parse bluetooth.h to get used events
358b2929115SMatthias Ringwald(events, le_events, event_types) = parser.parse_events()
35973a17974SMatthias Ringwald
36073a17974SMatthias Ringwald# create events, le meta events, event factory, and
361b2929115SMatthias Ringwaldcreate_event_factory(events, le_events, event_types)
36273a17974SMatthias Ringwaldcreate_command_builder(commands)
36373a17974SMatthias Ringwald
36473a17974SMatthias Ringwald# done
36573a17974SMatthias Ringwaldprint('Done!')
366