Ejemplo n.º 1
0
    def get_fun_info(self, fun_name, swig_generated_param_names):
        fun_info = self.collected_info["funcs"].get(fun_name)
        if not fun_info:
            # def get_all_functions(xml_tree, name=None):
            fnodes = doxygen_utils.get_toplevel_functions(self.xml_tree, name=fun_name)
            nfnodes = len(fnodes)
            if nfnodes > 0:
                if nfnodes > 1:
                    print("Warning: more than 1 function doc found for '%s'; picking first" % fun_name)

                fd = fun_doc_t()
                fd.traverse(fnodes[0], swig_generated_param_names)
                if fd.is_valid():
                    fun_info = []
                    fd.append_lines(fun_info)
        return fun_info
Ejemplo n.º 2
0
parser.add_argument("-b", "--bc695", default=False, action="store_true")
parser.add_argument("-x", "--xml-doc-directory", required=True)
args = parser.parse_args()

this_dir, _ = os.path.split(__file__)
sys.path.append(this_dir)
import doxygen_utils

typemaps = []

# generate typemaps that will have to be injected for additional checks
xml_tree = doxygen_utils.load_xml_for_module(args.xml_doc_directory,
                                             args.module,
                                             or_dummy=False)
if xml_tree is not None:
    all_functions = doxygen_utils.get_toplevel_functions(xml_tree)
    for fun_node in all_functions:
        fun_name = doxygen_utils.get_single_child_element_text_contents(
            fun_node, "name")
        params = []

        def reg_param(*args):
            params.append(args)

        doxygen_utils.for_each_param(fun_node, reg_param)

        def relevant_and_non_null(ptyp, desc):
            if ptyp.strip().startswith("qstring"):
                return False
            return (desc or "").lower().find("not be null") > -1
Ejemplo n.º 3
0
parser.add_argument("-l", "--lifecycle-aware", default=False, action="store_true")
parser.add_argument("-v", "--verbose", default=False, action="store_true")
parser.add_argument("-b", "--bc695", default=False, action="store_true")
parser.add_argument("-x", "--xml-doc-directory", required=True)
args = parser.parse_args()

this_dir, _ = os.path.split(__file__)
sys.path.append(this_dir)
import doxygen_utils

typemaps = []

# generate typemaps that will have to be injected for additional checks
xml_tree = doxygen_utils.load_xml_for_module(args.xml_doc_directory, args.module, or_dummy=False)
if xml_tree is not None:
    all_functions = doxygen_utils.get_toplevel_functions(xml_tree)
    for fun_node in all_functions:
        fun_name = doxygen_utils.get_single_child_element_text_contents(fun_node, "name")
        params = []
        def reg_param(*args):
            params.append(args)
        doxygen_utils.for_each_param(fun_node, reg_param)
        def relevant_and_non_null(ptyp, desc):
            if ptyp.strip().startswith("qstring"):
                return False
            return (desc or "").lower().find("not be null") > -1

        for name, ptyp, desc in params:
            if relevant_and_non_null(ptyp, desc):
                # generate 'check' typemap
                signature = []
