1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4# Copyright (c) 2022 Huawei Device Co., Ltd.
5#
6# HDF is dual licensed: you can use it either under the terms of
7# the GPL, or the BSD license, at your option.
8# See the LICENSE file in the root of this repository for complete details.
9
10
11import re
12import os
13from string import Template
14
15import hdf_utils
16
17
18def find_build_file_end_index(date_lines, model_name, pre_str='FRAMEWORKS'):
19    state = False
20    end_index = 0
21    frameworks_model_name = "%s_%s_ROOT" % (pre_str, model_name.upper())
22    frameworks_model_value = ''
23    for index, line in enumerate(date_lines):
24        if line.startswith("#"):
25            continue
26        elif line.find("hdf_driver") != -1:
27            state = True
28            continue
29        elif line.startswith("}") and state:
30            end_index = index
31            state = False
32        elif line.strip().startswith(frameworks_model_name):
33            frameworks_model_value = line.split("=")[-1].strip()
34        else:
35            continue
36    result_tuple = (end_index, frameworks_model_name, frameworks_model_value)
37    return result_tuple
38
39
40def audio_build_file_operation(path, args_tuple):
41    source_path, head_path, module, driver, root, devices, kernel = args_tuple
42    build_gn_path = path
43    date_lines = hdf_utils.read_file_lines(build_gn_path)
44    result_tuple = find_build_file_end_index(date_lines, model_name=module)
45    judge_result = judge_driver_config_exists(date_lines, driver_name=driver)
46    if judge_result:
47        return
48    end_index, frameworks_name, frameworks_value = result_tuple
49
50    first_line = "\n  if (defined(LOSCFG_DRIVERS_HDF_${model_name_upper}_${driver_name_upper})) {\n"
51    third_line = '    include_dirs += [ "$${file_parent_path}/${head_path}" ]\n'
52    four_line = "  }\n"
53    if len(source_path) > 1:
54        sources_line = []
55        multi_resource = "    sources += [ \n"
56        multi_end = "    ]\n"
57        temp_line = r'      "$${file_parent_path}/${source_path}",'
58        for source in source_path:
59            temp_handle = Template(temp_line.replace("\"$", "temp_flag"))
60            parent_temp_dict = analyze_parent_path(
61                date_lines, source, "", devices, root)
62            sources_line.append(temp_handle.substitute(
63                parent_temp_dict).replace("temp_flag", "\"$") + "\n")
64        sources_str = ''.join(sources_line)
65        build_resource = ''.join([multi_resource, sources_str, multi_end])
66    else:
67        build_resource = '    sources += [ "$${file_parent_path}/${source_path}" ]\n'
68        for source in source_path:
69            temp_handle = Template(build_resource.replace("\"$", "temp_flag"))
70            temp_dict = analyze_parent_path(
71                date_lines, source, "", devices, root)
72            build_resource = temp_handle.substitute(
73                temp_dict).replace("temp_flag", "\"$")
74    build_add_template = ''.join([first_line, build_resource, third_line, four_line])
75    build_replace_dict = analyze_parent_path(
76        date_lines, "", head_path[0], devices, root, kernel_type=kernel)
77    temp_handle = Template(build_add_template.replace("\"$", "temp_flag"))
78    model_dict = {
79        'model_name_upper': module.upper(),
80        'driver_name_upper': driver.upper(),
81    }
82    build_replace_dict.update(model_dict)
83    new_line = temp_handle.substitute(build_replace_dict).replace("temp_flag", "\"$")
84    date_lines = date_lines[:end_index] + [new_line] + date_lines[end_index:]
85    hdf_utils.write_file_lines(build_gn_path, date_lines)
86
87
88def judge_driver_config_exists(date_lines, driver_name):
89    for _, line in enumerate(date_lines):
90        if line.startswith("#"):
91            continue
92        elif line.find(driver_name) != -1:
93            return True
94    return False
95
96
97def analyze_parent_path(date, source_path, head_path,
98                        devices, root, kernel_type="linux"):
99    str_re = "^[A-Z _ 0-9]+="
100    macro_definition_dict = {}
101    for index, i in enumerate(date):
102        re_result = re.search(str_re, i)
103        if not re_result:
104            continue
105        str_split_list = i.strip().split(" = ")
106        if len(str_split_list) == 1 and str_split_list[0].endswith("="):
107            temp_name = str_split_list[0].split(" ")[0].strip("=")
108            macro_definition_dict[temp_name] = date[index + 1].strip()
109        else:
110            macro_definition_dict[str_split_list[0]] = str_split_list[-1]
111    date_replace = {
112        "file_parent_path": "",
113        "source_path": "",
114        "head_path": "",
115    }
116    if source_path:
117        parent_path_temp = source_path.split(devices)[0].strip(
118            root).replace("\\", "/").strip("/")
119        parent_path = '/'.join(parent_path_temp.split('/')[:3])
120    else:
121        parent_path_temp = head_path.split(devices)[0].strip(
122            root).replace("\\", "/").strip("/")
123        parent_path = '/'.join(parent_path_temp.split('/')[:3])
124    if kernel_type == "linux":
125        for k_name, values in macro_definition_dict.items():
126            if values.find(parent_path) == -1:
127                continue
128            if values.startswith("drivers/hdf/framework") and head_path.strip():
129                date_replace['file_parent_path'] = k_name
130            elif source_path.strip() and not values.startswith("drivers/hdf/framework"):
131                date_replace['file_parent_path'] = k_name
132    else:
133        for k_name, values in macro_definition_dict.items():
134            if values.find(parent_path) != -1:
135                date_replace['file_parent_path'] = k_name
136    relatively_path_dict, _ = hdf_utils.ini_file_read_operation(
137        section_name="audio", node_name='driver_path')
138    audio_board_name = parent_path_temp.split('/')[3]
139    if audio_board_name.startswith("rk3568"):
140        relatively_path = relatively_path_dict["rk3568"]
141    else:
142        relatively_path = relatively_path_dict["hi3516"]
143    res_date_replace = source_hand_file_path(
144        relatively_path, source_path, head_path, date_replace)
145    return res_date_replace
146
147
148def source_hand_file_path(relatively_path, source_path, head_path, date_replace):
149    if source_path:
150        file_source_path_full = source_path.replace("\\", "/")
151        date_replace['source_path'] = file_source_path_full.split(
152            relatively_path)[-1].strip('/')
153    if head_path:
154        file_head_path_full = head_path.replace("\\", "/")
155        date_replace['head_path'] = '/'.join(file_head_path_full.split(
156            relatively_path)[-1].split('/')[:-1]).strip('/')
157    return date_replace
158
159
160def build_file_operation(path, driver_file_path, head_path, module, driver):
161    build_gn_path = path
162    date_lines = hdf_utils.read_file_lines(build_gn_path)
163    source_file_path = driver_file_path.replace('\\', '/')
164    judge_result = judge_driver_config_exists(date_lines, driver_name=driver)
165    if judge_result:
166        return
167    if driver_file_path.find("FRAMEWORK".lower()) != -1:
168        result_tuple = find_build_file_end_index(date_lines, model_name=module)
169        end_index, frameworks_name, frameworks_value = result_tuple
170        new_line = build_file_operation_comm(
171            frameworks_value, source_file_path, module, driver, head_path)
172    else:
173        result_tuple = find_build_file_end_index(
174            date_lines, model_name=module, pre_str="PERIPHERAL")
175        end_index, frameworks_name, frameworks_value = result_tuple
176        build_add_template = template_str_splice(type_name=" ")
177        include_model_info = frameworks_value.split("/")[-1].strip("\"")
178        build_gn_path_config = source_file_path.split(include_model_info + "/", 1)
179        temp_handle = Template(
180            build_add_template.replace("$PERIPHERAL", "PERIPHERAL"))
181
182        temp_replace = {
183            'model_name_upper': module.upper(),
184            'driver_name_upper': driver.upper(),
185            'source_file_path': build_gn_path_config[-1],
186            'head_file_path': '/'.join(list(
187                filter(lambda x: x,
188                       head_path.split(include_model_info, 1)[-1].
189                       strip(os.path.sep).split(os.path.sep)))[:-1])
190        }
191        new_line = temp_handle.substitute(
192            temp_replace).replace("PERIPHERAL", "$PERIPHERAL")
193    date_lines = date_lines[:end_index] + [new_line] + date_lines[end_index:]
194    hdf_utils.write_file_lines(build_gn_path, date_lines)
195
196
197def template_str_splice(type_name):
198    if type_name == "framework":
199        first_line = "\n  if (defined(LOSCFG_DRIVERS_HDF" \
200                     "_${model_name_upper}_${driver_name_upper})) {\n"
201        include_line = '    include_dirs += [ "$FRAMEWORKS' \
202                       '_${model_name_upper}_ROOT/${head_file_path}" ]\n'
203        second_line = '    sources += [ "$FRAMEWORKS' \
204                      '_${model_name_upper}_ROOT/${source_file_path}" ]\n'
205        third_line = "  }\n"
206        build_add_template = first_line + include_line + second_line + third_line
207    else:
208        first_line = "\n  if (defined(LOSCFG_DRIVERS_" \
209                     "HDF_${model_name_upper}_${driver_name_upper})) {\n"
210        include_line = '    include_dirs += [ "$PERIPHERAL' \
211                       '_${model_name_upper}_ROOT/${head_file_path}" ]\n'
212        second_line = '    sources += [ "$PERIPHERAL' \
213                      '_${model_name_upper}_ROOT/${source_file_path}" ]\n'
214        third_line = "  }\n"
215        build_add_template = first_line + include_line + second_line + third_line
216    return build_add_template
217
218
219def input_build_file_operation(path, driver_file_path, head_path, module, driver):
220    build_gn_path = path
221    date_lines = hdf_utils.read_file_lines(build_gn_path)
222    source_file_path = driver_file_path.replace('\\', '/')
223    judge_result = judge_driver_config_exists(date_lines, driver_name=driver)
224    if judge_result:
225        return
226    result_tuple = find_build_file_end_index(date_lines, model_name=module)
227    end_index, frameworks_name, frameworks_value = result_tuple
228    re_str_include = "include_dirs ="
229    new_line = build_file_operation_comm(
230        frameworks_value, source_file_path, module, driver, head_path)
231    if re.search(re_str_include, "".join(date_lines[:end_index])) is None:
232        include_str = "  include_dirs = []\n"
233        date_lines = date_lines[:end_index] + [include_str] + [new_line] + date_lines[end_index:]
234    else:
235        date_lines = date_lines[:end_index] + [new_line] + date_lines[end_index:]
236    hdf_utils.write_file_lines(build_gn_path, date_lines)
237
238
239def build_file_operation_comm(
240        frameworks_value, source_file_path, module, driver, head_path):
241    build_add_template = template_str_splice(type_name="framework")
242    include_model_info = frameworks_value.split("model")[-1].strip('"') + "/"
243    build_gn_path_config = source_file_path.split(include_model_info)
244    temp_handle = Template(
245        build_add_template.replace("$FRAMEWORKS", "FRAMEWORKS"))
246    temp_replace = {
247        'model_name_upper': module.upper(),
248        'driver_name_upper': driver.upper(),
249        'source_file_path': build_gn_path_config[-1],
250        'head_file_path': '/'.join(
251            list(filter(lambda x: x, head_path.split("model")[-1].strip(
252                os.path.sep).split(os.path.sep)[2:-1])))
253    }
254    new_line = temp_handle.substitute(
255        temp_replace).replace("FRAMEWORKS", "$FRAMEWORKS")
256    return new_line
257