Commits

Leonard Ritter committed 8d3f870

refactored builder into autobuild-cffi

Comments (0)

Files changed (5)

predefs/sdl.pypredef

 def SDL_SetSurfaceRLE(*argv):
     """SDL_SetSurfaceRLE"""
 
+KMOD_LALT = int
 SDL_WINDOWEVENT_NONE = int
 SDL_HAT_CENTERED = int
 def SDL_UnionRect(*argv):
     """SDL_GetWindowData"""
 
 SDL_SCANCODE_KP_COLON = int
+KMOD_CAPS = int
 SDL_GL_STEREO = int
 SDL_WINDOW_INPUT_FOCUS = int
 SDL_SCANCODE_KP_HEXADECIMAL = int
 def SDL_GetWindowID(*argv):
     """SDL_GetWindowID"""
 
+KMOD_NUM = int
 SDL_SCANCODE_KP_4 = int
 SDL_SCANCODE_KP_5 = int
 def SDL_SetEventFilter(*argv):
 SDL_SCANCODE_KP_A = int
 SDL_SCANCODE_KP_B = int
 SDL_SCANCODE_KP_C = int
+KMOD_SHIFT = int
 SDL_GL_CONTEXT_PROFILE_MASK = int
 SDL_INPUTMOTION = int
 SDL_SCANCODE_SELECT = int
     """SDL_ShowWindow"""
 
 SDL_GL_CONTEXT_EGL = int
+KMOD_RESERVED = int
 def SDL_GetClipRect(*argv):
     """SDL_GetClipRect"""
 
     """SDL_WriteBE16"""
 
 SDL_SCANCODE_KP_MEMADD = int
+RW_SEEK_SET = int
 SDL_INIT_TIMER = int
 def SDL_ReadBE16(*argv):
     """SDL_ReadBE16"""
     """SDL_GetNumDisplayModes"""
 
 SDL_MULTIGESTURE = int
+KMOD_ALT = int
 SDL_SCANCODE_KP_ENTER = int
 def SDL_SaveDollarTemplate(*argv):
     """SDL_SaveDollarTemplate"""
     """SDL_GetRelativeMouseMode"""
 
 SDL_ALPHA_OPAQUE = int
+KMOD_NONE = int
 SDL_SCANCODE_SEPARATOR = int
 def SDL_GetSurfaceBlendMode(*argv):
     """SDL_GetSurfaceBlendMode"""
 def SDL_GL_SetSwapInterval(*argv):
     """SDL_GL_SetSwapInterval"""
 
+KMOD_RSHIFT = int
 SDL_SCANCODE_TAB = int
 def SDL_GetSurfaceColorMod(*argv):
     """SDL_GetSurfaceColorMod"""
 
 SDL_SCANCODE_MEDIASELECT = int
 SDL_WINDOWEVENT_FOCUS_GAINED = int
+KMOD_LGUI = int
 SDL_PRESSED = int
 def SDL_ConvertSurfaceFormat(*argv):
     """SDL_ConvertSurfaceFormat"""
     """SDL_GetDesktopDisplayMode"""
 
 SDL_GL_DEPTH_SIZE = int
+KMOD_MODE = int
 SDL_FINGERUP = int
 def SDL_FreeSurface(*argv):
     """SDL_FreeSurface"""
     """SDL_JoystickGetButton"""
 
 SDL_SCANCODE_KP_MEMSUBTRACT = int
+KMOD_RALT = int
 def SDL_WarpMouseInWindow(*argv):
     """SDL_WarpMouseInWindow"""
 
 def SDL_GL_GetProcAddress(*argv):
     """SDL_GL_GetProcAddress"""
 
+KMOD_LCTRL = int
 SDL_FIRSTEVENT = int
 SDL_SCANCODE_KP_MEMDIVIDE = int
 SDL_SCANCODE_MAIL = int
 def SDL_GL_MakeCurrent(*argv):
     """SDL_GL_MakeCurrent"""
 
+RW_SEEK_CUR = int
 SDL_BUTTON_X2MASK = int
 SDL_GL_BLUE_SIZE = int
 def SDL_SetWindowData(*argv):
 SDL_WINDOWEVENT_MINIMIZED = int
 SDL_SCANCODE_CUT = int
 SDL_HAT_LEFT = int
