Skip to content

Instantly share code, notes, and snippets.

@holocronweaver
Forked from tunabrain/wrap_openvr.py
Created June 29, 2016 00:46
Show Gist options
  • Save holocronweaver/57cae5e6c6d4c93061112503f3905d8a to your computer and use it in GitHub Desktop.
Save holocronweaver/57cae5e6c6d4c93061112503f3905d8a to your computer and use it in GitHub Desktop.
#! python3
import shlex
import sys
import re
import io
header = open('openvr.h', newline='\n').read()
annoyingMacroPattern = re.compile(r'#define\s+(\w+).*VR_CLANG_ATTR.*')
fullClassPattern = re.compile(r'^([^\S\n]*)class\s+(\w+).*?\{.*?\};', re.MULTILINE | re.DOTALL)
virtualPattern = re.compile(r'([^\S\n]*)virtual\s(.*?)(\w+)(\((.+?,\s*)*.*?\s*\))\s*=\s*0\s*;[^\S\n]*', re.MULTILINE)
optionalParamPattern = re.compile(r'\s*=\s*[^,)]+')
versionPattern = re.compile(r'\s*static\s*const\s*char\s*\*\s*const\s*IVR\w+\s*=\s*\"IVR\w+\";')
annoyingMacros = [match.group(1) for match in annoyingMacroPattern.finditer(header)]
newHeader = header
for match in versionPattern.finditer(newHeader):
newHeader = newHeader.replace(match.group(0), match.group(0).replace('"IVR', '"FnTable:IVR'))
for match in fullClassPattern.finditer(header):
if match.group(0).find('virtual') == -1:
continue
fullClass = match.group(0)
indent = match.group(1)
className = match.group(2)
newClass = fullClass
declarations = []
for function in virtualPattern.finditer(fullClass):
returnType = function.group(2)
functionName = function.group(3)
params = function.group(4)
paramsNoDefault = re.sub(optionalParamPattern, '', params)
for macro in annoyingMacros:
paramsNoDefault = re.sub(macro + r'\(.*?\)', '', paramsNoDefault)
args = []
paramTokens = list(shlex.shlex(io.StringIO(paramsNoDefault)))
for i, token in enumerate(paramTokens):
if token == ',' or (token == ')' and paramTokens[i - 1] not in ['(', 'void']):
args.append(paramTokens[i - 1])
declaration = indent + '\t{}(__stdcall *{}){};'.format(returnType, functionName, paramsNoDefault)
definition = indent + '\t' + returnType + functionName + params + ' { '
if returnType.strip() != 'void':
definition = definition + 'return '
definition = definition + '_table.' + functionName + '(' + ', '.join(args) + '); }'
declarations.append(declaration)
newClass = newClass.replace(function.group(0), definition)
tableName = 'VR_{}_FnTable'.format(className)
table = indent + 'struct ' + tableName + '\n' + indent + '{\n' + '\n'.join(declarations) + '\n' + indent + '};\n\n'
newClass = newClass.replace('public:', '\t{} _table;\n{}public:'.format(tableName, indent))
newHeader = newHeader.replace(fullClass, table + newClass)
open('openvr_mingw.hpp', 'w', newline='\n').write(newHeader)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment