def get_funcs()

in scripts/gen_wrappers.py [0:0]


def get_funcs(fname):
    src = subprocess.check_output([c_compiler, '-E', '-P', fname]).decode()
    src = src[src.find("int mj_activat"):]
    l = -1

    while l != len(src):
        l = len(src)
        src = src.replace("  ", " ")
        src = src.replace("\t", " ")
        src = src.replace("\n", " ")
        src = src.replace("const ", "")
        src = src.replace(", ", ",")
        src = src.strip()

    funcs = src.split(";")
    funcs = [f.strip() for f in funcs if len(f) > 0]
    ret = ""
    count = 0

    for f in funcs:
        ret_name = f.split(" ")[0]
        func_name = f.split(" ")[1].split("(")[0]

        args = f.split("(")[1][:-1]
        skip = False

        py_args_string = []
        c_args_string = []

        if args != "void":
            args = args.split(",")

            for arg in args:
                arg = arg.strip()
                data_type = " ".join(arg.split(" ")[:-1])
                var_name = arg.split(" ")[-1]

                if var_name.find("[") > -1:
                    #arr_size = var_name[var_name.find("[") + 1:var_name.find("]")]
                    data_type = data_type + "*"
                    var_name = var_name[:var_name.find("[")]

                # Some words are keywords in Python that are not keywords in C/C++, therefore they can be used as
                # variable identifiers. We need to handle these situations.
                if var_name in ['def']:
                    var_name = '_' + var_name

                if data_type in ["char*"]:
                    py_args_string.append("str " + var_name)
                    c_args_string.append(var_name + ".encode()")
                    continue
                if data_type in ["unsigned char"]:
                    skip = True
                    break
                if data_type == "mjtNum":
                    py_args_string.append("float " + var_name)
                    c_args_string.append(var_name)
                    continue
                if data_type == "mjtNum*":
                    py_args_string.append(
                        "np.ndarray[np.float64_t, mode=\"c\", ndim=1] " + var_name)
                    c_args_string.append("&%s[0]" % var_name)
                    continue
                if data_type == "mjtByte":
                    py_args_string.append("int " + var_name)
                    c_args_string.append(var_name)
                    continue
                if data_type == "mjtByte*":
                    py_args_string.append(
                        "np.ndarray[np.uint8_t, mode=\"c\", ndim=1] " + var_name)
                    c_args_string.append("&%s[0]" % var_name)
                    continue
                if data_type[:2] == "mj" and data_type[-1] == "*":
                    py_args_string.append(
                        "PyMj" + data_type[2:-1] + " " + var_name)
                    c_args_string.append(var_name + ".ptr")
                    continue
                if data_type[:2] == 'mj' and '*' not in data_type:
                    py_args_string.append(
                        "PyMj" + data_type[2:] + " " + var_name)
                    c_args_string.append(var_name + ".ptr[0]")  # dereference
                    continue
                if data_type in "int":
                    py_args_string.append("int " + var_name)
                    c_args_string.append(var_name)
                    continue
                if data_type in "int*":
                    py_args_string.append("uintptr_t " + var_name)
                    c_args_string.append("<int*>" + var_name)
                    continue

                # XXX
                skip = True

        if not skip and ((ret_name in ["int", "mjtNum", "void"]) or
                         (ret_name[:2] == "mj" and ret_name[-1] == "*") and ret_name != "mjtNum*" and ret_name != "mjData*"):

            code = "def _%s(%s):\n" % (func_name, ", ".join(py_args_string))
            ret_val = "%s(%s)" % (func_name, ", ".join(c_args_string))
            code += "    "
            if ret_name in ["int", "mjtNum"]:
                code += "return " + ret_val
            elif ret_name == "void":
                code += ret_val
            elif ret_name[:2] == "mj":
                code += "return WrapMj" + ret_name[2:-1] + "(" + ret_val + ")"
            else:
                import ipdb
                ipdb.set_trace()
            ret += code + "\n\n"
            count += 1

    print(ret)
    print("Generated %d out of %d" % (count, len(funcs)))
    return ret