1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3 4# 5# Copyright (c) 2024 Huawei Device Co., Ltd. 6# Licensed under the Apache License, Version 2.0 (the "License"); 7# you may not use this file except in compliance with the License. 8# You may obtain a copy of the License at 9# 10# http://www.apache.org/licenses/LICENSE-2.0 11# 12# Unless required by applicable law or agreed to in writing, software 13# distributed under the License is distributed on an "AS IS" BASIS, 14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15# See the License for the specific language governing permissions and 16# limitations under the License. 17# 18 19import os 20import subprocess 21import time 22import re 23 24__all__ = ["get_time_stamp", "print_success", "print_failure", "compare_target_files", "exec_command", "file_exists", 25 "make_binary_file", "clean_binary_file", "get_all_idl_files", "get_idl", "get_subclasses", 26 "dump_ast_compare", "hdi_gen_fail_check_ignore_line"] 27 28def get_time_stamp(): 29 return int(round(time.time() * 1000)) 30 31 32def print_success(info): 33 print("\033[32m{}\033[0m".format(info)) 34 35 36def print_failure(info): 37 print("\033[31m{}\033[0m".format(info)) 38 39 40def is_subsequence(first_file, second_file): 41 first_info = first_file.read() 42 second_info = second_file.readline() 43 while second_info: 44 if first_info.find(second_info) == -1: 45 print("line\n", second_info, "is not in output file") 46 return False 47 second_info = second_file.readline() 48 return True 49 50 51def dump_ast_compare(line_lhd:str, line_rhd:str): 52 if line_lhd == line_rhd: 53 return True 54 if not line_lhd.startswith("AST") or not line_rhd.startswith("AST"): 55 return False 56 ast_templage = r"AST\[name:\s(.*)\sfile:\s(.*)\]" 57 obj_lhd = re.search(ast_templage, line_lhd) 58 obj_rhd = re.search(ast_templage, line_rhd) 59 if not obj_lhd or not obj_rhd: 60 return False 61 ast_name_lhd = obj_lhd.group(1) 62 ast_name_rhd = obj_rhd.group(1) 63 if ast_name_lhd.strip() != ast_name_rhd.strip(): 64 return False 65 ast_path_lhd = obj_lhd.group(2) 66 ast_path_rhd = obj_rhd.group(2) 67 lhd_index = ast_path_lhd.find("foo") 68 rhd_index = ast_path_rhd.find("foo") 69 if ast_path_lhd[lhd_index:].strip() != ast_path_rhd[rhd_index:].strip(): 70 return False 71 return True 72 73 74def content_compare(file1, file2, lhd, rhd, special_proc_func=None): 75 if len(lhd) != len(rhd): 76 print_failure(f"{file1} line num({len(lhd)}) != {file2} line num({len(rhd)}))") 77 return False 78 line_num = 0 79 for line1, line2 in zip(lhd, rhd): 80 line_num += 1 81 if ((special_proc_func is None and line1 != line2) or 82 (special_proc_func is not None and not special_proc_func(line1, line2))): 83 print_failure(f"{file1}:{line_num}:{line1}") 84 print_failure(f"{file2}:{line_num}:{line2}") 85 return False 86 return True 87 88 89def compare_file(first_file_path, second_file_path, special_proc_func=None): 90 with open(first_file_path, 'r') as first_file: 91 with open(second_file_path, 'r') as second_file: 92 return content_compare(first_file_path, 93 second_file_path, 94 first_file.readlines(), 95 second_file.readlines(), 96 special_proc_func) 97 98 99def check_c_cpp_file(file_list): 100 for filename in file_list: 101 if filename.endswith(".h") or filename.endswith(".c") or filename.endswith(".cpp"): 102 return True 103 return False 104 105 106def compare_target_files(first_file_path, second_file_path, special_proc_func=None): 107 first_files_list = get_all_files(first_file_path) 108 second_files_list = get_all_files(second_file_path) 109 110 first_files = set([file[len(first_file_path):] for file in first_files_list]) 111 if_c_cpp = check_c_cpp_file(first_files) 112 if if_c_cpp: 113 # 去除末尾.txt符号 114 second_files = set([file[len(second_file_path):-4] for file in second_files_list]) 115 else: 116 second_files = set([file[len(second_file_path):] for file in second_files_list]) 117 118 if len(first_files) != len(second_files): 119 print_failure(f"[ERROR] file num not compile({len(first_files)}, {len(second_files)})") 120 return False 121 122 common_files = first_files & second_files 123 124 if len(common_files) == 0: 125 print_failure("[ERROR] not compile target") 126 return False 127 128 if if_c_cpp: 129 check_file_name_format = "{}{}.txt" 130 else: 131 check_file_name_format = "{}{}" 132 133 for files in common_files: 134 if not compare_file("{}{}".format(first_file_path, files), 135 check_file_name_format.format(second_file_path, files), special_proc_func): 136 print("file ", "{}{}".format(first_file_path, files), "{}{}".format(second_file_path, files), \ 137 "is different") 138 return False 139 return True 140 141 142def exec_command(command): 143 return subprocess.getstatusoutput(command) 144 145 146def file_exists(file_path): 147 return os.path.isfile(file_path) 148 149 150def make_binary_file(file_path): 151 print("making idl-gen...") 152 return exec_command("make --directory={} --jobs=4".format(file_path)) 153 154 155def clean_binary_file(file_path): 156 return exec_command("make --directory={} clean".format(file_path)) 157 158 159def get_all_files(path): 160 file_list = [] 161 items = os.listdir(path) 162 for item in items: 163 item_path = os.path.join(path, item) 164 if not os.path.isdir(item_path): 165 file_list.append(item_path) 166 else: 167 file_list += get_all_files(item_path) 168 return file_list 169 170 171def get_all_idl_files(idl_path): 172 file_list = get_all_files(idl_path) 173 idl_file_list = [] 174 for file in file_list: 175 if os.path.splitext(file)[-1] == ".idl": 176 idl_file_list.append(file) 177 return idl_file_list 178 179 180def get_idl(): 181 current_path = os.path.dirname(os.path.abspath(__file__)) 182 relative_path = os.path.join(current_path, "..", "..", "..", "idl_tool_2", "idl-gen") 183 return os.path.realpath(relative_path) 184 185 186def get_subclasses(cls): 187 return cls.__subclasses__() 188 189 190def hdi_gen_fail_check_ignore_line(result: str, target: str): 191 fail_template = r"(.*): \[(\S+):\d+\] \[?(.*)error:(.*)" 192 result_lines = result.split("\n") 193 target_lines = target.split("\n") 194 if len(result_lines) != len(target_lines): 195 print_failure(f"[ERROR] result line(len(result_lines)) != target line(len(target_lines))") 196 return False 197 198 for result_line, target_line in zip(result_lines, target_lines): 199 lhd_obj = re.search(fail_template, result_line) 200 rhd_obj = re.search(fail_template, target_line) 201 if not lhd_obj and not rhd_obj: 202 if result_line == target_line: 203 continue 204 else: 205 print_failure(f"[ERROR] actual: {result_line}") 206 print_failure(f"[ERROR] expect: {target_line}") 207 return False 208 elif not lhd_obj or not rhd_obj: 209 print_failure(f"[ERROR] actual: {result_line}") 210 print_failure(f"[ERROR] expect: {target_line}") 211 return False 212 lhd_start_check_content = lhd_obj.group(1) 213 rhd_start_check_content = rhd_obj.group(1) 214 lhd_err_func_check_content = lhd_obj.group(2) 215 rhd_err_func_check_content = rhd_obj.group(2) 216 lhd_median_check_content = lhd_obj.group(3) 217 rhd_median_check_content = rhd_obj.group(3) 218 lhd_end_check_content = lhd_obj.group(4) 219 rhd_end_check_content = rhd_obj.group(4) 220 if lhd_start_check_content != rhd_start_check_content or \ 221 lhd_err_func_check_content != rhd_err_func_check_content or \ 222 lhd_median_check_content != rhd_median_check_content or \ 223 lhd_end_check_content != rhd_end_check_content: 224 print_failure(f"[ERROR] actual: {result_line}") 225 print_failure(f"[ERROR] expect: {target_line}") 226 return False 227 228 return True 229