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