aboutsummaryrefslogtreecommitdiff
path: root/tools/bindings_generator.py
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2011-07-13 20:54:37 -0700
committerAlon Zakai <alonzakai@gmail.com>2011-07-13 20:54:37 -0700
commit8672034800dc463c5f5bffa95b3de9963e161788 (patch)
tree7ee9430db2d419910b10a6ab46f792dfa0459f62 /tools/bindings_generator.py
parentefbf009d0d40443c74cdef9c47e1e54206629e8d (diff)
bindings fixes
Diffstat (limited to 'tools/bindings_generator.py')
-rwxr-xr-xtools/bindings_generator.py70
1 files changed, 51 insertions, 19 deletions
diff --git a/tools/bindings_generator.py b/tools/bindings_generator.py
index ac8ddbc5..223b2720 100755
--- a/tools/bindings_generator.py
+++ b/tools/bindings_generator.py
@@ -4,7 +4,7 @@
Use CppHeaderParser to parse some C++ headers, and generate binding code for them.
Usage:
- bindings_generator.py BASENAME HEADER1 HEADER2 ... [-- "LAMBDA"]
+ bindings_generator.py BASENAME HEADER1 HEADER2 ... [-- "LAMBDA" ["IGNORED"]]
BASENAME is the name used for output files (with added suffixes).
HEADER1 etc. are the C++ headers to parse
@@ -22,6 +22,9 @@ We generate the following:
* LAMBDA: Optionally, provide the text of a lambda function here that will be
used to process the header files. This lets you manually tweak them.
+ * IGNORED: Optionally, a list of classes and class::methods not to generate code for.
+ Comma separated.
+
The C bindings file is basically a tiny C wrapper around the C++ code.
It's only purpose is to make it easy to access the C++ code in the JS
bindings, and to prevent DFE from removing the code we care about. The
@@ -45,9 +48,13 @@ import CppHeaderParser
basename = sys.argv[1]
processor = lambda line: line
+ignored = []
+
if '--' in sys.argv:
index = sys.argv.index('--')
processor = eval(sys.argv[index+1])
+ if len(sys.argv) > index+2:
+ ignored = sys.argv[index+2].split(',')
sys.argv = sys.argv[:index]
# First pass - read everything
@@ -68,7 +75,7 @@ parsed = CppHeaderParser.CppHeader(all_h_name)
for cname, clazz in parsed.classes.iteritems():
#print 'zz see', cname
if len(clazz['methods']['public']) > 0: # Do not notice stub classes
- #print 'zz for real', cname, clazz._public_structs
+ #print 'zz for real', cname, clazz, dir(clazz)
classes[cname] = clazz
for sname, struct in clazz._public_structs.iteritems():
struct_parents[sname] = cname
@@ -87,11 +94,15 @@ gen_c.write('extern "C" {\n')
def generate_class(generating_cname, cname, clazz):
inherited = generating_cname != cname
+ # Nothing to generate for pure virtual classes
+ if len(clazz.get_all_pure_virtual_methods().keys()) > 0: return
for method in clazz['methods']['public']:
- if method['pure_virtual']: return # Nothing to generate for pure virtual classes
+ if method['pure_virtual']: return
for method in clazz['methods']['public']:
mname = method['name']
+ if cname + '::' + mname in ignored: continue
+
args = method['parameters']
constructor = mname == cname
destructor = method['destructor']
@@ -130,39 +141,58 @@ def generate_class(generating_cname, cname, clazz):
ret = ((cname + ' *') if constructor else method['rtnType']).replace('virtual ', '')
callprefix = 'new ' if constructor else 'self->'
- typedargs = ', '.join( ([] if constructor else [cname + ' * self']) + map(lambda arg: arg['type'] + ' ' + arg['name'], args) )
- justargs = ', '.join(map(lambda arg: arg['name'], args))
- fullname = 'emscripten_bind_' + generating_cname + '__' + mname
- generating_cname_suffixed = generating_cname
- mname_suffixed = mname
- count = funcs.setdefault(fullname, 0)
- funcs[fullname] += 1
-
- # handle overloading
- if count > 0:
- suffix = '_' + str(count+1)
- funcs[fullname + suffix] = fullname # this should never change
- fullname += suffix
- mname_suffixed += suffix
- if constructor:
- generating_cname_suffixed += suffix
actualmname = ''
if mname == '__operator___assignment_':
callprefix = '*self = '
continue # TODO
+ elif mname == '__operator____mul__':
+ callprefix = '*self * '
+ continue # TODO
+ elif mname == '__operator____div__':
+ callprefix = '*self + '
+ continue # TODO
+ elif mname == '__operator____add__':
+ callprefix = '*self + '
+ continue # TODO
+ elif mname == '__operator____sub__':
+ callprefix = '*self - '
+ continue # TODO
elif mname == '__operator____imult__':
callprefix = '*self * '
continue # TODO
+ elif mname == '__operator____idiv__':
+ callprefix = '*self + '
+ continue # TODO
elif mname == '__operator____iadd__':
callprefix = '*self + '
continue # TODO
elif mname == '__operator____isub__':
callprefix = '*self - '
continue # TODO
+ elif mname == '__operator____eq__':
+ callprefix = '*self - '
+ continue # TODO
else:
actualmname = mname
+ typedargs = ', '.join( ([] if constructor else [cname + ' * self']) + map(lambda arg: arg['type'] + ' ' + arg['name'], args) )
+ justargs = ', '.join(map(lambda arg: arg['name'], args))
+ fullname = 'emscripten_bind_' + generating_cname + '__' + mname
+ generating_cname_suffixed = generating_cname
+ mname_suffixed = mname
+ count = funcs.setdefault(fullname, 0)
+ funcs[fullname] += 1
+
+ # handle overloading
+ if count > 0:
+ suffix = '_' + str(count+1)
+ funcs[fullname + suffix] = fullname # this should never change
+ fullname += suffix
+ mname_suffixed += suffix
+ if constructor:
+ generating_cname_suffixed += suffix
+
gen_c.write('''
%s %s(%s) {
%s%s%s(%s);
@@ -194,6 +224,8 @@ function %s(%s) {
''' % (generating_cname, mname_suffixed, justargs, 'return ' if ret != 'void' else '', fullname, (', ' if len(justargs) > 0 else '') + justargs))
for cname, clazz in classes.iteritems():
+ if cname in ignored: continue
+
generate_class(cname, cname, clazz)
# In addition, generate all methods of parent classes. We do not inherit in JS (how would we do multiple inheritance etc.?)