• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# Copyright (c) 2023 Huawei Device Co., Ltd.
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16import re
17import os
18import subprocess
19import openpyxl as op
20from typedef.check.check import ApiResultInfo, ErrorType, LogType, ErrorLevel
21
22
23def check_syntax(file_path):
24    cmd_list = ['clang']
25    if os.path.exists(r'.\sysroot'):
26        args = ['-I{}'.format(dir_path) for dir_path, _, _ in os.walk(r'.\sysroot')]
27        cmd_list.extend(args)
28    cmd_list.append('-std=c99')
29    result_list = []
30    command = cmd_list + [file_path]
31    run_result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
32    result_list.extend(processing_data(run_result, file_path))
33    return result_list
34
35
36def get_all_dependent_file_path(dependent_file_path):
37    link_path = []
38    for dir_path, _, _ in os.walk(dependent_file_path):
39        if 'build-tools' not in dir_path:
40            link_path.append(dir_path)
41
42    return link_path
43
44
45def process_result_data(result_info_list):
46    syntax_info_data = []
47    for syntax_info in result_info_list:
48        info_data = [
49            syntax_info.api_name,
50            syntax_info.file_name,
51            syntax_info.error_info,
52            syntax_info.location_line,
53            syntax_info.error_content,
54        ]
55        syntax_info_data.append(info_data)
56
57    return syntax_info_data
58
59
60def general_syntax_excel(syntax_data_list, output_path):
61    data = process_result_data(syntax_data_list)
62    wb = op.Workbook()
63    ws = wb['Sheet']
64    ws.title = '语法错误信息'
65    ws.append(['当前文件路径', '错误文件路径', '错误信息', '行号', '代码片段'])
66    for title in data:
67        d = title[0], title[1], title[2], title[3], title[4]
68        ws.append(d)
69
70    wb.save(output_path)
71
72
73def get_dir_file_path(file_path):
74    file_path_total = []
75    for dir_path, _, filenames in os.walk(file_path):
76        for file_name in filenames:
77            if 'build-tools' not in dir_path and 'sysroot_myself' not in dir_path and file_name.endswith('.h'):
78                file_path_total.append(os.path.join(dir_path, file_name))
79
80    return file_path_total
81
82
83def get_all_object_file_path(file_path):
84    file_path_total = []
85    if os.path.isdir(file_path):
86        file_path_total = get_dir_file_path(file_path)
87    else:
88        if file_path.endswith('.h'):
89            file_path_total.append(file_path)
90
91    return file_path_total
92
93
94def check_syntax_entrance(file_path, dependent_file_path, output_path):
95    cmd_list = ['clang']
96    link_path = get_all_dependent_file_path(dependent_file_path)
97    args = ['-I{}'.format(path) for path in link_path]
98    cmd_list.extend(args)
99    cmd_list.append('-std=c99')
100    cmd_list.append('--target=aarch64-linux-musl')
101    result_list = []
102    all_files_list = get_all_object_file_path(file_path)
103    for element_file in all_files_list:
104        command = cmd_list + [element_file]
105        run_result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
106        result_list.extend(processing_data(run_result, element_file))
107    general_syntax_excel(result_list, output_path)
108    return result_list
109
110
111def processing_data(run_result, current_file):
112    api_result_info_list = []
113    for run_result_child in run_result.stderr.decode().split('^'):
114        split_error_message = run_result_child.split('\r\n')
115        error_content = ''.join(split_error_message[-2:-3:-1])
116        result_child = run_result_child.replace('~', '')
117        ret = re.findall('\\d+:\\d+', result_child)
118        error_file_message = re.search(r'([^"]+):\d:\d:', result_child)
119        error_file_name = current_file
120        if error_file_message:
121            error_file_list = error_file_message.group(1).split('\r\n')
122            if len(error_file_list) >= 1:
123                error_file_name = os.path.normpath(error_file_list[len(error_file_list) - 1])
124        if len(ret) != 0:
125            error_message = get_specified_string(result_child)
126            if len(error_message) == 1:
127                continue
128            position = ret[0]
129            api_result_info = ApiResultInfo(ErrorType.SYNTAX_ERRORS.value,
130                                            error_message[1], current_file)
131            line_column = get_line_and_column(position)
132            api_result_info.set_location_line(line_column[0])
133            api_result_info.set_location_column(line_column[1])
134            api_result_info.set_location(current_file)
135            api_result_info.set_type(LogType.LOG_API.value)
136            api_result_info.set_level(ErrorLevel.LOW.value)
137            api_result_info.set_file_name(error_file_name)
138            api_result_info_list.append(api_result_info)
139            api_result_info.set_error_content(error_content)
140    return api_result_info_list
141
142
143def get_line_and_column(location):
144    if location is not None:
145        return location.split(':')
146    return ['', '']
147
148
149def get_original(result_child: str):
150    if len(result_child) == 0:
151        return result_child
152    original = result_child.lstrip().split("\r\n")
153    if len(original) == 2:
154        return ''
155    if len(original) == 3:
156        return original[1]
157    if len(original) == 4:
158        return original[2]
159    return ''
160
161
162def get_specified_string(target_string):
163    message_type = 'error'
164    function_result = []
165    pattern = r'error: (.*?)\r\n'
166    matches = re.findall(pattern, target_string, re.DOTALL)
167    if len(matches) == 0:
168        pattern = r'warning: (.*?)\r\n'
169        matches = re.findall(pattern, target_string, re.DOTALL)
170        message_type = 'warning'
171    if len(matches) == 0:
172        pattern = r'note: (.*?)\r\n'
173        matches = re.findall(pattern, target_string, re.DOTALL)
174        message_type = 'note'
175    function_result.append(message_type)
176    for match in matches:
177        function_result.append(match)
178    if len(function_result[1]) == 0:
179        function_result.append('')
180    return function_result
181
182
183def get_file_path(file_path: str):
184    if len(file_path) == 0:
185        return file_path
186    path_split_len = len(file_path.split('\r\n'))
187    path_list = file_path.split('\r\n')
188    if path_split_len == 1:
189        return file_path
190    if path_split_len == 2:
191        return path_list[1]
192    if path_split_len == 3:
193        return path_list[2]
194    return ''
195