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