gen_beef.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #!/usr/bin/env python3
  2. """ SoLoud Beef (bf) wrapper generator """
  3. import soloud_codegen
  4. fo = open("../glue/soloud.bf", "w")
  5. C_TO_BF_TYPES = {
  6. "string":"String",
  7. "int":"int32",
  8. "void":"void",
  9. "const char *":"char8 *",
  10. "char *":"char8 *",
  11. "unsigned int":"uint32",
  12. "float":"float",
  13. "double":"double",
  14. "float *":"float *",
  15. "File *":"void *",
  16. "unsigned char *":"uint8 *",
  17. "const unsigned char *":"uint8 *",
  18. "unsigned char":"uint8",
  19. "short *":"uint16 *"
  20. }
  21. for soloud_type in soloud_codegen.soloud_type:
  22. C_TO_BF_TYPES[soloud_type + " *"] = "SoloudObject"
  23. def has_ex_variant(funcname):
  24. """ Checks if this function has an "Ex" variant """
  25. if funcname[-2::] == "Ex":
  26. # Already an Ex..
  27. return False
  28. for func in soloud_codegen.soloud_func:
  29. if func[1] == (funcname + "Ex"):
  30. return True
  31. return False
  32. fo.write("""
  33. // SoLoud wrapper for Beef (bf)
  34. // This file is autogenerated; any changes will be overwritten
  35. using System;
  36. namespace SoLoud
  37. {
  38. public class SoloudObject
  39. {
  40. public void* objhandle;
  41. }
  42. """)
  43. fo.write("\n")
  44. #################################################################
  45. def fix_default_param(defparam, classname):
  46. """ 'fixes' default parameters from C to what python expectes """
  47. if defparam == "false":
  48. return "0"
  49. if defparam == "true":
  50. return "1"
  51. if (classname + '::') == defparam[0:len(classname)+2:]:
  52. return defparam[len(classname)+2::]
  53. if 'Soloud::' in defparam:
  54. return "Soloud." + defparam[len("Soloud")+2::]
  55. return defparam
  56. def external_pointer_fix(param):
  57. if param == "SoloudObject":
  58. return "void *"
  59. if param == "string":
  60. return "char8 *"
  61. return param
  62. for x in soloud_codegen.soloud_type:
  63. first = True
  64. for y in soloud_codegen.soloud_func:
  65. if (x + "_") == y[1][0:len(x)+1:]:
  66. if first:
  67. fo.write('\n')
  68. fo.write('public class %s : SoloudObject\n{\n'%(x))
  69. for z in soloud_codegen.soloud_enum:
  70. if z[0:len(x)+1] == x.upper()+'_':
  71. s = str(soloud_codegen.soloud_enum[z])
  72. fo.write('\tpublic const int %s = %s;\n'%(z[len(x)+1::], s))
  73. fo.write('\n\t[LinkName(\"%s_create\")]\n\tprivate static extern void* create();\n'%(x))
  74. fo.write('\tpublic this()\n\t{\n')
  75. fo.write('\t\tobjhandle = create();\n')
  76. fo.write('\t}\n')
  77. fo.write('\n\t[LinkName(\"%s_destroy\")]\n\tprivate static extern void* destroy(void* aObjHandle);\n'%(x))
  78. fo.write('\tpublic ~this()\n\t{\n')
  79. fo.write('\t\tdestroy(objhandle);\n')
  80. fo.write('\t}\n')
  81. first = False
  82. funcname = y[1][len(x)+1::]
  83. # If the function has the name "Ex", remove the subfix
  84. if funcname[-2::] == "Ex":
  85. funcname = funcname[:len(funcname)-2]
  86. # Skip generating functions that have an Ex variant
  87. if funcname == "create" or funcname == "destroy" or has_ex_variant(y[1]):
  88. pass # omit create/destroy, handled by __exit__ / close
  89. else:
  90. charptr = False
  91. floatptr = False
  92. ret = C_TO_BF_TYPES[y[0]]
  93. if y[0] == 'const char *':
  94. charptr = True
  95. ret = 'char8 *'
  96. if y[0] == 'const unsigned char *':
  97. charptr = True
  98. ret = 'uint8 *'
  99. if y[0] == 'float *':
  100. floatptr = True
  101. ret = 'float *'
  102. fo.write('\n\t[CLink]\n\tprivate static extern %s %s(void* aObjHandle'%(ret, y[1]))
  103. for z in y[2]:
  104. if len(z) > 1:
  105. if z[1] == 'a'+x:
  106. pass # skip the 'self' pointer
  107. else:
  108. fo.write(', ')
  109. fo.write(external_pointer_fix(C_TO_BF_TYPES[z[0]]) + ' ' + z[1])
  110. fo.write(');\n')
  111. fo.write('\tpublic %s %s('%(C_TO_BF_TYPES[y[0]], funcname))
  112. firstparm = True
  113. for z in y[2]:
  114. if len(z) > 1:
  115. if z[1] == 'a'+x:
  116. pass # skip the 'self' pointer
  117. else:
  118. if firstparm:
  119. firstparm = False
  120. else:
  121. fo.write(', ')
  122. fo.write(C_TO_BF_TYPES[z[0]] + ' ' + z[1])
  123. if len(z) > 2:
  124. fo.write(' = ' + fix_default_param(z[2], x))
  125. fo.write(')\n\t{\n')
  126. fo.write('\t\t')
  127. if y[0] == 'void':
  128. pass
  129. elif charptr:
  130. fo.write('return ')
  131. elif floatptr:
  132. fo.write('return ')
  133. else:
  134. fo.write('return ')
  135. fo.write(y[1] + '(objhandle')
  136. for z in y[2]:
  137. if len(z) > 1:
  138. if z[1] == 'a'+x:
  139. pass # skip the 'self' pointer
  140. else:
  141. fo.write(', ')
  142. fudged_type = C_TO_BF_TYPES[z[0]]
  143. if fudged_type == 'SoloudObject':
  144. fo.write(z[1] + '.objhandle')
  145. else:
  146. fo.write(z[1])
  147. fo.write(');\n')
  148. fo.write('\t}\n')
  149. if not first:
  150. fo.write('}\n')
  151. fo.write('}\n')
  152. print("soloud.bf generated")
  153. fo.close()