+KMOD_RGUI = int
 SDL_SCANCODE_INSERT = int
 SDL_SCANCODE_LCTRL = int
 SDL_SCANCODE_VOLUMEUP = int
 SDL_SCANCODE_F9 = int
 SDL_INPUTBUTTONDOWN = int
 SDL_RELEASED = int
+KMOD_LSHIFT = int
 SDL_HAT_LEFTUP = int
 def SDL_FilterEvents(*argv):
     """SDL_FilterEvents"""
 
 SDL_SCANCODE_EXECUTE = int
 SDL_HAT_LEFTDOWN = int
+SDLK_SCANCODE_MASK = int
 def SDL_WriteBE64(*argv):
     """SDL_WriteBE64"""
 
 def SDL_RaiseWindow(*argv):
     """SDL_RaiseWindow"""
 
+RW_SEEK_END = int
 SDL_WINDOWEVENT_RESIZED = int
 def SDL_JoystickName(*argv):
     """SDL_JoystickName"""
 
 SDL_SCANCODE_KP_DBLVERTICALBAR = int
 SDL_SCANCODE_RIGHT = int
+KMOD_GUI = int
 SDL_LASTERROR = int
 def SDL_Init(*argv):
     """SDL_Init"""
 def SDL_InitSubSystem(*argv):
     """SDL_InitSubSystem"""
 
+KMOD_CTRL = int
 def SDL_CreateColorCursor(*argv):
     """SDL_CreateColorCursor"""
 
 def SDL_GetFinger(*argv):
     """SDL_GetFinger"""
 
+KMOD_RCTRL = int
 SDL_ADDEVENT = int
 SDL_GL_CONTEXT_PROFILE_CORE = int
 SDL_SCANCODE_AUDIOSTOP = int
 # add wrapped functions
 _module_names = set(locals().keys())
 def get_mangled_names():
-    for name in SDL_UNMANGLED_EXPORTS:
+    for name in UNMANGLED_EXPORTS:
         mangled_name = name.lstrip('_')
         if mangled_name in _module_names:
             yield mangled_name
         else:
             yield name 
-__all__ = SDL_EXPORTS + list(get_mangled_names())
+__all__ = EXPORTS + list(get_mangled_names())
 del _module_names
 
-# this file is auto-generated by sdl.builder. do not edit.
+# this file is auto-generated. do not edit.
+from __future__ import (print_function, division, absolute_import)
+
 from cffi import FFI
 