Ejemplo n.º 4
0
    def generate_function_pydoc(self, class_name=None):
        out = []
        line = self.copy(out)
        fun_name = get_fun_name(line)
        class_info = self.get_class_info(class_name) if class_name else None

        if args.debug_function:
            global selective_debug_status
            selective_debug_status = fun_name == args.debug_function

        #verb("generate_function_pydoc: fun_name: '%s'" % fun_name)
        line = self.copy(out)
        doc_start_line_idx = len(out)
        if line.find(DOCSTR_MARKER) > -1:
            # Opening docstring line; determine indentation level
            indent = get_indent_string(line)
            docstring_line_nr = 0
            while True:
                line = self.next()
                if docstring_line_nr == 0:
                    line = self.maybe_fix_swig_generated_docstring_prototype(
                        fun_name, line)

                if line.find(DOCSTR_MARKER) > -1:

                    # Closing docstring line
                    pydoc_lines = out[doc_start_line_idx:]
                    swig_generated_param_names = self.extract_swig_generated_param_names(
                        fun_name, pydoc_lines)

                    if class_name is None:
                        pywraps_fi = self.collected_pywraps_pydoc["funcs"].get(
                            fun_name)
                    else:
                        pywraps_fi = class_info["methods"].get(
                            fun_name) if class_info else []
                    if pywraps_fi:
                        # documentation coming from pywraps takes precedence.
                        dbg("'pywraps/'-originating comment takes precedence (%s)"
                            % str(pywraps_fi))
                        found = pywraps_fi
                        if pydoc_lines:
                            l0 = pydoc_lines[0].lstrip()
                            if l0.startswith(fun_name):
                                found = [l0] + found
                    else:
                        found = []
                        # no documentation coming from pywraps.
                        # Merge SWiG-generated documentation, and the
                        # SDK-provided bits
                        generated_fi = generated_func_info_t(pydoc_lines)
                        if generated_fi.original_comment:
                            dbg("SWiG-generated comment found (%s)" %
                                str(pydoc_lines))
                            found = pydoc_lines
                        else:
                            sdk_fi = SDK_func_info_t()
                            fnodes = []
                            if class_name is None:
                                fnodes = doxygen_utils.get_toplevel_functions(
                                    self.xml_tree, name=fun_name)
                            else:
                                if class_name.endswith("_Hooks"):
                                    enums = hooks_utils.get_hooks_enumerators(
                                        self.xml_dir, class_name)
                                    for enum in enums:
                                        if enum["name"] == fun_name:
                                            sdk_fi.import_from_hooks_enumerator(
                                                enum,
                                                swig_generated_param_names)
                                else:
                                    refid, udt_xml_tree = doxygen_utils.load_xml_for_udt(
                                        self.xml_dir,
                                        self.xml_tree,
                                        udt_name=class_name)
                                    if udt_xml_tree:
                                        fnodes = doxygen_utils.get_udt_methods(
                                            udt_xml_tree, refid, name=fun_name)

                            for fnode in fnodes:
                                sdk_fi.traverse(fnode,
                                                swig_generated_param_names)

                            if sdk_fi.brief:
                                found.extend(sdk_fi.brief)
                                found.append("")
                            if sdk_fi.detailed:
                                found.extend(sdk_fi.detailed)
                                found.append("")

                            # We'll look in all SDK signatures (i.e., we don't
                            # do proper signature matching) and patch all params
                            # in all generated signatures information. Hopefully
                            # this will be good enough.
                            for sdk_match in sdk_fi.matches:
                                for p in sdk_match.params:
                                    dbg("Handling param '%s'" % p)
                                    if p.name:
                                        pline = "@param %s" % p.name
                                        subsequent_indent = len(pline) + 2
                                        if p.desc:
                                            pline = "%s: %s" % (pline, p.desc)
                                        if p.ptyp:
                                            pline = "%s (C++: %s)" % (pline,
                                                                      p.ptyp)
                                        for sig in generated_fi.signatures:
                                            sig.replace_param(
                                                p.original_name, p.name, pline,
                                                subsequent_indent)
                                if sdk_match.returns:
                                    rline = "@return: %s" % sdk_match.returns.desc
                                    for sig in generated_fi.signatures:
                                        sig.append_return(
                                            rline, len("@return: "))
                                if sdk_match.retvals:
                                    for retval_value, retval_desc in sdk_match.retvals:
                                        rvline_pfx = "@retval: %s - " % retval_value
                                        rvline = "%s%s" % (rvline_pfx,
                                                           retval_desc)
                                        for sig in generated_fi.signatures:
                                            sig.append_retval(
                                                rvline, len(rvline_pfx))

                            # Append the (modified) signatures
                            for sig in generated_fi.signatures:
                                add_lines_block(found, sig.get_lines())

                    found = doxygen_utils.remove_empty_header_or_footer_lines(
                        found)
                    if found:
                        verb("fix_%s: found info for %s" %
                             ("method" if class_name else "fun", fun_name))
                        while len(out) > doc_start_line_idx:
                            out.pop()
                        add_lines_block(out, apply_indent(found, indent))

                    #
                    # apply possible additional patches
                    #
                    fun_patches = self.patches.get(fun_name, {})

                    example = fun_patches.get("+example", None)
                    if example:
                        ex_lines = list(
                            map(lambda l: "Python> %s" % l,
                                example.split("\n")))
                        out.extend(
                            list(
                                map(lambda l: indent + l,
                                    ["", "Example:"] + ex_lines)))

                    repl_text = fun_patches.get("repl_text", None)
                    if repl_text:
                        from_text, to_text = repl_text
                        for i in range(doc_start_line_idx, len(out)):
                            out[i] = out[i].replace(from_text, to_text)

                    out.append(line)
                    break
                else:
                    out.append(line)
                docstring_line_nr += 1
        return out