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