-SDL_UNMANGLED_EXPORTS = [
+UNMANGLED_EXPORTS = [
 "_SDL_GetError",
 "_SDL_Init",
 "_SDL_PollEvent",
 
 ]
 
-SDL_EXPORTS = [
-'SDLError',
+EXPORTS = [
 "SDL_JoystickGetAxis",
 "SDL_SetWindowTitle",
 "SDL_SetSurfaceRLE",
 
 INTERNAL_EXPORTS = [
 '_ffi',
-'SDL_EXPORTS',
-'SDL_UNMANGLED_EXPORTS',
+'EXPORTS',
+'UNMANGLED_EXPORTS',
 ]
 
-__all__ = SDL_EXPORTS + SDL_UNMANGLED_EXPORTS + INTERNAL_EXPORTS
+__all__ = EXPORTS + UNMANGLED_EXPORTS + INTERNAL_EXPORTS
 
 from .internal import *
 
-_SDL = load_sdl("""
+_LIB = load_lib("""
 typedef enum
 {
 SDL_FALSE = 0,
 extern Uint32 SDL_WasInit(Uint32 flags);
 extern void SDL_Quit(void);
 
-""")   
+""")
 
 SDL_JoystickGetAxis = guard(lookup('SDL_JoystickGetAxis'))
 SDL_SetWindowTitle = guard(lookup('SDL_SetWindowTitle'))
 SDL_GetRGBA = guard(lookup('SDL_GetRGBA'))
 SDL_UnlockSurface = guard(lookup('SDL_UnlockSurface'))
 SDL_FlushEvents = guard(lookup('SDL_FlushEvents'))
-SDL_BlitSurface = 140088695350512
+SDL_BlitSurface = 140027187430640
 SDL_SCANCODE_KP_RIGHTBRACE = 185
 SDL_BLENDMODE_NONE = 0
 SDL_SetWindowFullscreen = guard(lookup('SDL_SetWindowFullscreen'))
 SDL_PeepEvents = guard(lookup('SDL_PeepEvents'))
 SDL_SCANCODE_KP_AMPERSAND = 199
 SDL_SCANCODE_UNDO = 122
-SDL_BlitScaled = 140088695351280
+SDL_BlitScaled = 140027187431408
 SDL_SCANCODE_SLEEP = 282
 SDL_SCANCODE_CRSEL = 163
 SDL_LASTEVENT = 65535
 SDL_SCANCODE_KP_EQUALSAS400 = 134
 SDL_WriteLE64 = guard(lookup('SDL_WriteLE64'))
 
+
+# code generator - only required at build time
 from __future__ import (print_function, division, absolute_import)
 
-# code generator
+import os
+from autobind import AutoBind
 
-import os
-import sys
-from tempfile import mktemp
-from subprocess import PIPE, Popen
-sys.path.insert(0, os.path.join(os.path.dirname(__file__),'..','..','cffi'))
-
-import re
-import traceback
-from cffi import FFI, CDefError
-from StringIO import StringIO
-from fnmatch import fnmatch
-
-#include "SDL_stdinc.h"
-#include "SDL_error.h"
-#include "SDL_video.h"
-#include "SDL_keyboard.h"
-#include "SDL_mouse.h"
-#include "SDL_joystick.h"
-#include "SDL_quit.h"
-#include "SDL_gesture.h"
-#include "SDL_touch.h"
-
-CDEF_FILES = [ 
-     'SDL_stdinc.h',
-     'SDL_blendmode.h',
-     'SDL_scancode.h',
-#    'SDL_config.h',
-     'SDL_pixels.h',
-     'SDL_rect.h',
-     'SDL_rwops.h',
-     'SDL_surface.h',
-     'SDL_keycode.h',
-     'SDL_error.h',
-#    'SDL_endian.h',
-#    'SDL_mutex.h',
-#    'SDL_thread.h',
-     'SDL_video.h',
-     'SDL_keyboard.h',
-     'SDL_mouse.h',
-     'SDL_joystick.h',
-     'SDL_quit.h',
-     'SDL_touch.h',
-     'SDL_gesture.h',
-#    'SDL_main.h',
-#    'SDL_assert.h',
-#    'SDL_atomic.h',
-#    'SDL_audio.h',
-#    'SDL_clipboard.h',
-#    'SDL_cpuinfo.h',
-     'SDL_events.h',
-#    'SDL_hints.h',
-#    'SDL_loadso.h',
-#    'SDL_log.h',
-#    'SDL_power.h',
-#    'SDL_render.h',
-#    'SDL_system.h',
-#    'SDL_timer.h',
-#    'SDL_version.h',
-    'SDL.h'
-]
-
-_DEFINES_BLACKLIST = set([
-])
-
-_DEFINES = set([
-])
-
-_PRIVATE_SYMBOLS = set([
-    'SDL_GetError',
-    'SDL_Init',
-    'SDL_PollEvent',
-])
-
-_AUTOCHECK_BLACKLIST = set([
-    'SDL_GetError',
-    'SDL_ClearError',
-    'SDL_Init',
-    'SDL_Quit',
-])
-
-_THISDIR = os.path.dirname(__file__)
+THISDIR = os.path.dirname(__file__)
+        
+autobind = AutoBind(options=dict(
+    CDEF_PATH = os.path.join(THISDIR, '..', 'sdl_defs'),
+    CDEF_FILES = [ 
+         'SDL_stdinc.h',
+         'SDL_blendmode.h',
+         'SDL_scancode.h',
+    #    'SDL_config.h',
+         'SDL_pixels.h',
+         'SDL_rect.h',
+         'SDL_rwops.h',
+         'SDL_surface.h',
+         'SDL_keycode.h',
+         'SDL_error.h',
+    #    'SDL_endian.h',
+    #    'SDL_mutex.h',
+    #    'SDL_thread.h',
+         'SDL_video.h',
+         'SDL_keyboard.h',
+         'SDL_mouse.h',
+         'SDL_joystick.h',
+         'SDL_quit.h',
+         'SDL_touch.h',
+         'SDL_gesture.h',
+    #    'SDL_main.h',
+    #    'SDL_assert.h',
+    #    'SDL_atomic.h',
+    #    'SDL_audio.h',
+    #    'SDL_clipboard.h',
+    #    'SDL_cpuinfo.h',
+         'SDL_events.h',
+    #    'SDL_hints.h',
+    #    'SDL_loadso.h',
+    #    'SDL_log.h',
+    #    'SDL_power.h',
+    #    'SDL_render.h',
+    #    'SDL_system.h',
+    #    'SDL_timer.h',
+    #    'SDL_version.h',
+        'SDL.h'
+    ],
+    DEFINES_BLACKLIST = [],
+    DEFINES = [],
+    PRIVATE_SYMBOLS = [
+        'SDL_GetError',
+        'SDL_Init',
+        'SDL_PollEvent',
+    ],
+    AUTOCHECK_BLACKLIST = [
+        'SDL_GetError',
+        'SDL_ClearError',
+        'SDL_Init',
+        'SDL_Quit',
+    ],
+    REPLACES = [
+        ('DECLSPEC', ''),
+        ('SDLCALL', ''),
+    ],
+    LIBNAME = 'SDL2',
+    VERIFY_SOURCE = "#include <SDL2/SDL.h>\n",
+    AUTOMANGLE = False,
+    PYPREDEFS = os.path.join(THISDIR, '..', 'predefs', 'sdl.pypredef'),
+    OUTMODULE = os.path.join(THISDIR, '_sdl.py'),
+))
 
 ################################################################################
 
-def build_cdefs():
-    re_ifdef = re.compile(r'^\#\S+\s+(\S+)')
-    re_define = re.compile(r'^\#define\s+(\S+)(\s+\S+)?')
-    re_hex = re.compile(r'(.*)(0x[0-9A-Fa-f]+)([^0-9A-Fa-f]*.*)')
-    
-    cdefs = StringIO()
-    hdefs = StringIO()
-    
-    for cdef_path in CDEF_FILES:
-        local_defines = set(_DEFINES)
-        
-        cdef_path = os.path.join(_THISDIR, '..', 'sdl_defs', cdef_path)
-        with open(cdef_path,'r') as cdef_file:
-            cdef_header = cdef_file.read()
-            
-        clean_cdefs = ''
-        hdefs.write(cdef_header + '\n')
-        
-        blockdesc = []
-        blockdef = []
-        
-        def active_block_desc():
-            return blockdesc[-1]
-        def is_blocked():
-            return blockdef and (blockdef[-1] == False)
-        def is_meta_blocked():
-            return (len(blockdef) > 1) and (blockdef[-2] == False)
-        def block_push(value,line):
-            blockdesc.append(line)
-            blockdef.append(value)
-        def block_pop():
-            blockdesc.pop()
-            blockdef.pop()
-        def block_flip():
-            blockdef[-1] = not blockdef[-1] 
-        
-        eat_next = False
-        for line in cdef_header.splitlines():
-            line = line.strip()
-            if 0:
-                while '0x' in line:
-                    # convert hexadecimal numbers to decimal ones
-                    m = re_hex.search(line)
-                    line = m.group(1) + str(int(m.group(2),16)) + m.group(3)
-            if eat_next:
-                if not line.endswith('\\'):
-                    eat_next = False
-            elif line.startswith('#endif'):
-                block_pop()
-            elif line.startswith('#ifndef '):
-                if is_blocked():
-                    block_push(False, line)
-                else:
-                    m = re_ifdef.match(line)
-                    block_push(not (m.group(1) in local_defines), line)
-            elif line.startswith('#ifdef '):
-                if is_blocked():
-                    block_push(False, line)
-                else:
-                    m = re_ifdef.match(line)
-                    block_push(m.group(1) in local_defines, line)
-            elif line.startswith('#if '):
-                print('excluding',line)               
-                block_push(False, line)
-            elif line.startswith('#elif'):
-                print('excluding',line)
-            elif line.startswith('#else'):
-                if is_meta_blocked():
-                    pass
-                else:
-                    block_push(not is_blocked(), line)
-            elif is_blocked():
-                clean_cdefs += '//' + line + ' | excluded by: %s\n' % (active_block_desc(),)
-            elif line.startswith('#include'):
-                continue
-            elif line.startswith('#define'):
-                m = re_define.match(line)
-                define = m.group(1)
-                var = m.group(2)
-                if line.endswith('\\'):
-                    eat_next = True
-                if '(' in define:
-                    # skip function macros
-                    continue
-                local_defines.add(define)
-                if not var:
-                    print('+',define)
-                elif not (define in _DEFINES_BLACKLIST):
-                    var = var.strip()                   
-                    clean_cdefs += '#define ' + define + ' ... // ' + var + '\n'
-            elif line:
-                clean_cdefs += line + '\n'
-        
-        # remove superfluous macros
-        clean_cdefs = clean_cdefs.replace('DECLSPEC', '')
-        clean_cdefs = clean_cdefs.replace('SDLCALL', '')
-        
-        cdefs.write(clean_cdefs + '\n')
-        
-    return cdefs.getvalue(), hdefs.getvalue()
-
-def remove_comments(cdefs):
-    """List cdefs in the current folder sorted by include order"""
-    tmppath = mktemp(suffix='.h')
-    file(tmppath, 'w').write(cdefs) 
-    cmdline = 'cpp -P -fpreprocessed -dD -E ' + tmppath
-    pipe = Popen(cmdline, shell=True, stdout=PIPE, universal_newlines=True)
-    text = pipe.communicate()[0]
-    outtext = ''
-    for line in text.splitlines():
-        line = line.strip()
-        if not line:
-            continue
-        outtext += line + '\n'
-    return outtext
-
-def test_cdefs(cdefs,hdefs):
-    ffi = FFI()
-    ffi.cdef(cdefs)
-    capi = ffi.verify("#include <SDL2/SDL.h>\n", 
-        libraries=['SDL2'])
-    # crosscheck
-    dlffi = FFI()
-    dlffi.cdef(cdefs)
-    dlcapi = dlffi.dlopen('SDL2')
-    outcapi = {}
-    for name,value in capi.__dict__.items():
-        if name.startswith('__'):
-            print("skipping",name)
-            continue
-        if callable(value):
-            dlvalue = getattr(dlcapi, name)
-            outcapi[name] = dlvalue
-        elif isinstance(value, (int,float,long)):
-            assert not hasattr(dlcapi, name)
-            outcapi[name] = value
-        else:
-            print("ignoring",name,value)
-    return outcapi
-
-def write_pypredef(CAPI):
-    dirpath = os.path.join(_THISDIR, '..', 'predefs')
-    if not os.path.isdir(dirpath):
-        os.makedirs(dirpath)
-    
-    filepath = os.path.join(dirpath, 'sdl.pypredef')
-    
-    print("writing",filepath)
-    with file(filepath, 'w') as f:
-        for name,value in CAPI.items():
-            if not name.startswith('SDL_'):
-                continue
-            if callable(value):
-                f.write('def {name}(*argv):\n    """{name}"""\n\n'.format(
-                    name=name))
-            if isinstance(value, (int,float,long)):
-                f.write('{name} = {typeid}\n'.format(name=name,typeid=type(value).__name__))
-
-_TEMPLATE = """
-# this file is auto-generated by sdl.builder. do not edit.
-from cffi import FFI
-
-SDL_UNMANGLED_EXPORTS = [
-{all_unmangled}
-]
-
-SDL_EXPORTS = [
-'SDLError',
-{all}
-]
-
-INTERNAL_EXPORTS = [
-'_ffi',
-'SDL_EXPORTS',
-'SDL_UNMANGLED_EXPORTS',
-]
-
-__all__ = SDL_EXPORTS + SDL_UNMANGLED_EXPORTS + INTERNAL_EXPORTS
-
-from .internal import *
-
-_SDL = load_sdl(\"""
-{cdefs}
-\""")   
-
-{imports}
-"""
-
-_IMPORT_FUNC_TEMPLATE = "{module_name} = lookup('{name}')\n"
-
-_IMPORT_SAFE_FUNC_TEMPLATE = "{module_name} = guard(lookup('{name}'))\n"
-
-def safeguard_blacklisted(name):
-    if name in _AUTOCHECK_BLACKLIST:
-        return True
-    for entry in _AUTOCHECK_BLACKLIST:
-        if fnmatch(name, entry):
-            return True
-    return False
-
-def write_module(cdefs, CAPI):
-    f = StringIO()
-    
-    imports = ''
-    exports = {
-        'all' : '',
-        'all_unmangled' : '',
-    }
-    
-    for name,value in CAPI.items():
-        module_name = name        
-        export_target = 'all'
-
-        if callable(value):
-            func_template = "lookup('{name}')"
-            
-            mangle = False            
-            if name in _PRIVATE_SYMBOLS:
-                mangle = True
-                
-            if mangle:
-                module_name = '_' + module_name
-                export_target = 'all_unmangled'
-                
-            if not safeguard_blacklisted(name):
-                func_template = "guard({func_template})".format(**locals())
-                
-            func_template = func_template.format(**locals())
-            imports += "{module_name} = {func_template}\n".format(**locals())
-                
-        elif isinstance(value, (int,float,long)):
-            imports += '{module_name} = {value}\n'.format(**locals())
-
-        exports[export_target] +=  '"{module_name}",\n'.format(**locals())
-
-    all = exports['all']
-    all_unmangled = exports['all_unmangled']
-
-    f.write(_TEMPLATE.format(**locals()))
-    
-    filepath = os.path.join(_THISDIR, '_sdl.py')
-    print("writing",filepath)
-    with open(filepath, 'w') as outfile:
-        outfile.write(f.getvalue())
-
-def find_error(cdefs):
-    lines = cdefs.splitlines()
-    upper = len(lines)
-    print("backtracking for broken part...")
-    while upper > 0:
-        source = '\n'.join(lines[:upper])
-        try:
-            test_ffi = FFI()
-            test_ffi.cdef(source)
-            with file('debug.txt','w') as f:
-                print("writing to debug.txt...")
-                part_a = '\n'.join(lines[:upper])
-                part_b = '\n'.join(lines[upper:])
-                f.write(part_a)
-                f.write('\n <<<<<< BROKEN PART AROUND HERE >>>>>> \n')
-                f.write(part_b)
-                return
-        except:
-            pass
-        upper -= 1 # remove a line, see if it works
-
 if __name__ == '__main__':
-    cdefs,hdefs = build_cdefs()
-    cdefs = remove_comments(cdefs)
-    try:    
-        CAPI = test_cdefs(cdefs,hdefs)
-    except:
-        traceback.print_exc()
-        #find_error(cdefs)
-        raise SystemExit, 255
-    write_module(cdefs, CAPI)
-    write_pypredef(CAPI)
+    autobind.build()
 
 __all__ = [
     '_ffi',
-    'load_sdl',
+    'load_lib',
     'lookup',
     'check_error',
     'guard',
     pass
 
 _ffi = FFI()
-_SDL = None
+_LIB = None
 
-def load_sdl(cdefs):
-    global _SDL
+def load_lib(cdefs):
+    global _LIB
     import time
     t = time.time()
     _ffi.cdef(cdefs)
     print("SDL cdefs loaded in {0}s".format(time.time() - t))
-    _SDL = _ffi.dlopen('SDL2')
-    return _SDL
+    _LIB = _ffi.dlopen('SDL2')
+    return _LIB
 
 def wrapstr(result):
     if result:
     return wrapper
 
 def lookup(name):
-    if hasattr(_SDL, name):
-        return getattr(_SDL, name)
+    if hasattr(_LIB, name):
+        return getattr(_LIB, name)
     print("SDL warning: function",name,"missing.")
     return None 
     
 def check_error():
-    error = _ffi.string(_SDL.SDL_GetError())
+    error = _ffi.string(_LIB.SDL_GetError())
     if error:
-        _SDL.SDL_ClearError()
+        _LIB.SDL_ClearError()
         raise SDLError, error
 
 def guard(func):