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 os 12import re 13from string import Template 14 15from hdf_tool_exception import HdfToolException 16from command_line.hdf_command_error_code import CommandErrorCode 17import hdf_utils 18 19 20class HdfManagerConfigFile(object): 21 def __init__(self, file_path): 22 self.file_path = file_path 23 self.file_dir = os.path.dirname(self.file_path) 24 self.host_pattern = r'%s\s*::\s*host\s*{' 25 self.hdf_manager_pattern = r'device_info\s*{' 26 self.contents = '' 27 self._read_contents() 28 29 def _read_contents(self): 30 if os.path.exists(self.file_path): 31 self.contents = hdf_utils.read_file(self.file_path) 32 else: 33 self.contents = '' 34 35 def check_and_create(self): 36 if self.contents: 37 return 38 template_str = \ 39 hdf_utils.get_template('hdf_driver_manager_config.template') 40 self.contents = Template(template_str).safe_substitute({}) 41 if not os.path.exists(self.file_dir): 42 os.makedirs(self.file_dir) 43 hdf_utils.write_file(self.file_path, self.contents) 44 45 def _find_range(self, pattern): 46 match_obj = re.search(pattern, self.contents) 47 if not match_obj: 48 return False 49 start = match_obj.start() 50 if start == -1: 51 return False 52 braces = [] 53 start += len(match_obj.group(0)) - 1 54 end = start 55 for i in range(start, len(self.contents)): 56 if '{' == self.contents[i]: 57 braces.append('{') 58 elif '}' == self.contents[i]: 59 count = len(braces) 60 if count == 0: 61 return False 62 if count == 1: 63 end = i 64 break 65 braces.pop() 66 if end != start: 67 while end > start + 1: 68 end -= 1 69 if self.contents[end] not in [' ', '\t']: 70 break 71 return hdf_utils.SectionRange(start, end) 72 return False 73 74 @staticmethod 75 def _begin_end(module, driver): 76 dev_id = hdf_utils.get_id(module, driver) 77 device_begin = '\n/* <begin %s */\n' % dev_id 78 device_end = '\n/* %s end> */\n' % dev_id 79 return device_begin, device_end 80 81 def _create_device(self, module, driver): 82 drv_converter = hdf_utils.WordsConverter(driver) 83 data_model = { 84 'driver_lower_case': drv_converter.lower_case(), 85 'driver_lower_camel_case': drv_converter.lower_camel_case() 86 } 87 template_str = \ 88 hdf_utils.get_template('hdf_driver_manager_config_device.template') 89 contents = Template(template_str).safe_substitute(data_model) 90 begin, end = self._begin_end(module, driver) 91 return hdf_utils.SectionContent(begin, contents, end) 92 93 def _get_host_range(self): 94 pattern = self.host_pattern % 'common' 95 host_range = self._find_range(pattern) 96 if not host_range: 97 self.add_host('common') 98 self._read_contents() 99 host_range = self._find_range(pattern) 100 return host_range 101 102 def add_device(self, module, driver): 103 device_config = self._create_device(module, driver) 104 old_device_range = hdf_utils.find_section(self.contents, device_config) 105 if old_device_range: 106 hdf_utils.replace_and_save(self.contents, self.file_path, 107 old_device_range, device_config) 108 return 109 host_range = self._get_host_range() 110 last_brace_range = hdf_utils.SectionRange(host_range.end_pos, 111 host_range.end_pos) 112 hdf_utils.add_after_and_save(self.contents, self.file_path, 113 last_brace_range, device_config) 114 115 def delete_device(self, module, driver): 116 begin, end = self._begin_end(module, driver) 117 empty_device = hdf_utils.SectionContent(begin, '', end) 118 old_range = hdf_utils.find_section(self.contents, empty_device) 119 if old_range: 120 hdf_utils.delete_and_save(self.contents, self.file_path, old_range) 121 122 def _create_host(self, module): 123 template_str = \ 124 hdf_utils.get_template('hdf_driver_manager_config_host.template') 125 mod_converter = hdf_utils.WordsConverter(module) 126 data_model = { 127 'module_lower_case': mod_converter.lower_case() 128 } 129 host_content = Template(template_str).safe_substitute(data_model) 130 begin, end = self._begin_end(module, module) 131 return hdf_utils.SectionContent(begin, host_content, end) 132 133 def add_host(self, module): 134 manager_range = self._find_range(self.hdf_manager_pattern) 135 if not manager_range: 136 raise HdfToolException('file: %s format wrong, no hdf_manager node' 137 ' found' % self.file_path, 138 CommandErrorCode.FILE_FORMAT_WRONG) 139 host_section = self._create_host(module) 140 last_brace = hdf_utils.SectionRange(manager_range.end_pos, 141 manager_range.end_pos) 142 hdf_utils.add_after_and_save(self.contents, self.file_path, 143 last_brace, host_section) 144 145 def delete_host(self, module): 146 begin, end = self._begin_end(module, module) 147 empty_section = hdf_utils.SectionContent(begin, "", end) 148 host_range = hdf_utils.find_section(self.contents, empty_section) 149 if not host_range: 150 return 151 hdf_utils.delete_and_save(self.contents, self.file_path, host_range) 152