emscripten/tools/namespacer.py

96 строки
2.5 KiB
Python

#!/usr/bin/python2
'''
Tool that generates namespace boilerplate. Given
_mangled_name1_ = MyClass::MyClass()
_mangled_name2_ = MyClass::~MyClass()
_mangled_name3_ = MyClass::DoSomething(int)
the tool will generate
MyClass = {
'MyClass': _mangled_name1_,
'~MyClass': _mangled_name2_,
'DoSomething': _mangled_name3_
};
You can then do the following in JavaScript:
MyClass.MyClass(ptr);
MyClass['~MyClass'](ptr); // Need string here, due to |~|
MyClass.DoSomething(ptr, 17);
Note that you need to send the |this| pointer yourself. TODO:
a more OO boilerplate on top of that.
'''
import os, sys, json
js = open(sys.argv[1], 'r').read()
data = open(sys.argv[2], 'r').readlines()
space = {}
counts = {}
for line in data:
line = line.rstrip()
realname, signature = line.split(' = ')
signature = signature.replace(') const', ')')
signature = signature[:-1].split('(')
func, params = signature[0], '('.join(signature[1:])
if ' ' in func:
i = func.index(' ')
ret = func[:i]
if '<' not in ret and '[' not in ret and '(' not in ret:
func = func[i+1:]
#funcparts = ['Namespace'] + func.split('::')
funcparts = func.split('::')
currspace = space
for part in funcparts[:-1]:
currspace = currspace.setdefault(part, {})
finalname = funcparts[-1]
key = str(funcparts)
if key in counts:
i = counts[key]
counts[key] += 1
finalname += '_' + str(i)
else:
i = 0
counts[key] = 1
currspace[finalname] = realname
currspace[finalname + '__params'] = params
if len(funcparts) >= 2 and funcparts[-1] == funcparts[-2]:
found = False
for what in ['struct', 'class']:
size = '$%s_%s' % (what, '__'.join(funcparts[:-1]))
if len(funcparts) > 2:
size = '_' + size + '_'
size = size + '___SIZE'
if size in js:
found = True
break
if not found:
#print '// Warning: cannot find %s' % ('[_]$[class|struct]' + '__'.join(funcparts[:-1]) + '[_]___SIZE')
continue
currspace['__new__' + ('' if i == 0 else str(i))] = 'function() { var ret = _malloc(%s); Module._.%s.%s.apply(null, [ret].concat(Array.prototype.slice.apply(arguments))); return ret; }' % (
size, '.'.join(funcparts[:-1]), finalname
)
def finalize(line):
try:
key, val = line.split(': ')
assert val != '}' and '_params"' not in key
return key + ': ' + val.replace('"', '')
except:
return line
print 'var ModuleNames = ' + '\n'.join(map(finalize, json.dumps(space, sort_keys=True, indent=2).split('\n')))