1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 
4 # Copyright (c) 2020-2021 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 
11 import os
12 import re
13 from string import Template
14 
15 import hdf_utils
16 from hdf_tool_exception import HdfToolException
17 from hdf_tool_settings import HdfToolSettings
18 from .hdf_liteos_scann import HdfLiteScan
19 from .hdf_command_error_code import CommandErrorCode
20 
21 
22 class EnableOperation(object):
23     def __init__(self, root, vendor, board, model):
24         self.root = root
25         self.vendor = vendor
26         self.board = board
27         self.model = model
28         if self.board.endswith("linux") or self.board.endswith("Hi3516DV300"):
29             pass
30         else:
31             temp_liteos_model_name = HdfLiteScan(
32                 self.root, self.vendor, self.board).scan_build()
33             self.liteos_model_name = list(map(lambda x: x.strip(",").strip('"'),
34                                               temp_liteos_model_name))
35 
36         self.makefile_path = hdf_utils.get_vendor_makefile_path(
37             root, kernel="linux")
38         if not os.path.exists(self.makefile_path):
39             raise HdfToolException(
40                 'Makefile: %s not exist' % self.makefile_path,
41                 CommandErrorCode.TARGET_NOT_EXIST)
42 
43         self.contents_makefile = hdf_utils.read_file_lines(self.makefile_path)
44         self.re_temp2 = r'model/[a-z 0-9 _ ]+'
45         self.re_temp = r"^group"
46 
47     def scan_makefile(self):
48         model_list = []
49         for i in self.contents_makefile:
50             result = re.search(self.re_temp2, i)
51             if result:
52                 model_name = result.group().split('/')[-1]
53                 if model_name not in model_list:
54                     model_list.append(model_name)
55         return list(set(model_list))
56 
57     def scan_build(self):
58         start_index = 0
59         end_index = 0
60         state = 0
61         for index, line in enumerate(self.contents_build):
62             if re.compile(self.re_temp).match(line):
63                 start_index = index
64                 state += 1
65             elif line.strip() == "{" and start_index > 0:
66                 state += 1
67             elif line.strip() == "}" and start_index > 0:
68                 state -= 1
69                 if state == 0:
70                     end_index = index + 1
71 
72         model_list = []
73         for i in self.contents[start_index: end_index]:
74             model_name = re.compile(self.re_temp2).match(i.strip())
75             if model_name:
76                 model_list.append(model_name.group().split('/')[-1])
77         return list(set(model_list))
78 
79     def disable_model_liteos(self):
80         dot_file_list = hdf_utils.get_dot_configs_path(
81             self.root, self.vendor, self.board)
82         old_template_string = \
83             "LOSCFG_DRIVERS_HDF_${module_upper_case}=y"
84         new_template_string = \
85             "LOSCFG_DRIVERS_HDF_${module_upper_case} is not set\n"
86         return self.enable_disable_same_code(
87             new_template_string, old_template_string, dot_file_list)
88 
89     def enable_model_liteos(self):
90         dot_file_list = hdf_utils.get_dot_configs_path(
91             self.root, self.vendor, self.board)
92         new_template_string = \
93             "LOSCFG_DRIVERS_HDF_${module_upper_case}=y\n"
94         old_template_string = \
95             "LOSCFG_DRIVERS_HDF_${module_upper_case} is not set"
96         return self.enable_disable_same_code(
97             new_template_string, old_template_string, dot_file_list)
98 
99     def enable_disable_same_code(self, new_template_string,
100                                  old_template_string, dot_file_list):
101         new_demo_config = Template(new_template_string).substitute(
102             {"module_upper_case": self.model.upper()})
103         old_demo_config = Template(old_template_string).substitute(
104             {"module_upper_case": self.model.upper()})
105 
106         if self.model not in self.liteos_model_name:
107             return False
108         for dot_file in dot_file_list:
109             file_lines = hdf_utils.read_file_lines(dot_file)
110             for index, line in enumerate(file_lines):
111                 if old_demo_config == line.strip():
112                     file_lines[index] = new_demo_config
113             hdf_utils.write_file_lines(dot_file, file_lines)
114         return True
115 
116     def operation_enable(self):
117         if self.board.endswith("Hi3516DV300"):
118             try:
119                 if self.enable_model_linux():
120                     return "success(linux) enable %s" % self.model
121                 else:
122                     return "%s model_name is not linux_l2 type" % self.model
123             except Exception:
124                 raise "failure(linux) enable %s" % self.model
125             finally:
126                 pass
127 
128         elif self.board.endswith("hispark_taurus_linux"):
129             try:
130                 if self.enable_model_linux():
131                     return "success(linux) enable %s" % self.model
132                 else:
133                     return "%s model_name is not linux type" % self.model
134             except Exception:
135                 raise "failure(linux) enable %s" % self.model
136             finally:
137                 pass
138 
139         elif self.board.endswith("hispark_taurus"):
140             try:
141                 if self.enable_model_liteos():
142                     return "success(liteos) enable %s" % self.model
143                 else:
144                     return "%s model_name is not liteos type" % self.model
145             except Exception:
146                 raise "failure(liteos) enable %s" % self.model
147             finally:
148                 pass
149 
150         else:
151             return "this board name : (%s) is not support" % self.board
152 
153     def operation_disable(self):
154         if self.board.endswith("Hi3516DV300"):
155             try:
156                 if self.disable_model_linux():
157                     return "success(linux) disable %s" % self.model
158                 else:
159                     return "%s model_name is not linux_l2 type" % self.model
160             except Exception:
161                 raise "failure(linux) disable %s" % self.model
162             finally:
163                 pass
164 
165         elif self.board.endswith("hispark_taurus_linux"):
166             try:
167                 if self.disable_model_linux():
168                     return "success(linux) disable %s" % self.model
169                 else:
170                     return "%s model_name is not linux type" % self.model
171             except Exception:
172                 raise "failure(linux) disable %s" % self.model
173             finally:
174                 pass
175 
176         elif self.board.endswith("hispark_taurus"):
177             try:
178                 if self.disable_model_liteos():
179                     return "success(liteos) disable %s" % self.model
180                 else:
181                     return "%s model_name is not liteos type" % self.model
182             except Exception:
183                 raise "failure(liteos) disable %s" % self.model
184             finally:
185                 pass
186 
187         else:
188             return "this board name : (%s) is not support " % self.board
189 
190     def get_config_config(self, kernel):
191         return os.path.join(self.root, "kernel", kernel, "config")
192 
193     def get_config_patch(self, kernel):
194         return os.path.join(self.root, "kernel", kernel, "patches")
195 
196     def _get_file_patch(self, patch, endswitch, split_sign):
197         file_path = []
198         for roots, dirs, files in os.walk(patch):
199             if endswitch == "defconfig":
200                 files_list = list(filter(
201                     lambda x: x.split(split_sign)[-1] == endswitch, files))
202             else:
203                 files_list = list(filter(lambda x: x == endswitch, files))
204             for file_name in files_list:
205                 file_path.append(os.path.join(roots, file_name))
206         return file_path
207 
208     def _get_config_linux(self):
209         config_path = self.get_config_config(kernel="linux")
210         config_path_list = self._get_file_patch(
211             patch=config_path, endswitch="defconfig", split_sign="_")
212 
213         patch_path = self.get_config_patch(kernel="linux")
214         patch_path_list = self._get_file_patch(
215             patch=patch_path, endswitch="hi3516dv300.patch", split_sign=".")
216         config_path_list.extend(patch_path_list)
217 
218         return config_path_list
219 
220     def _replace_operation(self, new_string, old_string, file_path):
221         new_demo_config = Template(new_string).substitute(
222             {"module_upper_case": self.model.upper()})
223         old_demo_config = Template(old_string).substitute(
224             {"module_upper_case": self.model.upper()})
225 
226         with open(file_path, 'rb') as f_read:
227             file_lines = f_read.readlines()
228         for index, line in enumerate(file_lines):
229             if old_demo_config.encode('utf-8') == line.strip():
230                 file_lines[index] = new_demo_config.encode('utf-8')
231         config_info = HdfToolSettings().get_file_config_info()
232         write_fd = os.open(file_path, config_info["flags"], config_info["modes"])
233         with os.fdopen(write_fd, "wb") as f_write:
234             f_write.writelines(file_lines)
235         return True
236 
237     def disable_model_linux(self):
238         if self.model not in self.scan_makefile():
239             return False
240         file_path_list = self._get_config_linux()
241         for file_path in file_path_list:
242             if file_path.split("_")[-1] == "defconfig":
243                 old_template_string = \
244                     "CONFIG_DRIVERS_HDF_${module_upper_case}=y"
245                 new_template_string = \
246                     "CONFIG_DRIVERS_HDF_${module_upper_case} is not set\n"
247             else:
248                 old_template_string = \
249                     "+CONFIG_DRIVERS_HDF_${module_upper_case}=y"
250                 new_template_string = \
251                     "+CONFIG_DRIVERS_HDF_${module_upper_case} is not set\n"
252             self._replace_operation(new_string=new_template_string,
253                                     old_string=old_template_string,
254                                     file_path=file_path)
255         return True
256 
257     def enable_model_linux(self):
258         if self.model not in self.scan_makefile():
259             return False
260         file_path_list = self._get_config_linux()
261         for file_path in file_path_list:
262             if file_path.split("_")[-1] == "defconfig":
263                 new_template_string \
264                     = "CONFIG_DRIVERS_HDF_${module_upper_case}=y\n"
265                 old_template_string \
266                     = "CONFIG_DRIVERS_HDF_${module_upper_case} is not set"
267             else:
268                 new_template_string \
269                     = "+CONFIG_DRIVERS_HDF_${module_upper_case}=y\n"
270                 old_template_string = \
271                     "+CONFIG_DRIVERS_HDF_${module_upper_case} is not set"
272             self._replace_operation(new_string=new_template_string,
273                                     old_string=old_template_string,
274                                     file_path=file_path)
275         return True
276