mirror of
https://github.com/sipeed/MaixCDK.git
synced 2026-09-10 21:59:54 -05:00
fix some API map error & add MaixPy API dumplicate check
This commit is contained in:
2
components/3rd_party/zbar/CMakeLists.txt
vendored
2
components/3rd_party/zbar/CMakeLists.txt
vendored
@@ -46,7 +46,7 @@ list(REMOVE_ITEM ADD_SRCS "${src_path}/zbar/svg.c")
|
||||
#### Just for this component, won't affect other
|
||||
#### modules, including component that depend
|
||||
#### on this component
|
||||
# list(APPEND ADD_DEFINITIONS_PRIVATE -DAAAAA=1)
|
||||
list(APPEND ADD_DEFINITIONS_PRIVATE -Wno-parentheses)
|
||||
|
||||
#### Add compile option for this component
|
||||
#### Add components that depend on this component
|
||||
|
||||
@@ -586,7 +586,7 @@ namespace maix
|
||||
/**
|
||||
* Operator []
|
||||
* @maixpy maix.tensor.Tensors.__getitem__
|
||||
* @maixcdk maix.tensor.Tensors.[]
|
||||
* @maixcdk maix.tensor.Tensors.operator[]
|
||||
*/
|
||||
tensor::Tensor &operator[](const std::string &key)
|
||||
{
|
||||
|
||||
@@ -228,9 +228,9 @@ namespace maix::time
|
||||
* FPS is average value of recent n(buff_len) times, and you can call fps_set_buff_len(10) to change buffer length, default is 20.
|
||||
* Multiple invoke this function will calculate fps between two invoke, and you can also call fps_start() fisrt to manually assign fps calulate start point.
|
||||
* @return float type, current fps since last call this method
|
||||
* @maixpy maix.time.FPS.fps
|
||||
* @maixpy maix.time.FPS.end
|
||||
*/
|
||||
inline float end()
|
||||
float end()
|
||||
{
|
||||
return fps();
|
||||
}
|
||||
@@ -409,7 +409,7 @@ namespace maix::time
|
||||
* @param city string type, which city to set, can be empty means only get current, default empty.
|
||||
* @return list type, return current timezone setting, first is region, second is city.
|
||||
* @attention when set new timezone, time setting not take effect in this process for some API, so you need to restart program.
|
||||
* @maixpy maix.time.timezone
|
||||
* @maixpy maix.time.timezone2
|
||||
*/
|
||||
std::vector<std::string> timezone2(const std::string ®ion = "", const std::string &city = "");
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ public:
|
||||
/**
|
||||
* @brief Get the battery voltage.
|
||||
* @return uint16_t type, return battery voltage.
|
||||
* @maixpy maix.ext_dev.pmu.PMU.get_vat_vol
|
||||
* @maixpy maix.ext_dev.pmu.PMU.get_bat_vol
|
||||
*/
|
||||
uint16_t get_bat_vol();
|
||||
|
||||
|
||||
@@ -213,7 +213,7 @@ namespace maix::nn
|
||||
/**
|
||||
* Get object item
|
||||
* @maixpy maix.nn.FaceObjects.__getitem__
|
||||
* @maixcdk maix.nn.FaceObjects.[]
|
||||
* @maixcdk maix.nn.FaceObjects.operator[]
|
||||
*/
|
||||
nn::FaceObject &operator[](int idx)
|
||||
{
|
||||
|
||||
@@ -324,7 +324,7 @@ namespace maix::nn
|
||||
/**
|
||||
* Get object item
|
||||
* @maixpy maix.nn.Objects.__getitem__
|
||||
* @maixcdk maix.nn.Objects.[]
|
||||
* @maixcdk maix.nn.Objects.operator[]
|
||||
*/
|
||||
nn::Object &operator[](int idx)
|
||||
{
|
||||
|
||||
@@ -262,7 +262,7 @@ namespace maix::nn
|
||||
/**
|
||||
* Get object item
|
||||
* @maixpy maix.nn.OCR_Objects.__getitem__
|
||||
* @maixcdk maix.nn.OCR_Objects.[]
|
||||
* @maixcdk maix.nn.OCR_Objects.operator[]
|
||||
*/
|
||||
nn::OCR_Object &operator[](int idx)
|
||||
{
|
||||
|
||||
@@ -523,7 +523,7 @@ namespace maix::image
|
||||
* @param height new height, if value is -1, will use width to calculate aspect ratio
|
||||
* @param method resize method, by default is bilinear
|
||||
* @return new transformed image object
|
||||
* @maixpy maix.image.Image.affine
|
||||
* @maixpy maix.image.Image.perspective
|
||||
*/
|
||||
image::Image* perspective(std::vector<int> src_points, std::vector<int> dst_points, int width = -1, int height = -1, image::ResizeMethod method = image::ResizeMethod::BILINEAR);
|
||||
|
||||
@@ -1513,7 +1513,7 @@ namespace maix::image
|
||||
* @param w original rectagle width, can be -1 if not use this arg, default -1.
|
||||
* @param h original rectagle height, can be -1 if not use this arg, default -1.
|
||||
* @return list type, [x, y] if map point, [x, y, w, h] if resize rectangle.
|
||||
* @maixpy maix.image.resize_map_pos
|
||||
* @maixpy maix.image.Image.resize_map_pos
|
||||
*/
|
||||
std::vector<int> resize_map_pos(int w_out, int h_out, image::Fit fit, int x, int y, int w = -1, int h = -1)
|
||||
{
|
||||
|
||||
@@ -202,7 +202,7 @@ namespace maix::image
|
||||
* @param index 0 for width, 1 for height
|
||||
* @return int& width or height
|
||||
* @maixpy maix.image.Size.__getitem__
|
||||
* @maixcdk maix.image.Size.[]
|
||||
* @maixcdk maix.image.Size.operator[]
|
||||
*/
|
||||
int &operator[](int index)
|
||||
{
|
||||
|
||||
@@ -2847,7 +2847,7 @@ namespace maix::image
|
||||
* @param type The line list type, @see image::LineType
|
||||
* @param lines The line list
|
||||
* @param points Point sets of line
|
||||
* @maixpy maix.image.HaarCascade.__init__
|
||||
* @maixpy maix.image.LineGroup.__init__
|
||||
*/
|
||||
LineGroup(int id, image::LineType type, std::vector<image::Line> lines, std::vector<std::vector<std::vector<int>>> points = std::vector<std::vector<std::vector<int>>>()) {
|
||||
_id = id;
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace maix::http
|
||||
/**
|
||||
* @brief stop http
|
||||
* @return error code, err::ERR_NONE means success, others means failed
|
||||
* @maixpy maix.http.JpegStreamer.start
|
||||
* @maixpy maix.http.JpegStreamer.stop
|
||||
*/
|
||||
err::Err stop();
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace maix::rtmp
|
||||
/**
|
||||
* @brief Get bitrate
|
||||
* @return bitrate
|
||||
* @maixpy maix.rtmp.Rtmp.push_video
|
||||
* @maixpy maix.rtmp.Rtmp.bitrate
|
||||
*/
|
||||
int bitrate() {
|
||||
return _bitrate;
|
||||
@@ -234,7 +234,7 @@ namespace maix::rtmp
|
||||
/**
|
||||
* @brief Check whether push streaming has started
|
||||
* @return If rtmp thread is running, returns true
|
||||
* @maixpy maix.rtmp.Rtmp.get_path
|
||||
* @maixpy maix.rtmp.Rtmp.is_started
|
||||
*/
|
||||
bool is_started() {
|
||||
return _start ? true : false;
|
||||
|
||||
@@ -105,7 +105,7 @@ namespace maix::rtsp
|
||||
/**
|
||||
* @brief stop rtsp
|
||||
* @return error code, err::ERR_NONE means success, others means failed
|
||||
* @maixpy maix.rtsp.Rtsp.start
|
||||
* @maixpy maix.rtsp.Rtsp.stop
|
||||
*/
|
||||
err::Err stop();
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace maix::touchscreen
|
||||
* @param y y coordinate
|
||||
* @param pressed pressed state
|
||||
* @return error code, err::ERR_NONE means success, others means failed, if no event return err::ERR_NOT_READY
|
||||
* @maixcdk maix.touchscreen.TouchScreen.read
|
||||
* @maixcdk maix.touchscreen.TouchScreen.read0
|
||||
*/
|
||||
err::Err read0(int &x, int &y, bool &pressed);
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace maix::touchscreen
|
||||
* @attention This method will return immediately if have event, so it's better to use available() to check if have more event in buffer,
|
||||
* or too much event in buffer when your program call this read() interval is too long will make your program slow.
|
||||
* @return Returns a list include x, y, pressed state
|
||||
* @maixpy maix.touchscreen.TouchScreen.read
|
||||
* @maixpy maix.touchscreen.TouchScreen.read0
|
||||
*/
|
||||
std::vector<int> read0();
|
||||
|
||||
|
||||
@@ -879,21 +879,21 @@ namespace maix::video
|
||||
/**
|
||||
* @brief Get sample rate of audio (only valid in the context of audio)
|
||||
* @return sample rate
|
||||
* @maixpy maix.video.Context.audio_sample_rate
|
||||
* @maixpy maix.video.Decoder.audio_sample_rate
|
||||
*/
|
||||
int audio_sample_rate() { return _audio_sample_rate; }
|
||||
|
||||
/**
|
||||
* @brief Get channels of audio (only valid in the context of audio)
|
||||
* @return channels
|
||||
* @maixpy maix.video.Context.audio_channels
|
||||
* @maixpy maix.video.Decoder.audio_channels
|
||||
*/
|
||||
int audio_channels() { return _audio_channels; }
|
||||
|
||||
/**
|
||||
* @brief Get format of audio (only valid in the context of audio)
|
||||
* @return audio format. @see audio::Format
|
||||
* @maixpy maix.video.Context.audio_format
|
||||
* @maixpy maix.video.Decoder.audio_format
|
||||
*/
|
||||
audio::Format audio_format() { return _audio_format; }
|
||||
|
||||
|
||||
@@ -70,8 +70,12 @@ def get_code_def(code):
|
||||
# std::string hello = "hello"
|
||||
# func definition:
|
||||
# std::map<std::string, int> get_dict(std::map<std::string, int> in, int i, const char *j = "10")
|
||||
# Bytes &operator=(const Bytes &other)
|
||||
idx = code.find(";")
|
||||
idx3 = code.find("=")
|
||||
if code.find("operator") >= 0:
|
||||
idx3 = -1
|
||||
else:
|
||||
idx3 = code.find("=")
|
||||
start_idx = code.find("(")
|
||||
sub_count = 1
|
||||
idx2 = -1
|
||||
@@ -163,10 +167,28 @@ def get_var_name_value(definition):
|
||||
if "=" in definition:
|
||||
name, value = definition.rsplit("=", 1)
|
||||
value = value.strip()
|
||||
elif "{" in definition:
|
||||
name, value = definition.rsplit("{", 1)
|
||||
value = "{" + value.strip()
|
||||
elif ";" in definition:
|
||||
name = definition.rsplit(";", 1)[0]
|
||||
value = None
|
||||
else:
|
||||
value = None
|
||||
name = definition.strip()
|
||||
name = name.rsplit(" ", 1)[1].strip()
|
||||
words = name.split()
|
||||
new_words = []
|
||||
for word in words:
|
||||
# remove word startswith const, static, volatile, mutable, __attribute__, __restrict, extern
|
||||
rms = ["const", "static", "volatile", "mutable", "__attribute__", "__restrict", "extern"]
|
||||
valid = True
|
||||
for rm in rms:
|
||||
if word.startswith(rm):
|
||||
valid = False
|
||||
break
|
||||
if valid:
|
||||
new_words.append(word)
|
||||
name = new_words[-1].strip()
|
||||
if name.startswith("&"):
|
||||
name = name.rsplit("&", 1)[1]
|
||||
elif name.startswith("*"):
|
||||
@@ -243,7 +265,7 @@ def get_func_def_info(code):
|
||||
func_name = re.findall(r"([\*&]*)([\S]+)", func_name)[0]
|
||||
return_type = (return_type + func_name[0]).strip()
|
||||
func_name = func_name[1]
|
||||
if return_type.startswith("static"):
|
||||
if return_type.startswith("static") or return_type.startswith("extern"):
|
||||
return_type = return_type.split(" ", 1)[1].strip()
|
||||
func_name = func_name.strip()
|
||||
except_pair = {
|
||||
@@ -386,11 +408,47 @@ def parse_api_item_info(item):
|
||||
raise Exception("parse_api_info key {} value error: {} => {}".format(api, item, kv_str))
|
||||
return api, info
|
||||
|
||||
def parse_api(code, apis, sdks = ["maixpy", "maixcdk"], header_name = None, module_name = "maix"):
|
||||
def parse_api(code, apis, sdks = ["maixpy", "maixcdk"], header_name = None, module_name = "maix", header_path = None):
|
||||
|
||||
# if not header_name.endswith("api_example.hpp"):
|
||||
# return apis, "", False, []
|
||||
|
||||
def parse_item_code_def(item):
|
||||
def_code = code[item["start_idx"]:]
|
||||
idx = def_code.find(api)
|
||||
idx = def_code.find("*/", idx) + 2
|
||||
idx = def_code.find("\n", idx) + 1
|
||||
item["type"], definition, (idx, idx2) = get_code_def(def_code[idx:])
|
||||
# parse args values flags etc.
|
||||
if item["type"] == "class":
|
||||
words = definition.split("\n")[0].split()
|
||||
if "class" in words:
|
||||
item["name"] = words[words.index("class") + 1].split(":")[0].split("{")[0]
|
||||
else:
|
||||
item["name"] = words[words.index("struct") + 1].split(":")[0].split("{")[0]
|
||||
elif item["type"] == "enum":
|
||||
item["values"] = get_enum_values(definition)
|
||||
words = definition.split("\n")[0].split()
|
||||
if "class" in words:
|
||||
item["name"] = words[words.index("class") + 1].split(":")[0].split("{")[0]
|
||||
else:
|
||||
item["name"] = words[words.index("enum") + 1].split(":")[0].split("{")[0]
|
||||
elif item["type"] == "func":
|
||||
item["type"] = "func"
|
||||
item["name"], item["args"], item["ret_type"] = get_func_def_info(definition)
|
||||
elif item["type"] == "var":
|
||||
item["name"], item["value"] = get_var_name_value(definition)
|
||||
if definition.startswith("const"):
|
||||
item["kv"]["readonly"] = True
|
||||
elif item["type"] == "module":
|
||||
item["name"] = definition.split()[1].split(":")[-1]
|
||||
else:
|
||||
raise Exception("item type no valid: {}, {}".format(item["type"], definition))
|
||||
if definition.startswith("static"):
|
||||
item["kv"]["static"] = True
|
||||
item["def_idx"] = [idx, idx2]
|
||||
item["def"] = definition
|
||||
|
||||
comments_parsed = find_comments(code)
|
||||
|
||||
# find all @maixpy items
|
||||
@@ -409,7 +467,17 @@ def parse_api(code, apis, sdks = ["maixpy", "maixcdk"], header_name = None, modu
|
||||
info["start_idx"] = comment["start_idx"]
|
||||
comment.pop("start_idx")
|
||||
if api in items:
|
||||
# return None, "parse_api error: API {} multiple defined, info: {}, another: {}".format(api, info, items[api]), False, []
|
||||
if ["maixpy"] == sdks: # only for maixpy, not allow overload
|
||||
try:
|
||||
parse_item_code_def(info)
|
||||
parse_item_code_def(items[api])
|
||||
def1 = info["def"]
|
||||
def2 = items[api]["def"]
|
||||
except Exception:
|
||||
def1 = ""
|
||||
def2 = ""
|
||||
return None, "parse_api error:\n\nAPI \033[1;31m {} \033[0m multiple defined !!!\n\n\033[1;31mOne\033[0m:\n \033[1;33m{}\033[0m\n brief: {}\n info: {},\n\n\033[1;31mAnother\033[0m:\n \033[1;33m{}\033[0m\n brief: {}\n info: {}\n".format(
|
||||
api, def1, info["doc"]["brief"], info, def2, items[api]["doc"]["brief"], items[api]), False, []
|
||||
print("-- API {} is overloaded".format(api))
|
||||
if not "overload" in items[api]:
|
||||
items[api]["overload"] = []
|
||||
@@ -459,36 +527,13 @@ def parse_api(code, apis, sdks = ["maixpy", "maixcdk"], header_name = None, modu
|
||||
},
|
||||
}
|
||||
'''
|
||||
def parse_item_code_def(item):
|
||||
def_code = code[item["start_idx"]:]
|
||||
idx = def_code.find(api)
|
||||
idx = def_code.find("*/", idx) + 2
|
||||
idx = def_code.find("\n", idx) + 1
|
||||
item["type"], definition, (idx, idx2) = get_code_def(def_code[idx:])
|
||||
# parse args values flags etc.
|
||||
if item["type"] == "class":
|
||||
item["name"] = definition.split()[1].split(":")[0] # class AA: B\n{}
|
||||
elif item["type"] == "enum":
|
||||
item["values"] = get_enum_values(definition)
|
||||
item["name"] = definition.split()[1] # enum AA\n{}
|
||||
elif item["type"] == "func":
|
||||
item["type"] = "func"
|
||||
item["name"], item["args"], item["ret_type"] = get_func_def_info(definition)
|
||||
elif item["type"] == "var":
|
||||
item["name"], item["value"] = get_var_name_value(definition)
|
||||
if definition.startswith("const"):
|
||||
item["kv"]["readonly"] = True
|
||||
elif item["type"] == "module":
|
||||
item["name"] = definition.split()[1]
|
||||
else:
|
||||
raise Exception("item type no valid: {}, {}".format(item["type"], definition))
|
||||
if definition.startswith("static"):
|
||||
item["kv"]["static"] = True
|
||||
item["def_idx"] = [idx, idx2]
|
||||
item["def"] = definition
|
||||
|
||||
for api, item in items.items():
|
||||
parse_item_code_def(item)
|
||||
py_name = api.split(".")[-1]
|
||||
if not py_name.startswith("__") and item["name"] != py_name:
|
||||
return None, "API name \033[1;31m{} \033[0m not match with code definition name \033[1;31m{}\033[0m, def: {}".format(
|
||||
api, item["name"], item["def"]), False, []
|
||||
for overload in item.get("overload", []):
|
||||
parse_item_code_def(overload)
|
||||
|
||||
@@ -566,6 +611,11 @@ def parse_api(code, apis, sdks = ["maixpy", "maixcdk"], header_name = None, modu
|
||||
parent = root
|
||||
for name in parents:
|
||||
parent = parent["members"][name]
|
||||
if api_name in parent["members"]:
|
||||
msg = "parse_api error: \033[1;31m{}\033[0m multiple define in different headers".format(api)
|
||||
if "header_path" in parent["members"][api_name]:
|
||||
msg += f": \033[1;31m{parent['members'][api_name]['header_path']}\033[0m and \033[1;31m{header_path}\033[0m"
|
||||
raise Exception(msg)
|
||||
return parent, api_name
|
||||
|
||||
for key in final_keys:
|
||||
@@ -604,7 +654,8 @@ def parse_api(code, apis, sdks = ["maixpy", "maixcdk"], header_name = None, modu
|
||||
"value": item["value"],
|
||||
"static": item["kv"].get("static", False),
|
||||
"readonly": item["kv"].get("readonly", False),
|
||||
"def": item["def"]
|
||||
"def": item["def"],
|
||||
"header_path": header_path
|
||||
}
|
||||
elif item["type"] == "class":
|
||||
parent, name = get_parent_node(apis, key)
|
||||
@@ -613,7 +664,8 @@ def parse_api(code, apis, sdks = ["maixpy", "maixcdk"], header_name = None, modu
|
||||
"name": item["name"],
|
||||
"doc": item["doc"],
|
||||
"members": {},
|
||||
"def": item["def"]
|
||||
"def": item["def"],
|
||||
"header_path": header_path
|
||||
}
|
||||
elif item["type"] == "func":
|
||||
parent, name = get_parent_node(apis, key)
|
||||
@@ -624,7 +676,8 @@ def parse_api(code, apis, sdks = ["maixpy", "maixcdk"], header_name = None, modu
|
||||
"args": item["args"], # [["const char *", "i", None], ["int", "j", "10"]]
|
||||
"ret_type": item["ret_type"],
|
||||
"static": item["kv"].get("static", False),
|
||||
"def": item["def"]
|
||||
"def": item["def"],
|
||||
"header_path": header_path
|
||||
}
|
||||
# overload method
|
||||
if "overload" in item:
|
||||
@@ -637,7 +690,8 @@ def parse_api(code, apis, sdks = ["maixpy", "maixcdk"], header_name = None, modu
|
||||
"args": overload["args"], # [["const char *", "i", None], ["int", "j", "10"]]
|
||||
"ret_type": overload["ret_type"],
|
||||
"static": overload["kv"].get("static", False),
|
||||
"def": overload["def"]
|
||||
"def": overload["def"],
|
||||
"header_path": header_path
|
||||
})
|
||||
elif item["type"] == "enum":
|
||||
parent, name = get_parent_node(apis, key)
|
||||
@@ -646,7 +700,8 @@ def parse_api(code, apis, sdks = ["maixpy", "maixcdk"], header_name = None, modu
|
||||
"name": item["name"],
|
||||
"doc": item["doc"],
|
||||
"values": item["values"], # [("KIND_DOG", "0"), ("KIND_CAT", None)]
|
||||
"def": item["def"]
|
||||
"def": item["def"],
|
||||
"header_path": header_path
|
||||
}
|
||||
else:
|
||||
return None, "parse_api error: {} not support when generate tree".format(item["type"]), False, []
|
||||
@@ -657,13 +712,13 @@ def parse_api_from_header(header_path, api_tree = {}, sdks = ["maixpy"], module_
|
||||
with open(header_path, "r", encoding="utf-8") as f:
|
||||
code = f.read()
|
||||
try:
|
||||
api_tree, msg, updated, keys = parse_api(code, api_tree, sdks, os.path.basename(header_path), module_name)
|
||||
if api_tree is None:
|
||||
raise Exception("parse_api_from_header {} error: {}".format(header_path, msg))
|
||||
api_tree, msg, updated, keys = parse_api(code, api_tree, sdks, os.path.basename(header_path), module_name, header_path=header_path)
|
||||
except Exception as e:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
raise Exception("parse_api_from_header {} error: {}".format(header_path, e))
|
||||
raise Exception("\n\nparse_api_from_header \033[1;31m {} \033[0m error:\n{}".format(header_path, e))
|
||||
if api_tree is None:
|
||||
raise Exception("\n\nparse_api_from_header \033[1;31m {} \033[0m error:\n{}".format(header_path, msg))
|
||||
return api_tree, updated, keys
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user