import soloud_codegen
fo = open("../glue/soloud.py", "w")
C_TO_PY_TYPES = {
"int":"ctypes.c_int",
"void":"None",
"const char *":"ctypes.c_char_p",
"char *":"ctypes.c_char_p",
"unsigned int":"ctypes.c_uint",
"float":"ctypes.c_float",
"double":"ctypes.c_double",
"float *":"ctypes.POINTER(ctypes.c_float * 256)",
"File *":"ctypes.c_void_p",
"unsigned char *":"ctypes.POINTER(ctypes.c_ubyte)",
"const unsigned char *":"ctypes.POINTER(ctypes.c_ubyte)",
"unsigned char":"ctypes.c_ubyte",
"short *":"ctypes.POINTER(ctypes.c_short)"
}
for soloud_type in soloud_codegen.soloud_type:
C_TO_PY_TYPES[soloud_type + " *"] = "ctypes.c_void_p"
def fudge_types(origtype):
return C_TO_PY_TYPES[origtype]
def pythonize_camelcase(origstr):
ret = ""
for letter in origstr:
if letter.isupper():
ret += '_' + letter.lower()
else:
ret += letter
ret = ret.replace("_f_f_t", "_fft")
ret = ret.replace("3d", "_3d")
return ret
def has_ex_variant(funcname):
if funcname[-2::] == "Ex":
return False
for func in soloud_codegen.soloud_func:
if func[1] == (funcname + "Ex"):
return True
return False
bootstrap = '''\
# SoLoud wrapper for Python
# This file is autogenerated; any changes will be overwritten
# See: http://sol.gfxile.net/soloud/codegen.html
import ctypes
import sys
import os
soloud_dll = None
try:
for filename in ['soloud_x86','soloud_x64','libsoloud_x64.so']:
try:
soloud_dll = ctypes.CDLL("%s/%s" %(os.path.dirname(os.path.abspath(__file__)), filename))
break
except FileNotFoundError:
# on windows, we get an explicit FileNotFoundError
continue
except OSError as e:
# but on linux, we don't
if 'No such file or directory' in str(e):
continue
else:
raise e
if soloud_dll == None:
raise Exception("SoLoud dynamic library not found in %s " % (os.path.dirname(os.path.abspath(__file__))))
except BaseException as e:
print("Error while loading Soloud dynamic library on %s %sbit" % (sys.platform, sys.maxsize.bit_length()+1))
print(e)
sys.exit()
'''
fo.write(bootstrap)
fo.write("\n")
fo.write("# Raw DLL functions\n")
for x in soloud_codegen.soloud_func:
fo.write(x[1] + ' = soloud_dll.' + x[1] + '\n')
fo.write(x[1] + '.restype = ' + fudge_types(x[0]) + '\n')
fo.write(x[1] + '.argtypes = [')
first = True
for y in x[2]:
if len(y) > 0:
if first:
first = False
else:
fo.write(", ")
fo.write(fudge_types(y[0]))
fo.write(']\n')
fo.write('\n')
fo.write('# OOP wrappers\n')
def fix_default_param(defparam, classname):
if defparam == 'false':
defparam = 'False'
if defparam == 'true':
defparam = 'True'
if (classname + '::') == defparam[0:len(classname)+2:]:
return defparam[len(classname)+2::]
elif defparam.startswith('Soloud::'):
return 'Soloud.%s'%(defparam[8:])
if defparam[len(defparam)-1] == "f":
return defparam[0:len(defparam)-1]
return defparam
for x in soloud_codegen.soloud_type:
first = True
for y in soloud_codegen.soloud_func:
if (x + "_") == y[1][0:len(x)+1:]:
if first:
fo.write('\n')
fo.write('class %s(object):\n'%(x))
for z in soloud_codegen.soloud_enum:
if z[0:len(x)+1] == x.upper()+'_':
s = str(soloud_codegen.soloud_enum[z])
fo.write('\t%s = %s\n'%(z[len(x)+1::], s))
fo.write('\tdef __init__(self):\n')
fo.write('\t\tself.objhandle = %s_create()\n'%(x))
fo.write('\tdef __enter__(self):\n')
fo.write('\t\treturn self\n')
fo.write('\tdef __exit__(self, eType, eValue, eTrace):\n')
fo.write('\t\t%s_destroy(self.objhandle)\n'%(x))
fo.write('\t\tself.objhandle = ctypes.c_void_p(0)\n')
fo.write('\t\treturn False\n')
fo.write('\tdef close(self):\n')
fo.write('\t\t%s_destroy(self.objhandle)\n'%(x))
fo.write('\t\tself.objhandle = ctypes.c_void_p(0)\n')
fo.write('\tdef destroy(self):\n')
fo.write('\t\t%s_destroy(self.objhandle)\n'%(x))
fo.write('\t\tself.objhandle = ctypes.c_void_p(0)\n')
fo.write('\tdef quit(self):\n')
fo.write('\t\t%s_destroy(self.objhandle)\n'%(x))
fo.write('\t\tself.objhandle = ctypes.c_void_p(0)\n')
first = False
funcname = y[1][len(x)+1::]
if funcname[-2::] == "Ex":
funcname = funcname[:len(funcname)-2]
if funcname == "create" or funcname == "destroy" or has_ex_variant(y[1]):
pass else:
fo.write('\tdef %s(self'%(pythonize_camelcase(funcname)))
for z in y[2]:
if len(z) > 1:
if z[1] == 'a'+x:
pass else:
fo.write(', ' + z[1])
if len(z) > 2:
fo.write(' = ' + fix_default_param(z[2], x))
fo.write('):\n')
fo.write('\t\t')
floatbufreturn = False
if y[0] == 'void':
pass
elif y[0] == 'float *':
floatbufreturn = True
fo.write('floatbuf = ')
else:
fo.write('return ')
fo.write(y[1] + '(self.objhandle')
for z in y[2]:
if len(z) > 1:
if z[1] == 'a'+x:
pass else:
fo.write(', ')
fudged_type = fudge_types(z[0])
if fudged_type == 'ctypes.c_void_p':
fo.write(z[1] + '.objhandle')
else:
if fudged_type == 'ctypes.c_char_p':
fo.write(fudged_type + '(' + z[1] + ".encode('utf-8'))")
else:
fo.write(fudged_type + '(' + z[1] + ')')
fo.write(')\n')
if floatbufreturn:
fo.write('\t\treturn [f for f in floatbuf.contents]\n')
print("soloud.py generated")
fo.close()