diff --git a/components/3rd_party/zbar/CMakeLists.txt b/components/3rd_party/zbar/CMakeLists.txt index 2325ee63..dc8fe537 100644 --- a/components/3rd_party/zbar/CMakeLists.txt +++ b/components/3rd_party/zbar/CMakeLists.txt @@ -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 diff --git a/components/basic/include/maix_tensor.hpp b/components/basic/include/maix_tensor.hpp index f9c3ab1a..f221f7a2 100644 --- a/components/basic/include/maix_tensor.hpp +++ b/components/basic/include/maix_tensor.hpp @@ -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) { diff --git a/components/basic/include/maix_time.hpp b/components/basic/include/maix_time.hpp index 5471d12d..630dc29e 100644 --- a/components/basic/include/maix_time.hpp +++ b/components/basic/include/maix_time.hpp @@ -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 timezone2(const std::string ®ion = "", const std::string &city = ""); diff --git a/components/ext_dev/include/maix_pmu.hpp b/components/ext_dev/include/maix_pmu.hpp index 0fad71f6..8694e615 100644 --- a/components/ext_dev/include/maix_pmu.hpp +++ b/components/ext_dev/include/maix_pmu.hpp @@ -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(); diff --git a/components/nn/include/maix_nn_face_recognizer.hpp b/components/nn/include/maix_nn_face_recognizer.hpp index bd237ba1..2c851adb 100644 --- a/components/nn/include/maix_nn_face_recognizer.hpp +++ b/components/nn/include/maix_nn_face_recognizer.hpp @@ -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) { diff --git a/components/nn/include/maix_nn_object.hpp b/components/nn/include/maix_nn_object.hpp index e3c0a2b5..0303c37f 100644 --- a/components/nn/include/maix_nn_object.hpp +++ b/components/nn/include/maix_nn_object.hpp @@ -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) { diff --git a/components/nn/include/maix_nn_ocr_object.hpp b/components/nn/include/maix_nn_ocr_object.hpp index e9f39664..fc5c9c4b 100644 --- a/components/nn/include/maix_nn_ocr_object.hpp +++ b/components/nn/include/maix_nn_ocr_object.hpp @@ -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) { diff --git a/components/vision/include/maix_image.hpp b/components/vision/include/maix_image.hpp index fcfa801e..540fe65c 100644 --- a/components/vision/include/maix_image.hpp +++ b/components/vision/include/maix_image.hpp @@ -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 src_points, std::vector 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 resize_map_pos(int w_out, int h_out, image::Fit fit, int x, int y, int w = -1, int h = -1) { diff --git a/components/vision/include/maix_image_def.hpp b/components/vision/include/maix_image_def.hpp index 696f7880..26feb9a0 100644 --- a/components/vision/include/maix_image_def.hpp +++ b/components/vision/include/maix_image_def.hpp @@ -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) { diff --git a/components/vision/include/maix_image_obj.hpp b/components/vision/include/maix_image_obj.hpp index 0afdd261..6cd443f0 100644 --- a/components/vision/include/maix_image_obj.hpp +++ b/components/vision/include/maix_image_obj.hpp @@ -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 lines, std::vector>> points = std::vector>>()) { _id = id; diff --git a/components/vision/include/maix_jpg_stream.hpp b/components/vision/include/maix_jpg_stream.hpp index 58ffcd77..a2a3f439 100644 --- a/components/vision/include/maix_jpg_stream.hpp +++ b/components/vision/include/maix_jpg_stream.hpp @@ -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(); diff --git a/components/vision/include/maix_rtmp.hpp b/components/vision/include/maix_rtmp.hpp index 27bea560..8e72322b 100644 --- a/components/vision/include/maix_rtmp.hpp +++ b/components/vision/include/maix_rtmp.hpp @@ -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; diff --git a/components/vision/include/maix_rtsp.hpp b/components/vision/include/maix_rtsp.hpp index 29e52406..1b8fa37c 100644 --- a/components/vision/include/maix_rtsp.hpp +++ b/components/vision/include/maix_rtsp.hpp @@ -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(); diff --git a/components/vision/include/maix_touchscreen.hpp b/components/vision/include/maix_touchscreen.hpp index 544aa6ff..de0578a4 100644 --- a/components/vision/include/maix_touchscreen.hpp +++ b/components/vision/include/maix_touchscreen.hpp @@ -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 read0(); diff --git a/components/vision/include/maix_video.hpp b/components/vision/include/maix_video.hpp index b73fe296..73f05122 100644 --- a/components/vision/include/maix_video.hpp +++ b/components/vision/include/maix_video.hpp @@ -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; } diff --git a/tools/doc_tool/gen_api.py b/tools/doc_tool/gen_api.py index 83e5ac51..fe13d017 100644 --- a/tools/doc_tool/gen_api.py +++ b/tools/doc_tool/gen_api.py @@ -70,8 +70,12 @@ def get_code_def(code): # std::string hello = "hello" # func definition: # std::map get_dict(std::map 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