xref: /btstack/tool/misc/update_btstack_config.py (revision dbf84c8a4e5f19f37bf9128db249cb40829b9966)
1#!/usr/bin/env python3
2import fileinput
3import os
4import re
5import sys
6
7btstack_root = os.path.abspath(os.path.dirname(sys.argv[0]) + '/../../')
8
9defines_to_add = []
10defines_to_remove = []
11
12# dictionary with existing lines as keys, and new text as value
13lines_to_replace = {}
14
15def get_line_ending(full_path):
16    with open(full_path, "r", newline='') as fin:
17        line = fin.readline()
18        if line.endswith('\r\n'):
19            return '\r\n'
20        if line.endswith('\r'):
21            return '\r'
22        return '\n'
23
24
25def configuration_from_block(block, line_ending):
26    global defines_to_add, defines_to_remove
27    configuration = ""
28
29    if len(block) == 0:
30        return ""
31
32    for item in defines_to_remove:
33        if item in block:
34            block.remove(item)
35
36    defines_processed = []
37    for item in temp_defines_to_add:
38        if item in block:
39            defines_processed.append(item)
40            continue
41
42        if len(block) > 0:
43            prefix = block[0].split("_")[0]
44            if item.startswith(prefix):
45                block.append(item)
46                defines_processed.append(item)
47
48    for item in defines_processed:
49        temp_defines_to_add.remove(item)
50
51    block.sort()
52    for item in block:
53        configuration += ("#define %s%s" % (item, line_ending))
54
55    configuration += ("%s" % (line_ending))
56    return configuration
57
58def read_and_update_configuration(full_path, line_ending):
59    global lines_to_replace, temp_defines_to_add
60
61    configuration = ""
62    block = []
63    temp_defines_to_add = defines_to_add.copy()
64
65    with open(full_path, "rt") as fin:
66        for unstripped_line in fin:
67            line = unstripped_line.strip()
68
69            if not line:
70                if len(block) == 0:
71                    # we have newline to deal with
72                    configuration += line_ending
73                else:
74                    configuration += configuration_from_block(block, line_ending)
75                block = []
76            else:
77                if line in lines_to_replace.keys():
78                    configuration += ("%s%s" % (lines_to_replace[line], line_ending))
79                    continue
80
81                parts = re.match("#define\\s*(.*)", line)
82                if parts:
83                    block.append(parts[1])
84                else:
85                    # if commented code follows directly block, process block, and start a new one
86                    configuration += configuration_from_block(block, line_ending)
87                    block = []
88                    configuration += ("%s%s" % (line, line_ending))
89
90    if len(temp_defines_to_add) > 0:
91        print("Cannot add defines: \n- " + "\n- ".join(temp_defines_to_add))
92        print("ABORT")
93        sys.exit(10)
94
95    # if end of file could not be detected, process last block
96    configuration += configuration_from_block(block, line_ending)
97    return configuration
98
99def write_configuration(full_path, config_file):
100    with open(full_path, "wb") as fout:
101        bytes = configuration.encode('utf-8')
102        fout.write(bytes)
103
104
105for root, dirs, files in os.walk(btstack_root, topdown=True):
106    for f in files:
107        if f.endswith("btstack_config.h"):
108            config_file = root + "/" + f
109            line_ending = get_line_ending(config_file)
110            configuration = read_and_update_configuration(config_file, line_ending)
111            write_configuration(config_file, configuration)
112