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 11import json 12import os 13import hashlib 14import platform 15import configparser 16import re 17from ast import literal_eval 18 19from hdf_tool_exception import HdfToolException 20from hdf_tool_settings import HdfToolSettings 21from command_line.hdf_command_error_code import CommandErrorCode 22 23 24class WordsConverter(object): 25 def __init__(self, words_str): 26 self.words_str = words_str 27 if len(self.words_str) == 0: 28 raise HdfToolException('empty words') 29 self.words_list = self.split() 30 self.upper = '_'.join([w.upper() for w in self.words_list]) 31 self.lower = '_'.join([w.lower() for w in self.words_list]) 32 self.upper_camel = ''.join([w.capitalize() for w in self.words_list]) 33 if len(self.upper_camel) == 1: 34 self.lower_camel = self.upper_camel[0].lower() 35 else: 36 self.lower_camel = '%s%s' % (self.upper_camel[0].lower(), 37 self.upper_camel[1:]) 38 39 def _capital_pos_generator(self): 40 count = len(self.words_str) 41 for i in range(count): 42 if self.words_str[i].isupper(): 43 yield i 44 yield count 45 46 def split(self): 47 words_list = [] 48 capital_split_words = [] 49 start = 0 50 for i in self._capital_pos_generator(): 51 end = i 52 if end != start: 53 capital_split_words.append(self.words_str[start:end]) 54 start = end 55 for word in capital_split_words: 56 words_list.extend([w for w in word.split('_') if w]) 57 return words_list 58 59 def upper_case(self): 60 return self.upper 61 62 def lower_case(self): 63 return self.lower 64 65 def upper_camel_case(self): 66 return self.upper_camel 67 68 def lower_camel_case(self): 69 return self.lower_camel 70 71 72class SectionRange(object): 73 def __init__(self, start_pos, end_pos): 74 self.start_pos = start_pos 75 self.end_pos = end_pos 76 77 78class SectionContent(object): 79 def __init__(self, begin_flag, content, end_flag): 80 self.begin_flag = begin_flag 81 self.content = content 82 self.end_flag = end_flag 83 84 def to_str(self): 85 return '%s%s%s' % (self.begin_flag, self.content, self.end_flag) 86 87 88def find_section(file_content, section_content): 89 if not file_content or not section_content: 90 return False 91 start_pos = file_content.find(section_content.begin_flag) 92 if start_pos == -1: 93 return False 94 end_pos = file_content.find(section_content.end_flag) 95 if end_pos == -1: 96 return False 97 return SectionRange(start_pos, end_pos + len(section_content.end_flag) - 1) 98 99 100def _write_one_section(file_obj, section_content): 101 if not file_obj or not section_content: 102 return 103 file_obj.write(section_content.begin_flag) 104 file_obj.write(section_content.content) 105 file_obj.write(section_content.end_flag) 106 107 108def add_before_and_save(file_content, file_path, pos_range, new_section): 109 if not file_content or not file_path or not pos_range or not new_section: 110 return 111 config_info = HdfToolSettings().get_file_config_info() 112 write_fd = os.open(file_path, config_info["flags"], config_info["modes"]) 113 with os.fdopen(write_fd, "w", newline='\n') as file_write: 114 file_write.write(file_content[:pos_range.start_pos]) 115 _write_one_section(file_write, new_section) 116 file_write.write(file_content[pos_range.start_pos:]) 117 118 119def add_after_and_save(file_content, file_path, pos_range, new_section): 120 if not file_content or not file_path or not pos_range or not new_section: 121 return 122 with open(file_path, 'w', newline='\n') as file_write: 123 file_write.write(file_content[:pos_range.end_pos + 1]) 124 _write_one_section(file_write, new_section) 125 if len(file_content) > pos_range.end_pos + 1: 126 file_write.write(file_content[pos_range.end_pos + 1:]) 127 128 129def append_and_save(file_content, file_path, new_section): 130 if not file_content or not file_path or not new_section: 131 return 132 with open(file_path, 'w', newline='\n') as file_write: 133 file_write.write(file_content) 134 _write_one_section(file_write, new_section) 135 136 137def delete_and_save(file_content, file_path, delete_range): 138 if not file_content or not file_path or not delete_range: 139 return 140 length = len(file_content) 141 with open(file_path, 'w', newline='\n') as file_write: 142 file_write.write(file_content[:delete_range.start_pos]) 143 if delete_range.end_pos + 1 < length: 144 file_write.write(file_content[delete_range.end_pos + 1:]) 145 146 147def replace_and_save(file_content, file_path, old_range, new_section): 148 if not file_content or not file_path or not old_range or not new_section: 149 return 150 with open(file_path, 'w', newline='\n') as file_write: 151 file_write.write(file_content[:old_range.start_pos]) 152 _write_one_section(file_write, new_section) 153 file_write.write(file_content[old_range.end_pos + 1:]) 154 155 156def get_id(part2): 157 full_name = part2 158 return hashlib.sha256(full_name.encode('utf8')).hexdigest()[:32] 159 160 161def create_dirs(dir_path): 162 if dir_path and not os.path.exists(dir_path): 163 try: 164 os.makedirs(dir_path) 165 except Exception: 166 raise HdfToolException('create dirs fail: %s' % dir_path) 167 168 169def read_file(file_path): 170 with open(file_path, encoding="utf-8") as file_read: 171 content = file_read.read() 172 return content 173 174 175def read_file_lines(file_path, code_type="utf-8"): 176 with open(file_path, encoding=code_type) as file_read: 177 lines = file_read.readlines() 178 return lines 179 180 181def read_file_binary(file_path): 182 with open(file_path, "rb") as file_binary_read: 183 temp_file_lines = file_binary_read.readlines() 184 file_lines = [] 185 for line in temp_file_lines: 186 if line.startswith(b"#") or not (line.strip()): 187 continue 188 else: 189 file_lines.append(line.decode("utf-8")) 190 return file_lines 191 192 193def write_file(file_path, content): 194 with open(file_path, 'w+', newline='\n') as file_write: 195 file_write.write(content) 196 197 198def write_file_lines(file_path, content, code_type="utf-8"): 199 config_info = HdfToolSettings().get_file_config_info() 200 write_fd = os.open(file_path, config_info["flags"], config_info["modes"]) 201 with os.fdopen(write_fd, "w", encoding=code_type) as file_write: 202 file_write.writelines(content) 203 204 205def get_framework_lite_dir(root): 206 return os.path.join(root, 'drivers', 'adapter', 'khdf', 'liteos') 207 208 209def get_vendor_root_dir(root): 210 return os.path.join(root, 'vendor') 211 212 213def get_vendor_dir(root, vendor): 214 return os.path.join(get_vendor_root_dir(root), vendor) 215 216 217def get_vendor_hdf_dir_framework(root): 218 relative_path = HdfToolSettings().get_drivers_path_framework() 219 return os.path.join(root, relative_path) 220 221 222def module_save_file_info(root): 223 adapter_framework = get_vendor_hdf_dir_framework(root=root) 224 if not os.path.exists(adapter_framework): 225 raise HdfToolException( 226 ' adapter model path "%s" not exist' % 227 adapter_framework, CommandErrorCode.TARGET_NOT_EXIST) 228 save_file_path = HdfToolSettings().get_module_save_path() 229 create_file_save_path = os.path.join(adapter_framework, save_file_path) 230 if not os.path.exists(create_file_save_path): 231 raise HdfToolException( 232 'create file config "%s" not exist' % 233 create_file_save_path, CommandErrorCode.TARGET_NOT_EXIST) 234 return create_file_save_path 235 236 237def get_vendor_hdf_dir_peripheral(root): 238 relative_path = HdfToolSettings().get_drivers_path_peripheral() 239 return os.path.join(root, relative_path) 240 241 242def get_vendor_hdf_dir_adapter(root, kernel='liteos'): 243 relative_path = HdfToolSettings().get_drivers_path_adapter() 244 return os.path.join(root, relative_path, kernel) 245 246 247def get_vendor_lite_mk_path(root): 248 return os.path.join(get_vendor_hdf_dir_adapter(root), 'hdf_lite.mk') 249 250 251def get_vendor_makefile_path(root, kernel): 252 return os.path.join(get_vendor_hdf_dir_adapter(root, kernel), 'Makefile') 253 254 255def get_dot_configs_path(root, vendor, board): 256 path = os.path.join(root, "vendor", vendor, board, 'kernel_configs') 257 return [os.path.join(path, i) for i in os.listdir(path)] 258 259 260def get_module_dir(root, module=""): 261 return os.path.join(get_vendor_hdf_dir_framework(root), 'model', module) 262 263 264def get_drv_root_dir(root, module): 265 return os.path.join(get_module_dir(root, module), 'driver') 266 267 268def get_drv_dir(root, module, driver): 269 return os.path.join(get_drv_root_dir(root, module), driver) 270 271 272def get_drv_src_dir(root, module): 273 return get_drv_root_dir(root, module) 274 275 276def get_drv_src_dir_peripheral(root, module): 277 return get_vendor_hdf_dir_peripheral(root) 278 279 280def get_drv_include_dir(root, module, driver): 281 return os.path.join(get_drv_dir(root, module, driver), 'include') 282 283 284def get_vendor_kconfig_path(root, kernel): 285 hdf_dir = get_vendor_hdf_dir_adapter(root, kernel) 286 return os.path.join(hdf_dir, 'Kconfig') 287 288 289def get_module_kconfig_path(root, module): 290 return os.path.join(get_drv_root_dir(root, module), 'Kconfig') 291 292 293def get_module_mk_path(root, module): 294 return os.path.join(get_drv_root_dir(root, module), 'Makefile') 295 296 297def get_liteos_a_dot_config_path(root): 298 return os.path.join(root, 'kernel', 'liteos_a', '.config') 299 300 301def get_resources_dir(): 302 cur_dir = os.path.realpath(os.path.dirname(__file__)) 303 return os.path.join(cur_dir, 'resources') 304 305 306def get_templates_dir(): 307 return os.path.join(get_resources_dir(), 'templates') 308 309 310def get_templates_lite_dir(): 311 return os.path.join(get_templates_dir(), 'lite') 312 313 314def get_template(template_name, type_='lite'): 315 templates_dir = os.path.join(get_templates_dir(), type_) 316 template = os.path.join(templates_dir, template_name) 317 with open(template) as file_read: 318 template_str = file_read.read() 319 return template_str 320 321 322def get_hdf_lite_settings_mk_path(root_dir): 323 return os.path.join(get_framework_lite_dir(root_dir), 324 'hdf_lite_settings.mk') 325 326 327def get_hdf_lite_mk_path(root_dir): 328 return os.path.join(get_framework_lite_dir(root_dir), 329 'hdf_lite.mk') 330 331 332def get_hdf_lite_kconfig_path(root_dir): 333 return os.path.join(get_framework_lite_dir(root_dir), 334 'Kconfig') 335 336 337def is_commented_line(line, comment_start): 338 if line.strip().startswith(comment_start): 339 return True 340 else: 341 return False 342 343 344def get_vendor_gn_path(root): 345 return os.path.join(get_vendor_hdf_dir_adapter(root), 'model', 'BUILD.gn') 346 347 348def get_template_file_path(root): 349 template_relative_path = HdfToolSettings().get_template_path() 350 relative_path2 = HdfToolSettings().get_drivers_path_framework() 351 return os.path.join(root, relative_path2, template_relative_path) 352 353 354def get_hcs_file_path(root, vendor, board): 355 l2_board_list = list(filter( 356 lambda x: x[0].isupper(), 357 HdfToolSettings().get_board_list())) 358 if board in l2_board_list: 359 return os.path.join(root, "vendor", vendor, board, 360 "hdf_config", "khdf", "device_info", 361 "device_info.hcs") 362 else: 363 return os.path.join(root, "vendor", vendor, board, 364 "hdf_config", "device_info", "device_info.hcs") 365 366 367def template_filename_filtrate(dir_path, kernal): 368 filename_list = [] 369 for filename in os.listdir(dir_path): 370 if filename.split("_")[0] == kernal.capitalize(): 371 filename_list.append(filename) 372 return filename_list 373 374 375def type_judge(file_path, root, model_file_path, k_filename, path_dict): 376 if isinstance(file_path, list): 377 for file_name in file_path: 378 if not os.path.exists(os.path.join(root, file_name)): 379 model_file_path[k_filename] = " " 380 else: 381 model_file_path[k_filename] = path_dict[k_filename] 382 else: 383 if not os.path.exists(os.path.join(root, file_path)): 384 model_file_path[k_filename] = " " 385 else: 386 model_file_path[k_filename] = path_dict[k_filename] 387 388 389def model_info(path_dict, root, model_file_path, key): 390 if isinstance(path_dict, dict): 391 for k_filename, file_path in path_dict.items(): 392 type_judge(file_path, root, model_file_path, k_filename, path_dict) 393 else: 394 hcs_file_path = os.path.join(root, path_dict) 395 if not os.path.exists(hcs_file_path): 396 model_file_path[key] = " " 397 else: 398 model_file_path[key] = path_dict 399 return model_file_path 400 401 402def get_create_model_info(root, create_data): 403 data = json.loads(create_data) 404 out_model_list = [] 405 if not data: 406 return [] 407 file_key_list = list(list(data.items())[0][-1].keys())[:-1] 408 for k, _ in data.items(): 409 model_file_path = {} 410 for key in file_key_list: 411 if key.split("_")[-1] == "path": 412 path_dict = data[k][key] 413 model_file_path = model_info( 414 path_dict, root, model_file_path, key) 415 out_model_list.append({k: model_file_path}) 416 return out_model_list 417 418 419def get_config_config_path(root, kernel): 420 return os.path.join(root, "kernel", kernel, "config", "linux-5.10") 421 422 423def judge_file_path_exists(temp_path): 424 if not os.path.exists(temp_path): 425 raise HdfToolException( 426 'path "%s" not exist' % temp_path, 427 CommandErrorCode.TARGET_NOT_EXIST) 428 429 430def write_config(root_path, config_file_json, config_name): 431 if platform.system() == "Windows": 432 config_file_replace = json.dumps(config_file_json, indent=4). \ 433 replace("{}\\\\".format(root_path.replace('\\', '\\\\')), "") 434 write_file(os.path.join('resources', config_name), 435 config_file_replace.replace('\\\\', '/')) 436 if platform.system() == "Linux": 437 config_file_replace = json.dumps(config_file_json, indent=4). \ 438 replace(root_path + '/', "") 439 write_file(os.path.join('resources', config_name), 440 config_file_replace) 441 442 443def ini_file_read_operation(section_name, node_name, path=""): 444 if path: 445 ini_config_path = path 446 else: 447 ini_config_path = os.path.join("resources", "config.ini") 448 config = configparser.ConfigParser() 449 config.read(ini_config_path) 450 if node_name: 451 model_child_dir_list = config.get(section=section_name, option=node_name) 452 return literal_eval(model_child_dir_list), config 453 else: 454 model_child_dir_list = config.items(section_name) 455 return model_child_dir_list, config 456 457 458def ini_file_write_operation(model, operation_object, model_child_dir_list): 459 json_format_list = json.dumps(model_child_dir_list) 460 operation_object.set(model, "file_dir", json_format_list) 461 ini_file_path = os.path.join("resources", "config.ini") 462 config_info = HdfToolSettings().get_file_config_info() 463 write_fd = os.open(ini_file_path, config_info["flags"], config_info["modes"]) 464 with os.fdopen(write_fd, "w") as write_ini_file: 465 operation_object.write(write_ini_file) 466 467 468def judge_enable_line(enable_line, device_base): 469 if isinstance(enable_line, bytes): 470 if enable_line.find((device_base + " ").encode("utf-8")) == -1: 471 return enable_line 472 else: 473 if enable_line.find(device_base + " ") == -1: 474 475 return enable_line 476 477 478class GnMkFileParse(object): 479 def __init__(self, file_path, temp_re): 480 self.file = file_path 481 self.file_info = self._file_read() 482 self.import_list = [] 483 self.module_switch = "" 484 self.module_name = "" 485 self.driver_dict = {} 486 self.driver_name = "" 487 self._start_index = "" 488 self._end_index = "" 489 self.driver_re = temp_re 490 491 def _file_read(self): 492 return read_file_binary(file_path=self.file) 493 494 def split_driver_start_to_end(self, flag_str): 495 count = 0 496 for index, line in enumerate(self.file_info): 497 re_result = re.search(self.driver_re, line.strip()) 498 if re_result and count == 0: 499 count += 1 500 self._start_index = index 501 self.driver_name = re_result.group("name") 502 continue 503 if line.strip() == flag_str and count > 0: 504 self._end_index = index 505 count -= 1 506 if count == 0: 507 self.driver_dict[self.driver_name] = \ 508 [self._start_index, self._end_index] 509 return self.driver_dict 510 511 def get_driver_config_str(self, driver_index): 512 return "".join(self.file_info[driver_index[0]: driver_index[-1] + 1]) 513 514 515class MakefileAndKconfigFileParse(object): 516 def __init__(self, file_path, flag_str, re_name): 517 self.file = file_path 518 self.file_info = self._file_read() 519 self.driver_re_name = re_name 520 self.driver_re_flg = flag_str 521 self.driver_dict = {} 522 523 def _file_read(self): 524 return read_file_binary(file_path=self.file) 525 526 def split_driver_start_to_end(self): 527 res_list = re.split(self.driver_re_flg, "".join(self.file_info)) 528 for res in res_list: 529 re_name = re.search(self.driver_re_name, res) 530 if res and re_name: 531 res_splicing = "".join([self.driver_re_flg, res]) 532 self.driver_dict[re_name.group("name")] = res_splicing 533 return self.driver_dict 534 535 def split_target_block(self, flag_re): 536 res_list = re.split(flag_re, "".join(self.file_info)) 537 flag_split_list = [] 538 for res in res_list: 539 if res.startswith("-"): 540 flag_split_list.append(res) 541 return flag_split_list 542 543 544def list_dict_tool(couple_list): 545 temp_dict = {} 546 for info in couple_list: 547 temp_dict[info[0]] = info[-1] 548 return temp_dict 549