def convert(self, defs, flags=None, dump=False, **kw): hfile = mktemp(".h") open(hfile, "w").write(defs) xmlfile = mktemp(".xml") try: if flags: h2xml.main(["h2xml", "-q", "-I.", hfile, "-o", xmlfile, flags]) else: h2xml.main(["h2xml", "-q", "-I.", hfile, "-o", xmlfile]) ofi = StringIO() from ctypes import CDLL generate_code(xmlfile, ofi, **kw) namespace = {} exec ofi.getvalue() in namespace ## print ofi.getvalue() return ADict(namespace) finally: os.unlink(hfile) if dump: print open(xmlfile).read() os.unlink(xmlfile)
def build_ctypes(): # Step 1: Remove old files try: os.remove(ctypes_xml_file) except: pass try: os.remove(ctypes_api_file) except: pass # Configure ctypeslib codegen.ASSUME_STRINGS = False codegen.CDLL_SET_ERRNO = False codegen.PREFIX = ('# Code autogenerated by ctypeslib. Any changes will be lost!\n\n' '#pylint: disable-all\n' '#@PydevCodeAnalysisIgnore\n\n') # Generate XML file from C/C++ header file h2xml_args = ['h2xml.py', c_h_file, '-o',ctypes_xml_file, '-I',src_path] h2xml.main(h2xml_args) # Generate Python bindings from XML file # Note 1: to get -r <regex> to work correctly in xml2py.py v0.5.6 a patch is necessary (see README) # Note 2: uses libvdifio.so from the C/C++ build tree because 'make install' may not have been done yet print ('creating bindings %s ...' % (ctypes_api_file)) xml2py_flags = ['-o',ctypes_api_file+'.tmp'] xml2py_flags.extend(['-k','esf']) # standard flags xml2py_flags.extend(['-s','VDIFHeaderPrintLevel']) # the enums to include in wrapper xml2py_flags.extend(['-s','vdif_header']) # structs to include in wrapper xml2py_flags.extend(['-s','vdif_edv1_header', '-s','vdif_edv3_header', '-s','vdif_mux']) xml2py_flags.extend(['-s','vdif_mux_statistics', '-s','vdif_file_summary']) xml2py_flags.extend(['-r','VDIF', '-r','vdif', '-r','vdifmux']) # functions to include in wrapper xml2py_flags.extend(['-l',c_lib_file]) xml2py_args = ['xml2py.py',ctypes_xml_file] xml2py_args.extend(xml2py_flags) xml2py.main(xml2py_args) # Rename try: with open(ctypes_api_file, 'w') as fout: with open(ctypes_api_file+'.tmp', 'r') as fin: for line in fin: fout.write(line.replace(c_lib_file, c_lib_obj)) os.remove(ctypes_api_file+'.tmp') except: pass # Make sure the generated .py seems okay -- regexp to select functions was ok? func_found = False with open(ctypes_api_file, 'r') as fin: for line in fin: if check_for_func in line: func_found = True if not func_found: print ('Error: ctypeslib did not extract function names. For old ctypeslib might need a patch.') sys.exit(-1)
def parse_header(): logging.info('Parsing HEADER file %s.' % HEADER) header_path = os.path.join(INCLUDE_PATH, HEADER) header_basename = os.path.splitext(HEADER)[0].split('-')[0] argv = [ 'h2xml.py', header_path, '-k', '-c', '-o', '%s.xml' % header_basename ] h2xml.main(argv)
def test(self): h2xml.main(["h2xml", "-q", "-c", "stdio.h", "-o", "_stdio_gen.xml"]) if sys.platform == "win32": xml2py.main(["xml2py", "_stdio_gen.xml", "-l", "msvcrt", "-o", "_stdio_gen.py"]) else: xml2py.main(["xml2py", "_stdio_gen.xml", "-l", "c", "-o", "_stdio_gen.py"]) import _stdio_gen
def test_windows(self): h2xml.main([ "h2xml", "-q", "-D WIN32_LEAN_AND_MEAN", "-D _UNICODE", "-D UNICODE", "-D", "NO_STRICT", "-c", "windows.h", "-o", "_windows_gen.xml" ]) xml2py.main([ "xml2py", "_windows_gen.xml", "-w", "-m", "ctypes.wintypes", "-o", "_winapi_gen.py" ]) import _winapi_gen
def test(self): h2xml.main(["h2xml", "-q", "-c", "stdio.h", "-o", "_stdio_gen.xml"]) if sys.platform == "win32": xml2py.main([ "xml2py", "_stdio_gen.xml", "-l", "msvcrt", "-o", "_stdio_gen.py" ]) else: xml2py.main( ["xml2py", "_stdio_gen.xml", "-l", "c", "-o", "_stdio_gen.py"]) import _stdio_gen
def test_windows(self): h2xml.main(["h2xml", "-q", "-D WIN32_LEAN_AND_MEAN", "-D _UNICODE", "-D UNICODE", "-D", "NO_STRICT", "-c", "windows.h", "-o", "_windows_gen.xml"]) xml2py.main(["xml2py", "_windows_gen.xml", "-w", "-m", "ctypes.wintypes", "-o", "_winapi_gen.py"]) import _winapi_gen
def run(self): '''Create ctypes API to local FUSE headers''' # Import ctypeslib basedir = os.path.abspath(os.path.dirname(sys.argv[0])) sys.path.insert(0, os.path.join(basedir, 'ctypeslib.zip')) from ctypeslib import h2xml, xml2py from ctypeslib.codegen import codegenerator as ctypeslib print('Creating ctypes API from local fuse headers...') cflags = self.get_cflags() print('Using cflags: %s' % ' '.join(cflags)) fuse_path = 'fuse' if not ctypes.util.find_library(fuse_path): print('Could not find fuse library', file=sys.stderr) sys.exit(1) # Create temporary XML file tmp_fh = tempfile.NamedTemporaryFile() tmp_name = tmp_fh.name print('Calling h2xml...') argv = [ 'h2xml.py', '-o', tmp_name, '-c', '-q', '-I', basedir, 'fuse_ctypes.h' ] argv += cflags ctypeslib.ASSUME_STRINGS = False ctypeslib.CDLL_SET_ERRNO = False ctypeslib.PREFIX = ('# Code autogenerated by ctypeslib. Any changes will be lost!\n\n' '#pylint: disable-all\n' '#@PydevCodeAnalysisIgnore\n\n') h2xml.main(argv) print('Calling xml2py...') api_file = os.path.join(basedir, 'llfuse', 'ctypes_api.py') argv = [ 'xml2py.py', tmp_name, '-o', api_file, '-l', fuse_path ] for el in fuse_export_regex: argv.append('-r') argv.append(el) for el in fuse_export_symbols: argv.append('-s') argv.append(el) xml2py.main(argv) # Delete temporary XML file tmp_fh.close() print('Code generation complete.')
def _run_h2xml(): p = subprocess.Popen(['MagickWand-config', '--cppflags'], stdout=subprocess.PIPE) cpp_directives = p.stdout.read().decode().strip() include_dir = cpp_directives.split('-I')[1] argv = ['generate.py', cpp_directives, '-o', 'magickwand.xml', os.path.join(include_dir, 'wand/MagickWand.h')] return h2xml.main(argv)
def convert(self, defs, flags=None, dump=False, **kw): hfile = mktemp(".h") open(hfile, "w").write(defs) xmlfile = mktemp(".xml") try: if flags: h2xml.main(["h2xml", "-q", "-I.", hfile, "-o", xmlfile, flags]) else: h2xml.main(["h2xml", "-q", "-I.", hfile, "-o", xmlfile]) ofi = StringIO() generate_code(xmlfile, ofi, **kw) namespace = {} exec ofi.getvalue() in namespace ## print ofi.getvalue() return ADict(namespace) finally: os.unlink(hfile) if dump: print open(xmlfile).read() os.unlink(xmlfile)
def main(argv=None): """A small script which runs h2xml, xml2py (from ctypeslib) and then does basic replacements. """ if argv is None: argv = sys.argv parser = OptionParser("usage: %prog [options]") parser.add_option( "-i", dest="chipmunk_includes", help="path to chipmunk include files (if not specified, '" + default_path_to_chipmunk_include + "' will be used)", default=default_path_to_chipmunk_include) parser.add_option("-o", dest="output", help="output filename (if not specified, '" + default_output + "' will be used)", default=default_output) parser.add_option("-l", dest="lib", help="chipmunk library path (if not specified, '" + default_path_to_chipmunk_lib + "' will be used)", default=default_path_to_chipmunk_lib) options, files = parser.parse_args(argv[1:]) h2xml_args = [ "", abspath(join(options.chipmunk_includes, "chipmunk.h")), abspath(join(options.chipmunk_includes, "chipmunk_unsafe.h")), abspath(join(options.chipmunk_includes, "chipmunk_ffi.h")), "-c", "-D", "CHIPMUNK_FFI", "-o", "chipmunk.xml" ] h2xml.main(h2xml_args) print("h2xml done") xml2py_args = [ "generate_bindings.py", "-l", options.lib, "-o", options.output, "-r", "cp.*", "chipmunk.xml" ] xml2py.main(argv=xml2py_args) print("xml2py done") custom_head = """ from ctypes import * from .vec2d import Vec2d cpVect = Vec2d STRING = c_char_p from .libload import load_library, platform_specific_functions try: import pymunkoptions _lib_debug = pymunkoptions.options["debug"] except: _lib_debug = True #Set to True to print the Chipmunk path. chipmunk_lib = load_library("chipmunk", debug_lib=_lib_debug) function_pointer = platform_specific_functions()['function_pointer'] """ custom_uintptr_size = """ if sizeof(c_void_p) == 4: uintptr_t = c_uint else: uintptr_t = c_ulonglong """ bad_symbols = ["free", "calloc", "realloc"] chipmunkpy = open(options.output, 'r').read() # change head, remove cpVect, and replace _libraries index with chipmunk_lib # also change to use the platform specific function pointer head_match = re.compile(r"from.*?\)", re.DOTALL) cpVect_classdef_match = re.compile(r"class cpVect.*?pass", re.DOTALL) cpVect_fields_match = re.compile(r"cpVect._fields_.*?]", re.DOTALL) lib_match = re.compile(r"_libraries.*?]") function_pointer_cdecl = re.compile(r"CFUNCTYPE", re.DOTALL) function_pointer_stddecl = re.compile(r"WINFUNCTYPE", re.DOTALL) pack = re.compile(r"(\w+\._pack_ = 4)", re.DOTALL) py3k_long = re.compile(r"4294967295L", re.DOTALL) py3k_long2 = re.compile(r"0L", re.DOTALL) uintptr_size = re.compile(r"uintptr_t = c_uint", re.DOTALL) symbol_match = re.compile("^(?P<n>" + "|".join(bad_symbols) + ").*", re.MULTILINE) #all_layers = re.compile(r"3344921057L", re.DOTALL) chipmunkpy = head_match.sub(custom_head, chipmunkpy) chipmunkpy = cpVect_classdef_match.sub("#cpVect class def removed", chipmunkpy) chipmunkpy = cpVect_fields_match.sub("#cpVect _fields_ def removed", chipmunkpy) chipmunkpy = lib_match.sub("chipmunk_lib", chipmunkpy) chipmunkpy = function_pointer_cdecl.sub("function_pointer", chipmunkpy) chipmunkpy = function_pointer_stddecl.sub("function_pointer", chipmunkpy) chipmunkpy = pack.sub(r"#\1", chipmunkpy) chipmunkpy = py3k_long.sub("4294967295", chipmunkpy) chipmunkpy = py3k_long2.sub("0", chipmunkpy) #chipmunkpy = all_layers.sub("-1", chipmunkpy) chipmunkpy = uintptr_size.sub(custom_uintptr_size, chipmunkpy) chipmunkpy = symbol_match.sub(r"\g<n> = None # symbol removed", chipmunkpy) f = open(options.output, 'w').write(chipmunkpy) print("replacement done")
#!/usr/bin/env python import sys from ctypeslib.h2xml import main if __name__ == "__main__": sys.exit(main())
def build_ctypes(): # Step 1: Remove old files try: os.remove(ctypes_xml_file) except: pass try: os.remove(ctypes_api_file) except: pass # Configure ctypeslib codegen.ASSUME_STRINGS = False codegen.CDLL_SET_ERRNO = False codegen.PREFIX = ( '# Code autogenerated by ctypeslib. Any changes will be lost!\n\n' '#pylint: disable-all\n' '#@PydevCodeAnalysisIgnore\n\n') # Generate XML file from C/C++ header file h2xml_args = ['h2xml.py', c_h_file, '-o', ctypes_xml_file, '-I', src_path] h2xml.main(h2xml_args) # Generate Python bindings from XML file # Note 1: to get -r <regex> to work correctly in xml2py.py v0.5.6 a patch is necessary (see README) # Note 2: uses libvdifio.so from the C/C++ build tree because 'make install' may not have been done yet print('creating bindings %s ...' % (ctypes_api_file)) xml2py_flags = ['-o', ctypes_api_file + '.tmp'] xml2py_flags.extend(['-k', 'esf']) # standard flags xml2py_flags.extend(['-s', 'VDIFHeaderPrintLevel' ]) # the enums to include in wrapper xml2py_flags.extend(['-s', 'vdif_header']) # structs to include in wrapper xml2py_flags.extend( ['-s', 'vdif_edv1_header', '-s', 'vdif_edv3_header', '-s', 'vdif_mux']) xml2py_flags.extend( ['-s', 'vdif_mux_statistics', '-s', 'vdif_file_summary']) xml2py_flags.extend(['-r', 'VDIF', '-r', 'vdif', '-r', 'vdifmux']) # functions to include in wrapper xml2py_flags.extend(['-l', c_lib_file]) xml2py_args = ['xml2py.py', ctypes_xml_file] xml2py_args.extend(xml2py_flags) xml2py.main(xml2py_args) # Rename try: with open(ctypes_api_file, 'w') as fout: with open(ctypes_api_file + '.tmp', 'r') as fin: for line in fin: fout.write(line.replace(c_lib_file, c_lib_obj)) os.remove(ctypes_api_file + '.tmp') except: pass # Make sure the generated .py seems okay -- regexp to select functions was ok? func_found = False with open(ctypes_api_file, 'r') as fin: for line in fin: if check_for_func in line: func_found = True if not func_found: print( 'Error: ctypeslib did not extract function names. For old ctypeslib might need a patch.' ) sys.exit(-1)
def main(argv=None): """A small script which runs h2xml, xml2py (from ctypeslib) and then does basic replacements. """ if argv is None: argv = sys.argv parser = OptionParser("usage: %prog [options]") parser.add_option("-i" ,dest="chipmunk_includes" ,help="path to chipmunk include files (if not specified, '" + default_path_to_chipmunk_include + "' will be used)" ,default=default_path_to_chipmunk_include ) parser.add_option("-o" ,dest="output" ,help="output filename (if not specified, '" + default_output + "' will be used)" ,default=default_output ) parser.add_option("-l" ,dest="lib" ,help="chipmunk library path (if not specified, '" + default_path_to_chipmunk_lib + "' will be used)" ,default=default_path_to_chipmunk_lib ) options, files = parser.parse_args(argv[1:]) h2xml_args = ["" , abspath( join(options.chipmunk_includes, "chipmunk.h") ) , abspath( join(options.chipmunk_includes, "chipmunk_unsafe.h") ) , abspath( join(options.chipmunk_includes, "chipmunk_ffi.h") ) , "-c" , "-D", "CHIPMUNK_FFI" , "-o", "chipmunk.xml"] h2xml.main(h2xml_args) print("h2xml done") xml2py_args = ["generate_bindings.py" , "-l", options.lib , "-o", options.output , "-r", "cp.*" , "chipmunk.xml"] xml2py.main(argv = xml2py_args) print("xml2py done") custom_head = """ from ctypes import * from .vec2d import Vec2d cpVect = Vec2d STRING = c_char_p from .libload import load_library, platform_specific_functions try: import pymunkoptions _lib_debug = pymunkoptions.options["debug"] except: _lib_debug = True #Set to True to print the Chipmunk path. chipmunk_lib = load_library("chipmunk", debug_lib=_lib_debug) function_pointer = platform_specific_functions()['function_pointer'] """ custom_uintptr_size = """ if sizeof(c_void_p) == 4: uintptr_t = c_uint else: uintptr_t = c_ulonglong """ bad_symbols = ["free","calloc","realloc"] chipmunkpy = open(options.output, 'r').read() # change head, remove cpVect, and replace _libraries index with chipmunk_lib # also change to use the platform specific function pointer head_match = re.compile(r"from.*?\)", re.DOTALL) cpVect_classdef_match = re.compile(r"class cpVect.*?pass", re.DOTALL) cpVect_fields_match = re.compile(r"cpVect._fields_.*?]", re.DOTALL) lib_match = re.compile(r"_libraries.*?]") function_pointer_cdecl = re.compile(r"CFUNCTYPE", re.DOTALL) function_pointer_stddecl = re.compile(r"WINFUNCTYPE", re.DOTALL) pack = re.compile(r"(\w+\._pack_ = 4)", re.DOTALL) py3k_long = re.compile(r"4294967295L", re.DOTALL) py3k_long2 = re.compile(r"0L", re.DOTALL) uintptr_size = re.compile(r"uintptr_t = c_uint", re.DOTALL) symbol_match = re.compile( "^(?P<n>" + "|".join(bad_symbols) + ").*",re.MULTILINE) #all_layers = re.compile(r"3344921057L", re.DOTALL) chipmunkpy = head_match.sub(custom_head, chipmunkpy) chipmunkpy = cpVect_classdef_match.sub("#cpVect class def removed", chipmunkpy) chipmunkpy = cpVect_fields_match.sub("#cpVect _fields_ def removed", chipmunkpy) chipmunkpy = lib_match.sub("chipmunk_lib", chipmunkpy) chipmunkpy = function_pointer_cdecl.sub("function_pointer", chipmunkpy) chipmunkpy = function_pointer_stddecl.sub("function_pointer", chipmunkpy) chipmunkpy = pack.sub(r"#\1", chipmunkpy) chipmunkpy = py3k_long.sub("4294967295", chipmunkpy) chipmunkpy = py3k_long2.sub("0", chipmunkpy) #chipmunkpy = all_layers.sub("-1", chipmunkpy) chipmunkpy = uintptr_size.sub(custom_uintptr_size, chipmunkpy) chipmunkpy = symbol_match.sub(r"\g<n> = None # symbol removed", chipmunkpy) f = open(options.output, 'w').write(chipmunkpy) print("replacement done")
def build_ctypes(): # Step 1: Remove old files try: os.remove(ctypes_xml_file) except: pass try: os.remove(ctypes_api_file) except: pass # Configure ctypeslib codegen.ASSUME_STRINGS = False codegen.CDLL_SET_ERRNO = False codegen.PREFIX = ('# Code autogenerated by ctypeslib. Any changes will be lost!\n\n' '#pylint: disable-all\n' '#@PydevCodeAnalysisIgnore\n\n') # Modify a copy of mark5access headers # By design h2xml is using C++ to convert headers. # There are issues with C++ <complex> and the Python conversion. # We create a copy of 'mark5_stream.h' to force C-only headers # and the C <complex.h> definition of complex numbers c_h_file_tmp = 'mark5_stream_tmp.h' with open(c_h_file_tmp, 'w') as fout: with open(c_h_file, 'r') as fin: fout.write('#undef __cplusplus\n') for line in fin: if not('complex' in line): fout.write(line) # Generate XML file from C/C++ header file h2xml_args = ['h2xml.py', c_h_file_tmp, '-o',ctypes_xml_file, '-I',src_path] h2xml.main(h2xml_args) os.remove(c_h_file_tmp) # Generate Python bindings from XML file # Note 1: to get -r <regex> to work correctly in xml2py.py v0.5.6 a patch is necessary (see README) # Note 2: uses libvdifio.so from the C/C++ build tree because 'make install' may not have been done yet print ('creating bindings %s ...' % (ctypes_api_file)) xml2py_flags = ['-o',ctypes_api_file+'.tmp'] xml2py_flags.extend(['-k','esf']) # standard flags xml2py_flags.extend(['-s','Mark5Format']) # the enums to include in wrapper xml2py_flags.extend(['-s','Mark5Blanker']) xml2py_flags.extend(['-s','mark5_stream']) # structs to include in wrapper xml2py_flags.extend(['-s','mark5_stream_generic', '-s','mark5_format_generic', '-s','mark5_format']) xml2py_flags.extend(['-r','mark5']) # functions to include in wrapper xml2py_flags.extend(['-l',c_lib_file]) xml2py_args = ['xml2py.py', ctypes_xml_file] xml2py_args.extend(xml2py_flags) xml2py.main(xml2py_args) # Rename try: with open(ctypes_api_file, 'w') as fout: with open(ctypes_api_file+'.tmp', 'r') as fin: for line in fin: fout.write(line.replace(c_lib_file, c_lib_obj)) os.remove(ctypes_api_file+'.tmp') except: pass # Make sure the generated .py seems okay -- regexp to select mark5* functions was ok? func_found = False with open(ctypes_api_file, 'r') as fin: for line in fin: if check_for_func in line: func_found = True if not func_found: print ('Error: ctypeslib did not extract function names. For old ctypeslib might need a patch.') sys.exit(-1)