• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# coding=utf-8
3#   Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
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 os
17import re
18import sys
19import platform
20import string
21import shutil
22import time
23import json
24import xml.etree.ElementTree as ET
25
26
27py_version = platform.python_version()
28
29def timestamp():
30    return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
31
32##########################################################################
33#
34# 日志内容提取函数
35#
36##########################################################################
37# 日志状态机处理流程:
38# LOG_ENTRY_FINDING              -- 查找日志接口
39# LOG_ENTRY_FOUNDED              -- 日志接口匹配,查找日志内容
40# LOG_CONT_ENTRY_FINDING         -- 日志内容入口匹配,以“号开关,以”号结束
41# LOG_CONT_END_FOUNING           -- 日志内容查找
42# LOG_EXIT_FINDING               -- 日志线束符匹配
43
44# 全局变量
45aich_name = ""
46log_info_list = []   # 日志信息列表,【文件号, 行号, 日志内容】
47g_undefine_id = []  # 保存未定义的FileId
48g_fsm_status = "LOG_ENTRY_FINDING"
49g_log_key_find = 0  # (状态位)判断是否查找到日志关键字,0否1是
50g_log_str = ""
51g_log_str_full = ""
52g_log_entry = [
53    r"LOG_PRINT[0-4](\s*)\(",
54    r"log_print[0-4](\s*)\(",
55    r"acore_log[0-4](\s*)\(",
56    r"[printlog]{3,5}_alter(\s*)\(",
57    r"[PRINTLOG]{3,5}_ALTER(\s*)\(",
58    r"_LOG[0-4]{1,2}(\s*)\(",
59    r"(DBG|INFO|ERR|WARN)_LOG(\s*)\(",
60    # BTH
61    r"(dbg|info|err|warn)_log(\s*)\(",
62    r"(dbg|info|err|warn)_log[0-4](\s*)\(",
63    # diag common
64    r"diag_(error|warning|info|debug)_log(\d*)(\s*)\(",
65    r"PRINT_(DEBUG|INFO|ERR|WARN)(\s*)\(",
66    r"print_(debug|info|err|warn)(\s*)\(",
67    r"_log_(err|warn|info|debug)(\s*)\(",
68    # GPU
69    r"(vau|dpu|jpeg|gmmu|vg)_(err|info|dbg|print)(\s*)\(",
70    # WIFI
71    r"oam_(error|warning|info)_log[0-4](\s*)\(",
72    r"alg_ar_dbg_log[0-4](\s*)\(",
73    r"common_log_dbg[0-4](\s*)\(",
74    # GPU
75    r"GRAPHIC_LOG(F|E|W|I|D|P)(\s*)\(",
76    r"DISP_LOG(E|W|I|D)(\s*)\(",
77    r"LV_LOG(E|W|I)(\s*)\(",
78    # Meida
79    r"ALOG(V|D|I|W|E)(\s*)\(",
80    r"MEDIA_(DEBUG|ERR|WARNING|INFO|FATAL)_LOG(\s*)\(",
81    r"HMF_LOG(F|E|W|I)(\s*)\(",
82    r"MEDIA_HAL_LOG(V|D|I|W|E)(\s*)\(",
83    r"CHECK_NULL_(RETURN|RETURN_NONE)(\s*)\(",
84    r"CHECK_FAILED_(RETURN|RETURN_NONE|PRINT|RETURN_WITH_UNLOCK)(\s*)\(",
85    r"CHK_NULL_(RETURN|RETURN_NONE|RETURN_WITH_UNLOCK)(\s*)\(",
86    r"CHK_FAILED_(RETURN|NO_RETURN)(\s*)\(",
87    r"(CHK_COND_RETURN|CHK_FALSE_RETURN|CHECK_STATE_SAME_RETURN)(\s*)\(",
88    # OHOS
89    r"HILOG_(DEBUG|ERROR|FATAL|INFO|WARN)(\s*)\(",
90    r"SAMGR_LOG_(ERROR|FATAL|INFO|WARN)(\s*)\(",
91    # app
92    r"WEARABLE_LOG(D|I|W|E)(\s*)\(",
93    # plat
94    r"hcc_printf_err_log(\s*)\(",
95    # audio
96    r"audio_log[0-4](\s*)\(",
97]  # 日志关键字规则
98
99# DSP日志关键字规则,不要改变顺序,慎重修改
100g_audio_log_entry = [
101    r"sap_(alert|fatal|err|warn|dbg|trace)_log_(s32|bool)(\s*)\(",
102    r"sap_(alert|fatal|err|warn|dbg|trace)_log_u32(\s*)\(",
103    r"sap_(alert|fatal|err|warn|dbg|trace)_log_h32(\s*)\(",
104    r"sap_(alert|fatal|err|warn|dbg|trace)_log_float(\s*)\(",
105    r"sap_(alert|fatal|err|warn|dbg|trace)_log_void(\s*)\(",
106    r"sap_(alert|fatal|err|warn|dbg|trace)_log_ret(\s*)\(",
107    r"sap_(alert|fatal|err|warn|dbg|trace)_log_fun(\s*)\(",
108    r"sap_(alert|fatal|err|warn|dbg|trace)_log_null_pointer(\s*)\(",
109    r"audio_func_enter(\s*)\(",
110    r"audio_func_exit(\s*)\(",
111    r"sap_(alert|fatal|err|warn|dbg|trace)_log_info(\s*)\(",
112    r"audio_log_(alert|fatal|err|warn|dbg|trace)(\s*)\(",
113]  # DSP日志关键字规则,不要改变顺序,慎重修改
114
115g_audio_log_key_index = -1
116g_audio_log_addition_info = [" = %d",
117                             " = %u",
118                             " = 0x%08X",
119                             " = %f",
120                             " = %p",
121                             "Error Code: [0x%08X]",
122                             " Failed, Error Code: [0x%08X]",
123                             " = %p,  Null Pointer!\\n",
124                             "enter...",
125                             "exit..."]
126
127g_log_full_cont = '\"(.*)\"\s*[,|)]'
128# 用于记录日志行数,日志多行时可能是第一行,有可能是最后一行;
129# 0 表示第一行  1表示最后一行
130g_log_entry_or_end_flag = -1
131
132XML_PATH="build/config/target_config/<chip>/hdb_config/database_cfg/mk_hdb_xml.json"
133
134def get_log_level(str):
135    m = re.search(r'LOG_LEVEL_ERROR|ERR_LOG|err_log|(GRAPHIC|DISP|LV)_LOGF|(GRAPHIC|DISP|LV)_LOGE|WEARABLE_LOGE|_ERR|print_err|ERROR|FATAL', str)
136    if m is not None:
137        return 2,'ERROR'
138    m = re.search(r'(CHK|CHECK)_NULL_RETURN|(CHK|CHECK)_NULL_RETURN_NONE|(CHK|CHECK)_FAILED_RETURN|CHECK_FAILED_RETURN_NONE', str)
139    if m is not None:
140        return 2,'ERROR'
141    m = re.search(r'CHECK_FAILED_PRINT|CHECK_FAILED_RETURN_WITH_UNLOCK|CHK_NULL_RETURN_WITH_UNLOCK|CHK_FAILED_NO_RETURN', str)
142    if m is not None:
143        return 2,'ERROR'
144    m = re.search(r'CHK_COND_RETURN|CHK_FALSE_RETURN', str)
145    if m is not None:
146        return 2,'ERROR'
147    m = re.search(r'LOG_LEVEL_WARNING|WARN_LOG|warn_log|warning_log|(GRAPHIC|DISP|LV)_LOGW|WEARABLE_LOGW|_WARN|print_warn', str)
148    if m is not None:
149        return 3,'WARNING'
150    m = re.search(r'alg_ar_dbg|common_log_dbg', str)
151    if m is not None:
152        return 3,'WARNING'
153    m = re.search(r'LOG_LEVEL_INFO|INFO_LOG|info_log|(GRAPHIC|DISP|LV)_LOGI|GRAPHIC_LOGP|WEARABLE_LOGI|_INFO|print_info', str)
154    if m is not None:
155        return 5,'INFO'
156    m = re.search(r'CHECK_STATE_SAME_RETURN', str)
157    if m is not None:
158        return 5,'INFO'
159    m = re.search(r'LOG_LEVEL_DBG|(DBG|DEBUG)_LOG|(dbg|debug)_log|(GRAPHIC|DISP|LV)_LOGD|WEARABLE_LOGD|_DEBUG|print_debug', str)
160    if m is not None:
161        return 6,'DBG'
162
163    m = re.search(r'_error_log|_log_err|_ERROR_|(vau|dpu|jpeg|gmmu|vg)_err|ALOGE|MEDIA_(ERR|FATAL)_LOG|HMF_LOG(F|E)|MEDIA_HAL_LOGE', str)
164    if m is not None:
165        return 2,'ERROR'
166    m = re.search(r'_warning_log|_log_warn|_WARNING_|ALOGW|HMF_LOGW|MEDIA_HAL_LOGW', str)
167    if m is not None:
168        return 3,'WARNING'
169    m = re.search(r'_info_log|_log_info|_INFO_|(vau|dpu|jpeg|gmmu|vg)_info|ALOGI|MEDIA_INFO_LOG|HMF_LOGI|MEDIA_HAL_LOGI', str)
170    if m is not None:
171        return 5,'INFO'
172    m = re.search(r'_debug_log|_log_debug|(vau|dpu|jpeg|gmmu|vg)_(dbg|print)|ALOG(V|D)|MEDIA_DEBUG_LOG|MEDIA_HAL_LOG(V|D)', str)
173    if m is not None:
174        return 6,'DBG'
175
176    print("no match for :%s" % str)
177    return 7, 'no match'
178
179# DSP日志级别识别,慎重修改
180def get_audio_log_level(str):
181    m = re.search(r'_alert|_err|_fatal', str)
182    if m is not None:
183        return 2,'ERROR'
184    m = re.search(r'_warn', str)
185    if m is not None:
186        return 3,'WARNING'
187    m = re.search(r'_trace', str)
188    if m is not None:
189        return 5,'INFO'
190    m = re.search(r'_dbg', str)
191    if m is not None:
192        return 6,'DBG'
193    m = re.search(r'_enter|_exit', str)
194    if m is not None:
195        return 5,'INFO'
196    print("audio log no match for :%s" % str)
197    return 7, 'no match'
198
199def add_content_to_xml(data, msg_root_element):
200    prim_pri  = data["LEVEL_STR"]
201    prim_sz =  data["FMT"]
202    prim_line = data["LINE_NUM"]
203    prim_file = data["FILE_NAME"]
204    prim_file_id = data["FILE_ID"]
205    args_count = data["ARGS_COUNT"]
206    mod_id = data["MOD_ID"]
207    level = data["LEVEL_NUM"]
208
209    new_element = ET.Element('')
210    new_element.tag = 'MSG'
211    new_element.attrib['STRUCTURE'] = "%s%d" % ("diag_log_msg", args_count)
212    new_element.attrib['NAME'] = "%s @%s(%d),%s" % (prim_sz, prim_file, prim_line, prim_pri)
213
214    #sdt log_id to hso msg_id
215    #log_flg  mod_id   file_id   line_num   level
216    #1bit     4bit     10bit     14bit      3bit
217    msg_id = (1 << 31) | (mod_id << 27) | (prim_file_id << 17) | (prim_line << 3) | level
218    new_element.attrib['ID'] = hex(msg_id)
219    new_element.tail = '\n\t\t\t'
220    msg_root_element.append(new_element)
221
222# 根据日志状态机流程逐行解析日志内容
223def parse_log_from_line(line):
224    global g_fsm_status
225    global g_log_str
226    global g_log_str_full
227    global g_log_str_full_flag
228    global g_log_entry
229    global g_log_full_cont
230    global g_log_entry_or_end_flag
231    global g_log_key_find
232    global g_audio_log_key_index
233    findkey = 0
234    # 匹配日志接口
235    if "LOG_ENTRY_FINDING" == g_fsm_status:
236        g_log_entry_or_end_flag = -1
237        g_audio_log_key_index = -1
238        g_log_str = ""
239        g_log_str_full = ""
240        for x in g_log_entry:
241            m = re.search(x, line.strip())
242            if m is not None:
243                findkey = 1
244                break
245        if 1 == findkey:
246            g_fsm_status = "LOG_ENTRY_FOUNDED"
247            g_log_str_full += line
248            g_log_entry_or_end_flag = 0
249            g_log_key_find = 1
250            parse_log_from_line(line)
251
252        # SAP log
253        find_audio_key = 0
254        index = 0
255        for x in g_audio_log_entry:
256            m = re.search(x, line.strip())
257            if m is not None:
258                find_audio_key = 1
259                break
260            index = index + 1
261        if 1 == find_audio_key:
262            g_fsm_status = "LOG_ENTRY_FOUNDED"
263            g_log_str_full += line
264            g_log_entry_or_end_flag = 0
265            g_audio_log_key_index = index
266            g_log_key_find = 1
267            parse_log_from_line(line)
268        else:
269            return
270
271    # 日志接口匹配,确认是否完整日志;确认日志是否正常结束
272    elif "LOG_ENTRY_FOUNDED" == g_fsm_status:
273        if g_audio_log_key_index >= 0 and g_audio_log_key_index <= 4:   # such as "sap_alert_log_u32"
274            m1 = re.search("\(\s*(\S+)\s*\)", line)
275            if m1 is not None:
276                g_log_str = m1.groups()[0] + g_audio_log_addition_info[g_audio_log_key_index] + '\0';
277                g_fsm_status = "LOG_EXIT_FINDING"
278                parse_log_from_line(line)
279        elif g_audio_log_key_index == 5: # such as "sap_fatal_log_err_code"
280            m1 = re.search("\(\s*(\w+)\s*\)", line)
281            if m1 is not None:
282                g_log_str = g_audio_log_addition_info[g_audio_log_key_index] + '\0';
283                g_fsm_status = "LOG_EXIT_FINDING"
284                parse_log_from_line(line)
285        elif g_audio_log_key_index == 6: # such as "sap_err_log_fun_err"
286            m1 = re.search("\(\s*(\w+)\s*,", line)
287            if m1 is not None:
288                g_log_str = "Call " + m1.groups()[0] + g_audio_log_addition_info[g_audio_log_key_index] + '\0';
289                g_fsm_status = "LOG_EXIT_FINDING"
290                parse_log_from_line(line)
291        elif g_audio_log_key_index == 7: # such as "sap_err_log_null_pointer"
292            m1 = re.search("\(\s*(\S+)\s*\)", line)
293            if m1 is not None:
294                g_log_str = m1.groups()[0] + g_audio_log_addition_info[g_audio_log_key_index] + '\0';
295                g_fsm_status = "LOG_EXIT_FINDING"
296                parse_log_from_line(line)
297        elif g_audio_log_key_index == 8 or g_audio_log_key_index == 9: # such as "audio_func_enter"
298            m1 = re.search("\(\)", line)
299            if m1 is not None:
300                g_log_str = g_audio_log_addition_info[g_audio_log_key_index] + '\0';
301                g_fsm_status = "LOG_EXIT_FINDING"
302                parse_log_from_line(line)
303        else:
304            m1 = re.search(g_log_full_cont, line)  # 完整日志格式
305            m2 = re.search("\"(.+)", line)  # 部分日志格式 ,引号开头
306            if m1 is not None:
307                g_log_str = m1.groups()[0] + '\0'
308                g_fsm_status = "LOG_EXIT_FINDING"
309                parse_log_from_line(line)
310            elif m2 is not None:
311                g_fsm_status = "LOG_CONT_END_FINDING"
312                g_log_str = m2.groups()[0]  # 引号后面的内容为日志内容
313                m1 = re.search(r'(.+)"\s*[,|)]', line)
314                if m1 is not None:
315                    g_fsm_status = "LOG_EXIT_FINDING"
316            if "LOG_ENTRY_FOUNDED" == g_fsm_status:
317                m3 = re.search(r"\)[\s]*\;", line.strip())
318                if m3 is not None:
319                    g_fsm_status = "LOG_ENTRY_FINDING"
320                    g_log_entry_or_end_flag = -1
321                    g_audio_log_key_index = -1
322            if g_log_str_full.find(line) == -1:
323                g_log_str_full += line
324
325    # 匹配部分日志接口
326    elif "LOG_CONT_END_FINDING" == g_fsm_status:
327        m = re.search(r"[\s]+(.+)\"", line)
328        if m is not None:
329            temp = m.groups()[0]
330            m1 = re.search(r'(.+)"\s*[,|)]', line)  #部分日志可以跨多行
331            if m1 is None:
332                g_log_str += temp
333            else:
334                g_log_str += (temp + '\0')
335                g_fsm_status = "LOG_EXIT_FINDING"
336                parse_log_from_line(line)
337        else:
338            g_log_str += line.strip()  # 纯日志内容 ,继续找日志
339        if g_log_str_full.find(line) == -1:
340            g_log_str_full += line
341
342    # 匹配日志结束符
343    elif "LOG_EXIT_FINDING" == g_fsm_status:
344        m = re.search(r"\)[\s]*\;", line.strip())
345        if m is not None:
346            g_fsm_status = "LOG_ENTRY_FINDING"  # 继续逐行扫描下一条日志入口
347            g_log_entry_or_end_flag = 1
348        if g_log_str_full.find(line) == -1:
349            g_log_str_full += line
350
351
352g_file_id_dict = {}  # file_id_str  file_id_num
353g_last_file_id_num = 0
354g_moudle_id = {
355    'wifi' : 0,
356    'bt' : 1,
357    'gnss' :2,
358    'dsp' : 3,
359    'pf' : 4,
360    'media' : 5,
361    'nfc': 6,
362    'app' : 7,
363    'gpu': 8,
364    'gui' : 9,
365    'slp' : 10,
366    'bth' : 11,
367    'ohos' : 12,
368}
369
370def parse_single_source_file(cfilepath, auto_def, module_name):
371    global g_log_key_find
372    global g_log_str
373    global g_fsm_status
374    global log_info_list
375    global g_audio_log_key_index
376    curr_line_num = 0      # 当前行行号
377    file_id_num = 0      # 本文件号
378    line_num_save = 0
379    log_info_list = []
380
381    m = re.search(r"\w.[cC|hH]", cfilepath)
382    if m is None:
383        print("Error!%s is not C or H File" % cfilepath)
384        return
385
386    # 增加对文件中换行符的处理
387    destfile = cfilepath + "_temp"
388    modify_newline_on_linux(cfilepath, destfile)
389    # 打开源文件,读取文件内容
390    try:
391        if py_version.startswith("3"):
392            try:
393                with open(destfile, 'r', encoding="UTF-8") as fd_src:
394                    datalines = [line for line in fd_src]
395            except Exception:
396                with open(destfile, 'r', encoding="ISO-8859-1") as fd_src:
397                    datalines = [line for line in fd_src]
398        else:
399            with open(destfile, 'r') as fd_src:
400                datalines = [line for line in fd_src]
401    except Exception:
402        print("open file %s failed." % cfilepath)
403        return
404
405    os.remove(destfile)
406    if module_name not in g_file_id_dict:
407        return
408    _, filename = os.path.split(cfilepath)
409    if auto_def:
410        file_id_str = filename.replace('.' , '_').upper()
411        if file_id_str not in g_file_id_dict[module_name]:
412            return
413        g_fsm_status = "LOG_ENTRY_FINDING"
414    else:
415        m = re.search(r"#define[\s]+THIS_FILE_ID[\s]+([\w]*)", '\n'.join(datalines))
416        if m is None:
417            return 0
418        file_id_str = m.group(1)
419        g_fsm_status = "LOG_ENTRY_FINDING"
420
421    # 遍历行内容
422    for line in datalines:
423        # 行号加1
424        curr_line_num += 1
425
426        m = re.search(r'^\/\/', line.strip())
427        if m is not None:
428            continue
429        # 判断是否可识别的普通日志文件
430        parse_log_from_line(line)
431        if 1 == g_log_key_find:
432            try:
433                file_id_num = g_file_id_dict[module_name][file_id_str]
434                moudle_id_num = g_moudle_id[module_name]
435            except KeyError:
436                #print(
437                #    "warning: Moudle:%s, %s not defined. fileName[%s]." %
438                #    (moudle_name, file_id_str, filename))
439                g_undefine_id.append((file_id_str, filename))
440                break
441            g_log_key_find = 0
442            line_num_save = curr_line_num
443        # 解析日志,判断是否找到,如果找到写入文件
444        if 1 == g_log_entry_or_end_flag:
445            g_log_str = g_log_str.replace('\\r', "")  # 清除\r,\n,空格
446            g_log_str = g_log_str.replace('\\n', "")
447            g_log_str = g_log_str.replace('\r', "")  # 清除\r,\n,空格
448            g_log_str = g_log_str.replace('\n', "")
449            g_log_str = g_log_str.replace("\\", "")
450            g_log_str = g_log_str.replace('""', "")
451            g_log_str = g_log_str.replace("\000", "")
452            g_log_str.strip()
453            if (g_audio_log_key_index != -1):
454                level_num, level_str = get_audio_log_level(g_log_str_full)
455            else:
456                level_num, level_str = get_log_level(g_log_str_full)
457            data = { }
458            data["MOD_ID"] = moudle_id_num
459            data["FILE_ID"] = file_id_num
460            if (aich_name == "cortex_m7"):
461                data["LINE_NUM"] = line_num_save
462            else:
463                data["LINE_NUM"] = curr_line_num
464            data["FMT"] = g_log_str
465            data["LEVEL_NUM"] = level_num
466            data["LEVEL_STR"] = level_str
467            data["ARGS_COUNT"] = g_log_str.count("%")
468            data["FILE_NAME"] =  cfilepath.split('/')[-1]
469            log_info_list.append(data)
470            g_log_key_find = 0
471            g_audio_log_key_index = -1
472    return 0
473
474
475# 保存FILD_ID
476def save_file_id_dict(line_str, moudle_name):
477    global g_file_id_dict
478    global g_last_file_id_num
479
480    file_id_str = ''
481    file_id_num = 0
482    if line_str == '':
483        return 0
484
485    m2 = re.search("[^A-Za-z0-9_=]", line_str)
486    if m2 is None:
487        m1 = line_str.split('=')  # XXXXXXX = dddd,
488        if len(m1) == 2:
489            file_id_str = m1[0]  # 获取file id字符串
490            file_id_num = m1[1]
491            g_file_id_dict[moudle_name][file_id_str] = int(file_id_num)
492            g_last_file_id_num = int(file_id_num) + 1
493        else:
494            file_id_str = line_str
495            g_file_id_dict[moudle_name][file_id_str] = g_last_file_id_num
496            g_last_file_id_num += 1
497    else:
498        return -1
499    return 0
500
501
502# 打印fileid的映射字典
503def print_file_id_dict():
504    print(timestamp() + " start to print FileIdDict::")
505    for system_name in g_file_id_dict:
506        for key in g_file_id_dict[system_name]:
507            print(timestamp() + " key:%s value:%d" % (key,\
508                  g_file_id_dict[system_name][key]))
509
510
511# 获取FILE_ID枚举值
512def get_file_id_enum_in_file(h_file_path):
513    global g_file_id_dict
514    global g_last_file_id_num
515    g_last_file_id_num = 0
516
517    moudle_name = os.path.basename(h_file_path).split('_')[-1][:-2]
518    # btc将file_id头文件迁移后取名为log_def_btc.h 实际moudle_name任是bt
519    # bth将file_id头文件迁移后取名为log_def_bth.h 实际moudle_name任是bt
520    if moudle_name == 'btc':
521        moudle_name = 'bt'
522    if chip == 'bs25' and core_name == 'bt_core' and moudle_name == "bth":
523        moudle_name = 'bt'
524    if moudle_name not in g_file_id_dict:
525        g_file_id_dict[moudle_name] = {}
526    m = re.search(r'\w+\.h$', h_file_path)
527    if m is None:
528        print(timestamp() + ' Wrong type file, please input head file path.')
529        return -1
530
531    if not os.path.exists(h_file_path):
532        print(timestamp() + ' Head file [%s] did not exist.' % (h_file_path))
533        return 0
534    try:
535        if py_version.startswith("3"):
536            with open(h_file_path, 'r', encoding="UTF-8") as fd:
537                id_file = fd.read()
538        else:
539            with open(h_file_path, 'r') as fd:
540                id_file = fd.read()
541    except Exception as e:
542        print(e)
543        return -1
544    id_list = re.search(r"typedef enum[\s]*\{([\d\D]*?)\}", id_file).group(1)
545    id_list = id_list.replace(',', '').replace(' ', '').split('\n')
546    for line_str in id_list:
547        line_str = line_str.strip().split("/")[0]
548        save_file_id_dict(line_str, moudle_name)
549
550    return 0
551
552def get_file_id_enum_in_paths(h_file_paths):
553    for h_file in h_file_paths:
554        if not h_file:
555            continue
556        if get_file_id_enum_in_file(h_file) != 0:
557            return -1
558    return 0
559
560
561# 文件换行符处理
562def modify_newline_on_linux(srcfile, destfile):
563    with open(srcfile, "rb") as fsrc, open(destfile, "wb") as fdest:
564        while True:
565            cs = fsrc.read(1)
566            if len(cs) > 0:
567                if cs == "\r":
568                    fdest.write(cs)
569                    cs = fsrc.read(1)
570                    if cs != "\n":
571                        fdest.write("\n")
572                        fdest.write(cs)
573                    else:
574                        fdest.write(cs)
575                else:
576                    fdest.write(cs)
577            else:
578                break
579
580#mkdir ${target} ${root} ${chip} ${core}
581def generate_db_temp_dir(sys_argv):
582    root = sys_argv[2]
583    chip = sys_argv[3]
584    core_name = sys_argv[4]
585    in_path = XML_PATH
586    in_path = in_path.replace('<chip>', chip)
587
588    # get global settings
589    db_conf = None
590    conf = os.path.join(root, in_path)
591    with open(conf, 'r') as f:
592        db_conf = json.load(f)
593
594    base_file_dir = os.path.join(os.path.join(root, db_conf["HDB_XML_TEMP_BASE_DIR"]), core_name)
595    if not os.path.exists(base_file_dir):
596        os.makedirs(base_file_dir)
597
598#${target} ${root} ${chip} ${core} ${src_file} ${file_id_dir}
599def generate_db_xml(root, core_name, auto_def, module_name, src_file, closed_flag):
600    global log_info_list
601    if not os.path.isfile(src_file):
602        return
603
604    # get global settings
605    db_conf = None
606    conf = os.path.join(root, in_path)
607    with open(conf, 'r') as f:
608        db_conf = json.load(f)
609
610    parse_single_source_file(src_file, auto_def, module_name)
611    if len(log_info_list) == 0:
612        return
613
614    _, filename = os.path.split(src_file)
615    filename = filename + ".xml"
616    if (closed_flag != True):
617        base_file_dir = os.path.join(os.path.join(root, db_conf["HDB_XML_TEMP_BASE_DIR"]), core_name)
618    else:
619        base_file_dir = os.path.join(os.path.join(root, db_conf["HDB_XML_TEMP_BASE_DIR"]), "closed_comp")
620        if not os.path.exists(base_file_dir):
621            os.makedirs(base_file_dir)
622
623    dst_xml_full_name = os.path.join(base_file_dir, filename)
624
625    msg_root_element = ET.Element('MSG_LOG')
626    for data in log_info_list:
627        add_content_to_xml(data, msg_root_element)
628
629    tree = ET.ElementTree(msg_root_element)
630    tree.write(dst_xml_full_name)
631
632# main
633if __name__ == "__main__":
634    if (sys.argv[1] == "mkdir"):
635        generate_db_temp_dir(sys.argv)
636        sys.exit(0)
637    root = sys.argv[1]
638    chip = sys.argv[2]
639    core_name = sys.argv[3]
640    aich_name = sys.argv[4]
641    in_path = XML_PATH
642    in_path = in_path.replace('<chip>', chip)
643    auto_def = sys.argv[5]
644    if auto_def == "TRUE" or auto_def == "True":
645        auto_def = True
646    else:
647        auto_def = False
648    module_name = sys.argv[6]
649    closed_flag = sys.argv[7]
650    if closed_flag == "TRUE" or closed_flag == "True":
651        closed_flag = True
652    else:
653        closed_flag = False
654    info_file = sys.argv[8]
655
656    try:
657        with open(info_file, 'r') as f:
658            text = f.read()
659            file_id_dir = text.split("####")[0].split(',')
660            src_files = text.split("####")[1].split(',')
661
662        if file_id_dir != None and get_file_id_enum_in_paths(file_id_dir) != 0:
663            sys.exit(1)
664
665        for src_file in src_files:
666            src_file = src_file.strip()
667            generate_db_xml(root, core_name, auto_def, module_name, src_file, closed_flag)
668    except:
669        print("[WARN] open %s exception" % info_file)
670