mirror of
https://github.com/openharmony/drivers_framework.git
synced 2026-08-27 02:42:28 -04:00
2577b335dc
Signed-off-by: bayanxing <bayanxing@kaihongdigi.com>
256 lines
11 KiB
Python
256 lines
11 KiB
Python
# !/usr/bin/env python3
|
|
# coding=utf-8
|
|
"""
|
|
* Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd.
|
|
*
|
|
* HDF is dual licensed: you can use it either under the terms of
|
|
* the GPL, or the BSD license, at your option.
|
|
* See the LICENSE file in the root of this repository for complete details.
|
|
"""
|
|
|
|
import json
|
|
import os
|
|
import re
|
|
from shutil import copyfile, move
|
|
|
|
import CppHeaderParser
|
|
|
|
|
|
class HeaderParser:
|
|
"""
|
|
Extract file path, file name, includes, enums, unions, structs, interfaces and callbacks
|
|
from CppHeaderParser
|
|
"""
|
|
|
|
def __init__(self):
|
|
self._header_dict = {
|
|
"name": "",
|
|
"path": "",
|
|
"import": [],
|
|
"enum": [],
|
|
"union": [],
|
|
"struct": [],
|
|
"typedef": [],
|
|
"interface": [],
|
|
"callback": []
|
|
}
|
|
self._rand_name_count = 0
|
|
|
|
def parse(self, header_file):
|
|
try:
|
|
hjson = json.loads(CppHeaderParser.CppHeader(header_file).toJSON())
|
|
except CppHeaderParser.CppParseError:
|
|
back_file = self._pre_handle(header_file)
|
|
hjson = json.loads(CppHeaderParser.CppHeader(header_file).toJSON())
|
|
move(back_file, header_file)
|
|
|
|
try:
|
|
self._extract_path_and_file(header_file)
|
|
self._extract_include(hjson["includes"])
|
|
self._extract_enum(hjson["enums"])
|
|
for i in hjson["classes"]:
|
|
self._extract_union(hjson["classes"][i])
|
|
self._extract_struct(hjson["classes"][i])
|
|
self._extract_interface(hjson["classes"][i])
|
|
self._extract_typedef(hjson["typedefs"])
|
|
return self._header_dict
|
|
except KeyError:
|
|
pass
|
|
|
|
@staticmethod
|
|
def _pre_handle(header_file):
|
|
back_file = header_file + ".back"
|
|
copyfile(header_file, back_file)
|
|
f = open(header_file, 'r')
|
|
new_lines = ""
|
|
for line in f:
|
|
tt = re.match(r".*enum *((\w+) *\*) *\w* *;", line)
|
|
if tt:
|
|
new_line = line.replace(tt[1], tt[2] + "_ENUM_POINTER ")
|
|
new_lines += new_line
|
|
continue
|
|
tt = re.match(r".*(\[\w* *\(.*\) *]) *", line)
|
|
if tt:
|
|
new_line = line.replace(tt[1], "[]")
|
|
new_lines += new_line
|
|
continue
|
|
else:
|
|
new_lines += line
|
|
f.close()
|
|
f = open(header_file, 'w')
|
|
f.writelines(new_lines)
|
|
f.close()
|
|
return back_file
|
|
|
|
@staticmethod
|
|
def _has_function_pointer(jvs):
|
|
for jv in jvs:
|
|
if jv["function_pointer"] > 0:
|
|
return True
|
|
return False
|
|
|
|
def _checkout_function_pointer_param(self, params):
|
|
if params == '':
|
|
return []
|
|
tt = re.match(r"(typedef )* *\w+ \( \* \) \(( .* )\)", params)
|
|
if tt:
|
|
params = tt[2].strip() + ","
|
|
else:
|
|
print("error cant analyze function pointer params: ", params)
|
|
return []
|
|
ret = []
|
|
while params:
|
|
tt = re.match(" *(const )*(struct |enum |union )* *", params)
|
|
if tt: # 去掉结构类型头
|
|
params = params[tt.regs[0][1]:]
|
|
tt = re.match(r"((unsigned )*[a-zA-Z0-9_:]+( *\** *\**)) *", params)
|
|
if tt:
|
|
param_type = params[tt.regs[1][0]:tt.regs[1][1]] # 参数类型
|
|
params = params[tt.regs[0][1]:]
|
|
tt = re.match("([a-zA-Z0-9_]+) *(,)", params)
|
|
if tt:
|
|
param_name = params[tt.regs[1][0]:tt.regs[1][1]]
|
|
params = params[tt.regs[0][1]:]
|
|
else: # 没有定义变量名的,设置一个默认变量名
|
|
param_name = "rand_name_%d" % self._rand_name_count
|
|
self._rand_name_count += 1
|
|
params = params[params.index(",") + 1:]
|
|
ret.append({"name": param_name, "type": param_type.strip()})
|
|
else:
|
|
ret.append({"name": '', "type": params.strip(',').strip()})
|
|
break
|
|
else:
|
|
print("error cant analyze param :[%s]" % params)
|
|
break
|
|
return ret
|
|
|
|
def _extract_path_and_file(self, path):
|
|
self._header_dict["path"], self._header_dict["name"] = os.path.split(path)
|
|
|
|
def _extract_include(self, includes):
|
|
"""
|
|
Extract imports from includes
|
|
"""
|
|
for include in includes:
|
|
if '<' not in include: # ignore system files
|
|
self._header_dict.get("import").append(include[1:-1])
|
|
|
|
def _extract_enum(self, enums):
|
|
"""
|
|
Extract enums from enums
|
|
"""
|
|
for enm in enums:
|
|
if "name" in enm:
|
|
enum_dict = {"name": enm["name"], "members": []}
|
|
else:
|
|
enum_dict = {"name": "LostName_%d" % self._rand_name_count, "members": []}
|
|
self._rand_name_count += 1
|
|
for value in enm["values"]:
|
|
v_value = value["value"]
|
|
if not isinstance(v_value, int):
|
|
tt = re.match(r"0x|0X|\(|-", v_value)
|
|
if tt:
|
|
errmsg = "unexpected '%s'" % tt[0]
|
|
v_value = v_value + " // " + errmsg
|
|
print("[HeaderParser]: %s[line %d] " % (enm["filename"], enm["line_number"]), errmsg)
|
|
enum_dict["members"].append({"name": value["name"], "value": v_value})
|
|
self._header_dict.get("enum").append(enum_dict)
|
|
|
|
def _extract_union(self, stack):
|
|
"""
|
|
Extract unions from classes
|
|
"""
|
|
union_dict = {}
|
|
if stack["declaration_method"] == "union":
|
|
union_dict["name"] = stack["name"].split(" ")[-1]
|
|
union_dict["type"] = "union"
|
|
union_dict["members"] = []
|
|
file_name = self._header_dict.get("path") + "/" + self._header_dict.get("name")
|
|
for mb in stack["members"]:
|
|
union_dict.get("members").append({"file_name": file_name,
|
|
"line_number": mb["line_number"],
|
|
"name": mb["name"], "type": mb["type"]})
|
|
self._header_dict.get("union").append(union_dict)
|
|
|
|
def _extract_struct(self, stack):
|
|
"""
|
|
Extract structs from structs or classes that have no methods
|
|
"""
|
|
struct_dict = {}
|
|
if stack["declaration_method"] in ["struct", "class"]:
|
|
if len(stack["methods"]["public"]) == 0: # 不带函数
|
|
if not self._has_function_pointer(stack["properties"]["public"]): # 变量中没有函数指针
|
|
struct_dict["name"] = stack["name"]
|
|
struct_dict["type"] = "struct"
|
|
struct_dict["members"] = []
|
|
file_name = self._header_dict.get("path") + "/" + self._header_dict.get("name")
|
|
for mb in stack["properties"]["public"]:
|
|
if "enum_type" in mb:
|
|
struct_dict.get("members").append({"file_name": file_name,
|
|
"line_number": mb["line_number"],
|
|
"name": mb["name"],
|
|
"type": mb["enum_type"]["name"]})
|
|
elif mb["array"] == 1:
|
|
struct_dict.get("members").append({"file_name": file_name,
|
|
"line_number": mb["line_number"],
|
|
"name": mb["name"],
|
|
"type": mb["type"] + " *"})
|
|
else:
|
|
struct_dict.get("members").append({"file_name": file_name,
|
|
"line_number": mb["line_number"],
|
|
"name": mb["name"],
|
|
"type": mb["type"]})
|
|
self._header_dict.get("struct").append(struct_dict)
|
|
|
|
def _extract_interface(self, stack):
|
|
"""
|
|
Extract interfaces from structs or classes which have some methods
|
|
"""
|
|
interface_dict = {}
|
|
if stack["declaration_method"] in ["struct", "class"]:
|
|
# 带函数,或变量中包含函数指针
|
|
if len(stack["methods"]["public"]) > 0 or self._has_function_pointer(stack["properties"]["public"]):
|
|
interface_dict["name"] = stack["name"]
|
|
interface_dict["members"] = []
|
|
for mb in stack["methods"]["public"]:
|
|
if mb["name"] in (stack["name"], "DECLARE_INTERFACE_DESCRIPTOR"):
|
|
continue
|
|
params = []
|
|
for param in mb["parameters"]:
|
|
para_name = param["name"]
|
|
if para_name == '':
|
|
para_name = "rand_name_%d" % self._rand_name_count
|
|
self._rand_name_count += 1
|
|
params.append({"name": para_name, "type": param["type"]})
|
|
interface_dict.get("members").append(
|
|
{"name": mb["name"],
|
|
"params": params,
|
|
"file_name":
|
|
self._header_dict.get("path") + "/" + self._header_dict.get("name"),
|
|
"line_number": mb["line_number"]})
|
|
for mb in stack["properties"]["public"]:
|
|
if mb["function_pointer"] > 0:
|
|
interface_dict.get("members").append(
|
|
{"name": mb["name"],
|
|
"params": self._checkout_function_pointer_param(mb["type"]),
|
|
"file_name":
|
|
self._header_dict.get("path") + "/" + self._header_dict.get("name"),
|
|
"line_number": mb["line_number"]})
|
|
self._header_dict.get("interface").append(interface_dict)
|
|
|
|
def _extract_typedef(self, typedefs):
|
|
"""
|
|
Extract typedef from global typedefs
|
|
e.g.
|
|
"typedefs": {
|
|
"HotPlugCallback": "typedef void ( * ) ( uint32_t devId , bool connected , void * data )",
|
|
"AudioHandle": "void *"
|
|
}
|
|
"""
|
|
for td in typedefs:
|
|
if "typedef" in typedefs[td]:
|
|
self._header_dict.get("typedef").append({"name": td,
|
|
"type": "/* unsupported function pointer type: " + td + " */"})
|
|
else:
|
|
self._header_dict.get("typedef").append({"name": td, "type": typedefs[td]})
|