VLAdaptorBench / external /pyrep /tools /generate_simConst.py
lsnu's picture
Add files using upload-large-folder tool
cf8614b verified
#!/usr/bin/env python
'''Generate simConst.py from simConst.h distributed from CoppeliaSim
$ ./generate_simConst.py > ../pyrep/backend/simConst.py
'''
import contextlib
import importlib
import os
import os.path as osp
import re
import shlex
import shutil
import subprocess
import sys
import tempfile
try:
import CppHeaderParser
except ImportError:
print('Please run following:\n\tpip install CppHeaderParser',
file=sys.stderr)
sys.exit(1)
def get_coppeliasim_root():
if 'COPPELIASIM_ROOT' not in os.environ:
raise RuntimeError('Please set env COPPELIASIM_ROOT')
return os.environ['COPPELIASIM_ROOT']
def import_as(filename, module):
spec = importlib.util.spec_from_file_location(
module, filename
)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
def generate_simConst_py():
header_file = osp.join(
get_coppeliasim_root(), 'programming/include/simConst.h'
)
with contextlib.redirect_stdout(sys.stderr):
header = CppHeaderParser.CppHeader(header_file)
assert header.classes == {}
assert header.functions == []
assert header.global_enums == {}
names = []
for define in header.defines:
m = re.match('^(.*)/\*.*\*/', define)
if m:
define = m.groups()[0]
splits = define.split()
if len(splits) == 2:
name, _ = splits
if name in ['SIM_PROGRAM_VERSION']:
continue
names.append(name)
for enum in header.enums:
assert enum['namespace'] == ''
for value in enum['values']:
names.append(value['name'])
names.append('')
out_dir = tempfile.mkdtemp()
cpp_file = osp.join(out_dir, 'generate_simConst_py.cpp')
with open(cpp_file, 'w') as f:
f.write('#include <iostream>\n')
f.write('#include <simConst.h>\n')
f.write('int main() {\n')
for name in names:
if name:
f.write(
f'\tstd::cout << "{name} = " << {name} << std::endl;\n'
)
else:
f.write('\tstd::cout << std::endl;\n')
f.write('}\n')
out_file = osp.join(out_dir, 'generate_simConst_py')
cmd = f'g++ {cpp_file} -o {out_file} -I{osp.dirname(header_file)}'
subprocess.check_call(shlex.split(cmd))
cmd = osp.join(out_dir, 'generate_simConst_py')
code = subprocess.check_output(cmd).strip().decode()
shutil.rmtree(out_dir)
return code
def merge_simConst_py(code):
official_file = osp.join(
get_coppeliasim_root(),
'programming/remoteApiBindings/python/python/simConst.py')
official = import_as(official_file, 'official')
out_dir = tempfile.mkdtemp()
generated_file = osp.join(out_dir, 'simConst_generated.py')
with open(generated_file, 'w') as f:
f.write(code)
generated = import_as(generated_file, 'generated')
name_and_value = []
for name in dir(official):
if re.match('__.*__', name):
continue
if name in dir(generated):
value_official = getattr(official, name)
value_generated = getattr(generated, name)
if value_official != value_generated:
print(f"WARNING: The values of var '{name}' is not equal: "
f'official={value_official}, '
f'generated={value_generated}', file=sys.stderr)
else:
name_and_value.append((name, getattr(official, name)))
code = ('# This file is automatically generated by '
f'{osp.basename(__file__)} from simConst.h\n\n' + code)
code += ('\n\n# Followings are copied from official simConst.py '
'(so possibly deprecated in C++ API)')
for name, value in name_and_value:
code += f'\n{name} = {value}'
code += '\n'
return code
def main():
code = generate_simConst_py()
code = merge_simConst_py(code)
print(code, end='')
if __name__ == '__main__':
main()