def configure_boehm_once(cls): """ Configure boehm only once, since we don't cache failures """ if hasattr(cls, 'malloc_fn_ptr'): return cls.malloc_fn_ptr from pypy.rpython.tool import rffi_platform compilation_info = rffi_platform.configure_boehm() # Versions 6.x of libgc needs to use GC_local_malloc(). # Versions 7.x of libgc removed this function; GC_malloc() has # the same behavior if libgc was compiled with # THREAD_LOCAL_ALLOC. class CConfig: _compilation_info_ = compilation_info HAS_LOCAL_MALLOC = rffi_platform.Has("GC_local_malloc") config = rffi_platform.configure(CConfig) if config['HAS_LOCAL_MALLOC']: GC_MALLOC = "GC_local_malloc" else: GC_MALLOC = "GC_malloc" malloc_fn_ptr = rffi.llexternal(GC_MALLOC, [lltype.Signed], # size_t, but good enough llmemory.GCREF, compilation_info=compilation_info, sandboxsafe=True, _nowrapper=True) cls.malloc_fn_ptr = malloc_fn_ptr cls.compilation_info = compilation_info return malloc_fn_ptr
def test_ifdef(): class CConfig: _compilation_info_ = ExternalCompilationInfo( post_include_bits = ['/* a C comment */', '#define XYZZY 42', 'typedef int foo;', ''' struct s { int i; double f; }; ''']) s = rffi_platform.Struct('struct s', [('i', rffi.INT)], ifdef='XYZZY') z = rffi_platform.Struct('struct z', [('i', rffi.INT)], ifdef='FOOBAR') foo = rffi_platform.SimpleType('foo', ifdef='XYZZY') bar = rffi_platform.SimpleType('bar', ifdef='FOOBAR') res = rffi_platform.configure(CConfig) assert res['s'] is not None assert res['z'] is None assert res['foo'] is not None assert res['bar'] is None
def test_nested_structs_in_the_opposite_order(): class CConfig: _compilation_info_ = ExternalCompilationInfo( post_include_bits=[ """ struct y { int foo; unsigned long bar; }; struct x { char c; struct y y; }; """ ] ) y = rffi_platform.Struct("struct y", [("bar", rffi.SHORT)]) x = rffi_platform.Struct("struct x", [("y", y)]) res = rffi_platform.configure(CConfig) c_x = res["x"] c_y = res["y"] assert isinstance(c_x, lltype.Struct) assert isinstance(c_y, lltype.Struct) assert c_x.c_y is c_y
def test_ifdef(): class CConfig: _compilation_info_ = ExternalCompilationInfo( post_include_bits=[ "/* a C comment */", "#define XYZZY 42", "typedef int foo;", """ struct s { int i; double f; }; """, ] ) s = rffi_platform.Struct("struct s", [("i", rffi.INT)], ifdef="XYZZY") z = rffi_platform.Struct("struct z", [("i", rffi.INT)], ifdef="FOOBAR") foo = rffi_platform.SimpleType("foo", ifdef="XYZZY") bar = rffi_platform.SimpleType("bar", ifdef="FOOBAR") res = rffi_platform.configure(CConfig) assert res["s"] is not None assert res["z"] is None assert res["foo"] is not None assert res["bar"] is None
def test_nested_structs(): class CConfig: _compilation_info_ = ExternalCompilationInfo( post_include_lines=""" struct x { int foo; unsigned long bar; }; struct y { char c; struct x x; }; """.split( "\n" ) ) x = rffi_platform.Struct("struct x", [("bar", rffi.SHORT)]) y = rffi_platform.Struct("struct y", [("x", x)]) res = rffi_platform.configure(CConfig) c_x = res["x"] c_y = res["y"] assert isinstance(c_x, lltype.Struct) assert isinstance(c_y, lltype.Struct) assert c_y.c_x is c_x
def register_os_uname(self): CHARARRAY = lltype.FixedSizeArray(lltype.Char, 1) class CConfig: _compilation_info_ = ExternalCompilationInfo( includes = ['sys/utsname.h'] ) UTSNAME = platform.Struct('struct utsname', [ ('sysname', CHARARRAY), ('nodename', CHARARRAY), ('release', CHARARRAY), ('version', CHARARRAY), ('machine', CHARARRAY)]) config = platform.configure(CConfig) UTSNAMEP = lltype.Ptr(config['UTSNAME']) os_uname = self.llexternal('uname', [UTSNAMEP], rffi.INT, compilation_info=CConfig._compilation_info_) def uname_llimpl(): l_utsbuf = lltype.malloc(UTSNAMEP.TO, flavor='raw') result = os_uname(l_utsbuf) if result == -1: raise OSError(rposix.get_errno(), "os_uname failed") retval = ( rffi.charp2str(rffi.cast(rffi.CCHARP, l_utsbuf.c_sysname)), rffi.charp2str(rffi.cast(rffi.CCHARP, l_utsbuf.c_nodename)), rffi.charp2str(rffi.cast(rffi.CCHARP, l_utsbuf.c_release)), rffi.charp2str(rffi.cast(rffi.CCHARP, l_utsbuf.c_version)), rffi.charp2str(rffi.cast(rffi.CCHARP, l_utsbuf.c_machine)), ) lltype.free(l_utsbuf, flavor='raw') return retval return extdef([], (str, str, str, str, str), "ll_os.ll_uname", llimpl=uname_llimpl)
def setup(): INSPECT = {'b': 'signed char', 'h': 'signed short', 'i': 'signed int', 'l': 'signed long', 'q': 'signed long long', 'B': 'unsigned char', 'H': 'unsigned short', 'I': 'unsigned int', 'L': 'unsigned long', 'Q': 'unsigned long long', 'P': 'char *', 'f': 'float', 'd': 'double', } pre_include_bits = [] for fmtchar, ctype in INSPECT.items(): pre_include_bits.append(""" struct about_%s { char pad; %s field; }; """ % (fmtchar, ctype)) class CConfig: _compilation_info_ = ExternalCompilationInfo( pre_include_bits = pre_include_bits ) for fmtchar, ctype in INSPECT.items(): setattr(CConfig, fmtchar, rffi_platform.Struct( "struct about_%s" % (fmtchar,), [('field', lltype.FixedSizeArray(rffi.CHAR, 1))])) cConfig = rffi_platform.configure(CConfig) for fmtchar, ctype in INSPECT.items(): S = cConfig[fmtchar] alignment = rffi.offsetof(S, 'c_field') size = rffi.sizeof(S.c_field) signed = 'a' <= fmtchar <= 'z' if fmtchar == 'f': pack = pack_float unpack = unpack_float elif fmtchar == 'd': pack = pack_double unpack = unpack_double else: cpython_checks_range = fmtchar in 'bBhH' pack = std.make_int_packer(size, signed, cpython_checks_range) unpack = std.make_int_unpacker(size, signed) native_fmttable[fmtchar] = {'size': size, 'alignment': alignment, 'pack': pack, 'unpack': unpack}
def setup(): INSPECT = {'b': 'signed char', 'h': 'signed short', 'i': 'signed int', 'l': 'signed long', 'q': 'signed long long', 'B': 'unsigned char', 'H': 'unsigned short', 'I': 'unsigned int', 'L': 'unsigned long', 'Q': 'unsigned long long', 'P': 'char *', 'f': 'float', 'd': 'double', } pre_include_lines = [] for fmtchar, ctype in INSPECT.items(): pre_include_lines += (""" struct about_%s { char pad; %s field; }; """ % (fmtchar, ctype)).split("\n") class CConfig: _compilation_info_ = ExternalCompilationInfo( pre_include_lines = pre_include_lines ) for fmtchar, ctype in INSPECT.items(): setattr(CConfig, fmtchar, rffi_platform.Struct( "struct about_%s" % (fmtchar,), [('field', lltype.FixedSizeArray(rffi.CHAR, 1))])) cConfig = rffi_platform.configure(CConfig) for fmtchar, ctype in INSPECT.items(): S = cConfig[fmtchar] alignment = rffi.offsetof(S, 'c_field') size = rffi.sizeof(S.c_field) signed = 'a' <= fmtchar <= 'z' if fmtchar == 'f': pack = pack_float unpack = unpack_float elif fmtchar == 'd': pack = pack_double unpack = unpack_double else: cpython_checks_range = fmtchar in 'bBhH' pack = std.make_int_packer(size, signed, cpython_checks_range) unpack = std.make_int_unpacker(size, signed) native_fmttable[fmtchar] = {'size': size, 'alignment': alignment, 'pack': pack, 'unpack': unpack}
def configure(self, CConfig): classes_seen = self.__dict__.setdefault('__classes_seen', {}) if CConfig in classes_seen: return from pypy.rpython.tool import rffi_platform as platform # copy some stuff self.compilation_info = CConfig._compilation_info_ self.__dict__.update(platform.configure(CConfig)) classes_seen[CConfig] = True
def register_posix__getfullpathname(self): # this nt function is not exposed via os, but needed # to get a correct implementation of os.abspath # XXX why do we ignore WINAPI conventions everywhere? class CConfig: _compilation_info_ = ExternalCompilationInfo( includes = ['Windows.h'] ) MAX_PATH = platform.ConstantInteger('MAX_PATH') DWORD = platform.SimpleType("DWORD", rffi.ULONG) LPCTSTR = platform.SimpleType("LPCTSTR", rffi.CCHARP) LPTSTR = platform.SimpleType("LPTSTR", rffi.CCHARP) LPTSTRP = platform.SimpleType("LPTSTR*", rffi.CCHARPP) config = platform.configure(CConfig) MAX_PATH = config['MAX_PATH'] DWORD = config['DWORD'] LPCTSTR = config['LPCTSTR'] LPTSTR = config['LPTSTR'] LPTSTRP = config['LPTSTRP'] # XXX unicode? GetFullPathName = self.llexternal('GetFullPathNameA', [LPCTSTR, DWORD, LPTSTR, LPTSTRP], DWORD) GetLastError = self.llexternal('GetLastError', [], DWORD) ##DWORD WINAPI GetFullPathName( ## __in LPCTSTR lpFileName, ## __in DWORD nBufferLength, ## __out LPTSTR lpBuffer, ## __out LPTSTR* lpFilePart ##); def _getfullpathname_llimpl(lpFileName): nBufferLength = MAX_PATH + 1 lpBuffer = lltype.malloc(LPTSTR.TO, nBufferLength, flavor='raw') try: res = GetFullPathName( lpFileName, rffi.cast(DWORD, nBufferLength), lpBuffer, lltype.nullptr(LPTSTRP.TO)) if res == 0: error = GetLastError() raise OSError(error, "_getfullpathname failed") # XXX ntpath expects WindowsError :-( result = rffi.charp2str(lpBuffer) return result finally: lltype.free(lpBuffer, flavor='raw') return extdef([str], # a single argument which is a str str, # returns a string "ll_os.posix__getfullpathname", llimpl=_getfullpathname_llimpl)
def posix_declaration(try_to_add=None): global STAT_STRUCT LL_STAT_FIELDS = STAT_FIELDS[:] if try_to_add: LL_STAT_FIELDS.append(try_to_add) if TIMESPEC is not None: def _expand(lst, originalname, timespecname): for i, (_name, _TYPE) in enumerate(lst): if _name == originalname: # replace the 'st_atime' field of type rffi.DOUBLE # with a field 'st_atim' of type 'struct timespec' lst[i] = (timespecname, TIMESPEC.TO) break _expand(LL_STAT_FIELDS, 'st_atime', 'st_atim') _expand(LL_STAT_FIELDS, 'st_mtime', 'st_mtim') _expand(LL_STAT_FIELDS, 'st_ctime', 'st_ctim') del _expand else: # Replace float fields with integers for name in ('st_atime', 'st_mtime', 'st_ctime', 'st_birthtime'): for i, (_name, _TYPE) in enumerate(LL_STAT_FIELDS): if _name == name: LL_STAT_FIELDS[i] = (_name, lltype.Signed) break class CConfig: _compilation_info_ = compilation_info STAT_STRUCT = platform.Struct('struct %s' % _name_struct_stat, LL_STAT_FIELDS) try: config = platform.configure(CConfig, ignore_errors=try_to_add is not None) except platform.CompilationError: if try_to_add: return # failed to add this field, give up raise STAT_STRUCT = lltype.Ptr(config['STAT_STRUCT']) if try_to_add: STAT_FIELDS.append(try_to_add)
def test_configure(): test_h = udir.join("test_ctypes_platform.h") test_h.write("#define XYZZY 42\n") class CConfig: _compilation_info_ = ExternalCompilationInfo( pre_include_bits=["/* a C comment */", "#include <stdio.h>", "#include <test_ctypes_platform.h>"], include_dirs=[str(udir)], ) FILE = rffi_platform.Struct("FILE", []) ushort = rffi_platform.SimpleType("unsigned short") XYZZY = rffi_platform.ConstantInteger("XYZZY") res = rffi_platform.configure(CConfig) assert isinstance(res["FILE"], lltype.Struct) assert res == {"FILE": res["FILE"], "ushort": rffi.USHORT, "XYZZY": 42}
def test_configure(): test_h = udir.join('test_ctypes_platform.h') test_h.write('#define XYZZY 42\n') class CConfig: _compilation_info_ = ExternalCompilationInfo(pre_include_bits=[ "/* a C comment */", "#include <stdio.h>", "#include <test_ctypes_platform.h>" ], include_dirs=[str(udir)]) FILE = rffi_platform.Struct('FILE', []) ushort = rffi_platform.SimpleType('unsigned short') XYZZY = rffi_platform.ConstantInteger('XYZZY') res = rffi_platform.configure(CConfig) assert isinstance(res['FILE'], lltype.Struct) assert res == {'FILE': res['FILE'], 'ushort': rffi.USHORT, 'XYZZY': 42}
def posix_declaration(try_to_add=None): global STAT_STRUCT LL_STAT_FIELDS = STAT_FIELDS[:] if try_to_add: LL_STAT_FIELDS.append(try_to_add) if TIMESPEC is not None: def _expand(lst, originalname, timespecname): for i, (_name, _TYPE) in enumerate(lst): if _name == originalname: # replace the 'st_atime' field of type rffi.DOUBLE # with a field 'st_atim' of type 'struct timespec' lst[i] = (timespecname, TIMESPEC.TO) break _expand(LL_STAT_FIELDS, "st_atime", "st_atim") _expand(LL_STAT_FIELDS, "st_mtime", "st_mtim") _expand(LL_STAT_FIELDS, "st_ctime", "st_ctim") del _expand else: # Replace float fields with integers for name in ("st_atime", "st_mtime", "st_ctime", "st_birthtime"): for i, (_name, _TYPE) in enumerate(LL_STAT_FIELDS): if _name == name: LL_STAT_FIELDS[i] = (_name, lltype.Signed) break class CConfig: _compilation_info_ = compilation_info STAT_STRUCT = platform.Struct("struct %s" % _name_struct_stat, LL_STAT_FIELDS) try: config = platform.configure(CConfig, ignore_errors=try_to_add is not None) except platform.CompilationError: if try_to_add: return # failed to add this field, give up raise STAT_STRUCT = lltype.Ptr(config["STAT_STRUCT"]) if try_to_add: STAT_FIELDS.append(try_to_add)
def test_padding_in_prebuilt_struct(self): from pypy.rpython.lltypesystem import rffi from pypy.rpython.tool import rffi_platform eci = rffi_platform.eci_from_header(""" typedef struct { char c1; /* followed by one byte of padding */ short s1; char c2; /* followed by 3 bytes of padding */ int i2; char c3; /* followed by 3 or 7 bytes of padding */ long l3; char c4; } foobar_t; """) class CConfig: _compilation_info_ = eci STRUCT = rffi_platform.Struct("foobar_t", [("c1", Signed), ("s1", Signed), ("l3", Signed)]) S = rffi_platform.configure(CConfig)['STRUCT'] assert 'get_padding_drop' in S._hints s1 = malloc(S, immortal=True) s1.c_c1 = rffi.cast(S.c_c1, -12) s1.c_s1 = rffi.cast(S.c_s1, -7843) s1.c_l3 = -98765432 s2 = malloc(S, immortal=True) s2.c_c1 = rffi.cast(S.c_c1, -123) s2.c_s1 = rffi.cast(S.c_s1, -789) s2.c_l3 = -9999999 # def f(n): if n > 5: s = s1 else: s = s2 return s.c_l3 # self.include_also_eci = eci fn = self.getcompiled(f, [int]) res = fn(10) assert res == -98765432 res = fn(1) assert res == -9999999
def test_ifdef(): class CConfig: _compilation_info_ = ExternalCompilationInfo(post_include_lines=[ '/* a C comment */', '#define XYZZY 42', 'typedef int foo;', 'struct s {', 'int i;', 'double f;' '};' ]) s = rffi_platform.Struct('struct s', [('i', rffi.INT)], ifdef='XYZZY') z = rffi_platform.Struct('struct z', [('i', rffi.INT)], ifdef='FOOBAR') foo = rffi_platform.SimpleType('foo', ifdef='XYZZY') bar = rffi_platform.SimpleType('bar', ifdef='FOOBAR') res = rffi_platform.configure(CConfig) assert res['s'] is not None assert res['z'] is None assert res['foo'] is not None assert res['bar'] is None
def test_nested_structs(): class CConfig: _compilation_info_ = ExternalCompilationInfo(post_include_lines=""" struct x { int foo; unsigned long bar; }; struct y { char c; struct x x; }; """.split("\n")) x = rffi_platform.Struct("struct x", [("bar", rffi.SHORT)]) y = rffi_platform.Struct("struct y", [("x", x)]) res = rffi_platform.configure(CConfig) c_x = res["x"] c_y = res["y"] assert isinstance(c_x, lltype.Struct) assert isinstance(c_y, lltype.Struct) assert c_y.c_x is c_x
def test_configure(): test_h = udir.join('test_ctypes_platform.h') test_h.write('#define XYZZY 42\n') class CConfig: _compilation_info_ = ExternalCompilationInfo( pre_include_bits = ["/* a C comment */", "#include <stdio.h>", "#include <test_ctypes_platform.h>"], include_dirs = [str(udir)] ) FILE = rffi_platform.Struct('FILE', []) ushort = rffi_platform.SimpleType('unsigned short') XYZZY = rffi_platform.ConstantInteger('XYZZY') res = rffi_platform.configure(CConfig) assert isinstance(res['FILE'], lltype.Struct) assert res == {'FILE': res['FILE'], 'ushort': rffi.USHORT, 'XYZZY': 42}
def configure_boehm_once(cls): """ Configure boehm only once, since we don't cache failures """ if hasattr(cls, "malloc_fn_ptr"): return cls.malloc_fn_ptr from pypy.rpython.tool import rffi_platform compilation_info = rffi_platform.configure_boehm() # on some platform GC_init is required before any other # GC_* functions, call it here for the benefit of tests # XXX move this to tests init_fn_ptr = rffi.llexternal( "GC_init", [], lltype.Void, compilation_info=compilation_info, sandboxsafe=True, _nowrapper=True ) init_fn_ptr() # Versions 6.x of libgc needs to use GC_local_malloc(). # Versions 7.x of libgc removed this function; GC_malloc() has # the same behavior if libgc was compiled with # THREAD_LOCAL_ALLOC. class CConfig: _compilation_info_ = compilation_info HAS_LOCAL_MALLOC = rffi_platform.Has("GC_local_malloc") config = rffi_platform.configure(CConfig) if config["HAS_LOCAL_MALLOC"]: GC_MALLOC = "GC_local_malloc" else: GC_MALLOC = "GC_malloc" malloc_fn_ptr = rffi.llexternal( GC_MALLOC, [lltype.Signed], # size_t, but good enough llmemory.GCREF, compilation_info=compilation_info, sandboxsafe=True, _nowrapper=True, ) cls.malloc_fn_ptr = malloc_fn_ptr return malloc_fn_ptr
def configure_boehm_once(cls): """ Configure boehm only once, since we don't cache failures """ if hasattr(cls, 'malloc_fn_ptr'): return cls.malloc_fn_ptr from pypy.rpython.tool import rffi_platform compilation_info = rffi_platform.configure_boehm() # on some platform GC_init is required before any other # GC_* functions, call it here for the benefit of tests # XXX move this to tests init_fn_ptr = rffi.llexternal("GC_init", [], lltype.Void, compilation_info=compilation_info, sandboxsafe=True, _nowrapper=True) init_fn_ptr() # Versions 6.x of libgc needs to use GC_local_malloc(). # Versions 7.x of libgc removed this function; GC_malloc() has # the same behavior if libgc was compiled with # THREAD_LOCAL_ALLOC. class CConfig: _compilation_info_ = compilation_info HAS_LOCAL_MALLOC = rffi_platform.Has("GC_local_malloc") config = rffi_platform.configure(CConfig) if config['HAS_LOCAL_MALLOC']: GC_MALLOC = "GC_local_malloc" else: GC_MALLOC = "GC_malloc" malloc_fn_ptr = rffi.llexternal( GC_MALLOC, [lltype.Signed], # size_t, but good enough llmemory.GCREF, compilation_info=compilation_info, sandboxsafe=True, _nowrapper=True) cls.malloc_fn_ptr = malloc_fn_ptr return malloc_fn_ptr
def __init__(self, gcdescr, translator): GcLLDescription.__init__(self, gcdescr, translator) # grab a pointer to the Boehm 'malloc' function from pypy.rpython.tool import rffi_platform compilation_info = rffi_platform.configure_boehm() # Versions 6.x of libgc needs to use GC_local_malloc(). # Versions 7.x of libgc removed this function; GC_malloc() has # the same behavior if libgc was compiled with # THREAD_LOCAL_ALLOC. class CConfig: _compilation_info_ = compilation_info HAS_LOCAL_MALLOC = rffi_platform.Has("GC_local_malloc") config = rffi_platform.configure(CConfig) if config['HAS_LOCAL_MALLOC']: GC_MALLOC = "GC_local_malloc" else: GC_MALLOC = "GC_malloc" malloc_fn_ptr = rffi.llexternal( GC_MALLOC, [lltype.Signed], # size_t, but good enough llmemory.GCREF, compilation_info=compilation_info, sandboxsafe=True, _nowrapper=True) self.funcptr_for_new = malloc_fn_ptr # on some platform GC_init is required before any other # GC_* functions, call it here for the benefit of tests # XXX move this to tests init_fn_ptr = rffi.llexternal("GC_init", [], lltype.Void, compilation_info=compilation_info, sandboxsafe=True, _nowrapper=True) init_fn_ptr()
def test_nested_structs_in_the_opposite_order(): class CConfig: _compilation_info_ = ExternalCompilationInfo(post_include_bits=[ """ struct y { int foo; unsigned long bar; }; struct x { char c; struct y y; }; """ ]) y = rffi_platform.Struct("struct y", [("bar", rffi.SHORT)]) x = rffi_platform.Struct("struct x", [("y", y)]) res = rffi_platform.configure(CConfig) c_x = res["x"] c_y = res["y"] assert isinstance(c_x, lltype.Struct) assert isinstance(c_y, lltype.Struct) assert c_x.c_y is c_y
def __init__(self, gcdescr, translator): GcLLDescription.__init__(self, gcdescr, translator) # grab a pointer to the Boehm 'malloc' function from pypy.rpython.tool import rffi_platform compilation_info = rffi_platform.check_boehm() # Versions 6.x of libgc needs to use GC_local_malloc(). # Versions 7.x of libgc removed this function; GC_malloc() has # the same behavior if libgc was compiled with # THREAD_LOCAL_ALLOC. class CConfig: _compilation_info_ = compilation_info HAS_LOCAL_MALLOC = rffi_platform.Has("GC_local_malloc") config = rffi_platform.configure(CConfig) if config['HAS_LOCAL_MALLOC']: GC_MALLOC = "GC_local_malloc" else: GC_MALLOC = "GC_malloc" malloc_fn_ptr = rffi.llexternal(GC_MALLOC, [lltype.Signed], # size_t, but good enough llmemory.GCREF, compilation_info=compilation_info, sandboxsafe=True, _nowrapper=True) self.funcptr_for_new = malloc_fn_ptr # on some platform GC_init is required before any other # GC_* functions, call it here for the benefit of tests # XXX move this to tests init_fn_ptr = rffi.llexternal("GC_init", [], lltype.Void, compilation_info=compilation_info, sandboxsafe=True, _nowrapper=True) init_fn_ptr()
'F_GETLK64', 'F_SETLK64', 'F_SETLKW64', 'F_GETLK', 'F_SETLK', 'F_SETLKW', 'F_GETOWN', 'F_SETOWN', 'F_RDLCK', 'F_WRLCK', 'F_SETLEASE', 'F_GETLEASE', 'F_NOTIFY', 'F_EXLCK', 'F_SHLCK', 'DN_ACCESS', 'DN_MODIFY', 'DN_CREATE', 'DN_DELETE', 'DN_RENAME', 'DN_ATTRIB', 'DN_MULTISHOT', 'I_NREAD', 'I_PUSH', 'I_POP', 'I_LOOK', 'I_FLUSH', 'I_SRDOPT', 'I_GRDOPT', 'I_STR', 'I_SETSIG', 'I_GETSIG', 'I_FIND', 'I_LINK', 'I_UNLINK', 'I_PEEK', 'I_FDINSERT', 'I_SENDFD', 'I_RECVFD', 'I_SWROPT', 'I_LIST', 'I_PLINK', 'I_PUNLINK', 'I_FLUSHBAND', 'I_CKBAND', 'I_GETBAND', 'I_ATMARK', 'I_SETCLTIME', 'I_GETCLTIME', 'I_CANPUT'] for name in constant_names: setattr(CConfig, name, platform.DefinedConstantInteger(name)) class cConfig(object): pass for k, v in platform.configure(CConfig).items(): setattr(cConfig, k, v) cConfig.flock.__name__ = "_flock" if "linux" in sys.platform: cConfig.F_GETSIG = 11 cConfig.F_SETSIG = 10 cConfig.F_GETLEASE = 1025 cConfig.F_SETLEASE = 1024 # needed to export the constants inside and outside. see __init__.py for name in constant_names: value = getattr(cConfig, name) if value is not None: constants[name] = value locals().update(constants)
FILE = rffi.COpaquePtr('FILE') BZFILE = rffi.COpaquePtr('BZFILE') constants = {} constant_names = ['BZ_RUN', 'BZ_FLUSH', 'BZ_FINISH', 'BZ_OK', 'BZ_RUN_OK', 'BZ_FLUSH_OK', 'BZ_FINISH_OK', 'BZ_STREAM_END', 'BZ_SEQUENCE_ERROR', 'BZ_PARAM_ERROR', 'BZ_MEM_ERROR', 'BZ_DATA_ERROR', 'BZ_DATA_ERROR_MAGIC', 'BZ_IO_ERROR', 'BZ_UNEXPECTED_EOF', 'BZ_OUTBUFF_FULL', 'BZ_CONFIG_ERROR'] for name in constant_names: setattr(CConfig, name, platform.DefinedConstantInteger(name)) class cConfig(object): pass for k, v in platform.configure(CConfig).items(): setattr(cConfig, k, v) if not cConfig.CHECK_LIBRARY: raise ImportError("Invalid bz2 library") for name in constant_names: value = getattr(cConfig, name) if value is not None: constants[name] = value locals().update(constants) off_t = cConfig.off_t bz_stream = lltype.Ptr(cConfig.bz_stream) BUFSIZ = cConfig.BUFSIZ SEEK_SET = cConfig.SEEK_SET BZ_OK = cConfig.BZ_OK
def setup(): INSPECT = { 'b': 'signed char', 'h': 'signed short', 'i': 'signed int', 'l': 'signed long', 'q': 'signed long long', 'B': 'unsigned char', 'H': 'unsigned short', 'I': 'unsigned int', 'L': 'unsigned long', 'Q': 'unsigned long long', 'P': 'char *', 'f': 'float', 'd': 'double', '?': '_Bool', } pre_include_bits = [ """ #ifdef _MSC_VER #define _Bool char #endif""" ] field_names = dict.fromkeys(INSPECT) for fmtchar, ctype in INSPECT.iteritems(): field_name = ctype.replace(" ", "_").replace("*", "star") field_names[fmtchar] = field_name pre_include_bits.append(""" struct about_%s { char pad; %s field; }; """ % (field_name, ctype)) class CConfig: _compilation_info_ = ExternalCompilationInfo( pre_include_bits=pre_include_bits) for fmtchar, ctype in INSPECT.items(): setattr( CConfig, field_names[fmtchar], rffi_platform.Struct( "struct about_%s" % (field_names[fmtchar], ), [('field', lltype.FixedSizeArray(rffi.CHAR, 1))])) cConfig = rffi_platform.configure(CConfig) for fmtchar, ctype in INSPECT.items(): S = cConfig[field_names[fmtchar]] alignment = rffi.offsetof(S, 'c_field') size = rffi.sizeof(S.c_field) signed = 'a' <= fmtchar <= 'z' if fmtchar == 'f': pack = pack_float unpack = unpack_float elif fmtchar == 'd': pack = pack_double unpack = unpack_double elif fmtchar == '?': pack = std.pack_bool unpack = std.unpack_bool else: pack = std.make_int_packer(size, signed, True) unpack = std.make_int_unpacker(size, signed) native_fmttable[fmtchar] = { 'size': size, 'alignment': alignment, 'pack': pack, 'unpack': unpack }
REG_OPTION_OPEN_LINK REG_LEGAL_OPTION REG_CREATED_NEW_KEY REG_OPENED_EXISTING_KEY REG_WHOLE_HIVE_VOLATILE REG_REFRESH_HIVE REG_NO_LAZY_FLUSH REG_NOTIFY_CHANGE_NAME REG_NOTIFY_CHANGE_ATTRIBUTES REG_NOTIFY_CHANGE_LAST_SET REG_NOTIFY_CHANGE_SECURITY REG_LEGAL_CHANGE_FILTER REG_NONE REG_SZ REG_EXPAND_SZ REG_BINARY REG_DWORD REG_DWORD_LITTLE_ENDIAN REG_DWORD_BIG_ENDIAN REG_LINK REG_MULTI_SZ REG_RESOURCE_LIST REG_FULL_RESOURCE_DESCRIPTOR REG_RESOURCE_REQUIREMENTS_LIST HKEY_LOCAL_MACHINE HKEY_CLASSES_ROOT HKEY_CURRENT_CONFIG HKEY_CURRENT_USER HKEY_DYN_DATA HKEY_LOCAL_MACHINE HKEY_PERFORMANCE_DATATA HKEY_USERS '''.split() for name in constant_names: setattr(CConfig, name, platform.DefinedConstantInteger(name)) constants = {} cConfig = platform.configure(CConfig) constants.update(cConfig) globals().update(cConfig) def external(name, args, result): return rffi.llexternal(name, args, result, compilation_info=eci, calling_conv='win') HKEY = rwin32.HANDLE PHKEY = rffi.CArrayPtr(HKEY) REGSAM = rwin32.DWORD RegSetValue = external( 'RegSetValueA', [HKEY, rffi.CCHARP, rwin32.DWORD, rffi.CCHARP, rwin32.DWORD], rffi.LONG)
def make_win32_traits(traits): from pypy.rlib import rwin32 if traits.str is unicode: suffix = 'W' else: suffix = 'A' class CConfig: _compilation_info_ = ExternalCompilationInfo( includes=['windows.h', 'winbase.h', 'sys/stat.h'], ) WIN32_FIND_DATA = platform.Struct( 'struct _WIN32_FIND_DATA' + suffix, # Only interesting fields [('dwFileAttributes', rwin32.DWORD), ('nFileSizeHigh', rwin32.DWORD), ('nFileSizeLow', rwin32.DWORD), ('ftCreationTime', rwin32.FILETIME), ('ftLastAccessTime', rwin32.FILETIME), ('ftLastWriteTime', rwin32.FILETIME), ('cFileName', lltype.FixedSizeArray(traits.CHAR, 250))]) ERROR_FILE_NOT_FOUND = platform.ConstantInteger('ERROR_FILE_NOT_FOUND') ERROR_NO_MORE_FILES = platform.ConstantInteger('ERROR_NO_MORE_FILES') GetFileExInfoStandard = platform.ConstantInteger( 'GetFileExInfoStandard') FILE_ATTRIBUTE_DIRECTORY = platform.ConstantInteger( 'FILE_ATTRIBUTE_DIRECTORY') FILE_ATTRIBUTE_READONLY = platform.ConstantInteger( 'FILE_ATTRIBUTE_READONLY') INVALID_FILE_ATTRIBUTES = platform.ConstantInteger( 'INVALID_FILE_ATTRIBUTES') ERROR_SHARING_VIOLATION = platform.ConstantInteger( 'ERROR_SHARING_VIOLATION') _S_IFDIR = platform.ConstantInteger('_S_IFDIR') _S_IFREG = platform.ConstantInteger('_S_IFREG') _S_IFCHR = platform.ConstantInteger('_S_IFCHR') _S_IFIFO = platform.ConstantInteger('_S_IFIFO') FILE_TYPE_UNKNOWN = platform.ConstantInteger('FILE_TYPE_UNKNOWN') FILE_TYPE_CHAR = platform.ConstantInteger('FILE_TYPE_CHAR') FILE_TYPE_PIPE = platform.ConstantInteger('FILE_TYPE_PIPE') WIN32_FILE_ATTRIBUTE_DATA = platform.Struct( 'WIN32_FILE_ATTRIBUTE_DATA', [('dwFileAttributes', rwin32.DWORD), ('nFileSizeHigh', rwin32.DWORD), ('nFileSizeLow', rwin32.DWORD), ('ftCreationTime', rwin32.FILETIME), ('ftLastAccessTime', rwin32.FILETIME), ('ftLastWriteTime', rwin32.FILETIME)]) BY_HANDLE_FILE_INFORMATION = platform.Struct( 'BY_HANDLE_FILE_INFORMATION', [('dwFileAttributes', rwin32.DWORD), ('nFileSizeHigh', rwin32.DWORD), ('nFileSizeLow', rwin32.DWORD), ('nNumberOfLinks', rwin32.DWORD), ('nFileIndexHigh', rwin32.DWORD), ('nFileIndexLow', rwin32.DWORD), ('ftCreationTime', rwin32.FILETIME), ('ftLastAccessTime', rwin32.FILETIME), ('ftLastWriteTime', rwin32.FILETIME)]) config = platform.configure(CConfig) def external(*args, **kwargs): kwargs['compilation_info'] = CConfig._compilation_info_ llfunc = rffi.llexternal(calling_conv='win', *args, **kwargs) return staticmethod(llfunc) class Win32Traits: apisuffix = suffix for name in '''WIN32_FIND_DATA WIN32_FILE_ATTRIBUTE_DATA BY_HANDLE_FILE_INFORMATION GetFileExInfoStandard FILE_ATTRIBUTE_DIRECTORY FILE_ATTRIBUTE_READONLY INVALID_FILE_ATTRIBUTES _S_IFDIR _S_IFREG _S_IFCHR _S_IFIFO FILE_TYPE_UNKNOWN FILE_TYPE_CHAR FILE_TYPE_PIPE ERROR_FILE_NOT_FOUND ERROR_NO_MORE_FILES ERROR_SHARING_VIOLATION '''.split(): locals()[name] = config[name] LPWIN32_FIND_DATA = lltype.Ptr(WIN32_FIND_DATA) GET_FILEEX_INFO_LEVELS = rffi.ULONG # an enumeration FindFirstFile = external('FindFirstFile' + suffix, [traits.CCHARP, LPWIN32_FIND_DATA], rwin32.HANDLE) FindNextFile = external('FindNextFile' + suffix, [rwin32.HANDLE, LPWIN32_FIND_DATA], rwin32.BOOL) FindClose = external('FindClose', [rwin32.HANDLE], rwin32.BOOL) GetFileAttributes = external('GetFileAttributes' + suffix, [traits.CCHARP], rwin32.DWORD) SetFileAttributes = external('SetFileAttributes' + suffix, [traits.CCHARP, rwin32.DWORD], rwin32.BOOL) GetFileAttributesEx = external('GetFileAttributesEx' + suffix, [ traits.CCHARP, GET_FILEEX_INFO_LEVELS, lltype.Ptr(WIN32_FILE_ATTRIBUTE_DATA) ], rwin32.BOOL) GetFileInformationByHandle = external( 'GetFileInformationByHandle', [rwin32.HANDLE, lltype.Ptr(BY_HANDLE_FILE_INFORMATION)], rwin32.BOOL) GetFileType = external('GetFileType', [rwin32.HANDLE], rwin32.DWORD) LPSTRP = rffi.CArrayPtr(traits.CCHARP) GetFullPathName = external( 'GetFullPathName' + suffix, [traits.CCHARP, rwin32.DWORD, traits.CCHARP, LPSTRP], rwin32.DWORD) GetCurrentDirectory = external('GetCurrentDirectory' + suffix, [rwin32.DWORD, traits.CCHARP], rwin32.DWORD) SetCurrentDirectory = external('SetCurrentDirectory' + suffix, [traits.CCHARP], rwin32.BOOL) CreateDirectory = external('CreateDirectory' + suffix, [traits.CCHARP, rffi.VOIDP], rwin32.BOOL) SetEnvironmentVariable = external('SetEnvironmentVariable' + suffix, [traits.CCHARP, traits.CCHARP], rwin32.BOOL) DeleteFile = external('DeleteFile' + suffix, [traits.CCHARP], rwin32.BOOL) MoveFile = external('MoveFile' + suffix, [traits.CCHARP, traits.CCHARP], rwin32.BOOL) return Win32Traits
def register_os_listdir(self): # we need a different approach on Windows and on Posix if sys.platform.startswith('win'): class CConfig: _compilation_info_ = ExternalCompilationInfo( includes = ['windows.h'] ) WIN32_FIND_DATA = platform.Struct('struct _WIN32_FIND_DATAA', [('cFileName', lltype.FixedSizeArray(rffi.CHAR, 1))]) INVALID_HANDLE_VALUE = platform.ConstantInteger( 'INVALID_HANDLE_VALUE') ERROR_FILE_NOT_FOUND = platform.ConstantInteger( 'ERROR_FILE_NOT_FOUND') ERROR_NO_MORE_FILES = platform.ConstantInteger( 'ERROR_NO_MORE_FILES') config = platform.configure(CConfig) WIN32_FIND_DATA = config['WIN32_FIND_DATA'] INVALID_HANDLE_VALUE = config['INVALID_HANDLE_VALUE'] ERROR_FILE_NOT_FOUND = config['ERROR_FILE_NOT_FOUND'] ERROR_NO_MORE_FILES = config['ERROR_NO_MORE_FILES'] LPWIN32_FIND_DATA = lltype.Ptr(WIN32_FIND_DATA) HANDLE = rffi.ULONG #MAX_PATH = WIN32_FIND_DATA.c_cFileName.length GetLastError = self.llexternal('GetLastError', [], lltype.Signed) FindFirstFile = self.llexternal('FindFirstFile', [rffi.CCHARP, LPWIN32_FIND_DATA], HANDLE) FindNextFile = self.llexternal('FindNextFile', [HANDLE, LPWIN32_FIND_DATA], rffi.INT) FindClose = self.llexternal('FindClose', [HANDLE], rffi.INT) def os_listdir_llimpl(path): if path and path[-1] not in ('/', '\\', ':'): path += '/' path += '*.*' filedata = lltype.malloc(WIN32_FIND_DATA, flavor='raw') try: result = [] hFindFile = FindFirstFile(path, filedata) if hFindFile == INVALID_HANDLE_VALUE: error = GetLastError() if error == ERROR_FILE_NOT_FOUND: return result else: # XXX guess error code :-( raise OSError(errno.ENOENT, "FindFirstFile failed") while True: name = rffi.charp2str(rffi.cast(rffi.CCHARP, filedata.c_cFileName)) if name != "." and name != "..": # skip these result.append(name) if not FindNextFile(hFindFile, filedata): break # FindNextFile sets error to ERROR_NO_MORE_FILES if # it got to the end of the directory error = GetLastError() FindClose(hFindFile) if error == ERROR_NO_MORE_FILES: return result else: # XXX guess error code :-( raise OSError(errno.EIO, "FindNextFile failed") finally: lltype.free(filedata, flavor='raw') else: compilation_info = ExternalCompilationInfo( includes = ['sys/types.h', 'dirent.h'] ) class CConfig: _compilation_info_ = compilation_info DIRENT = platform.Struct('struct dirent', [('d_name', lltype.FixedSizeArray(rffi.CHAR, 1))]) DIRP = rffi.COpaquePtr('DIR') config = platform.configure(CConfig) DIRENT = config['DIRENT'] DIRENTP = lltype.Ptr(DIRENT) os_opendir = self.llexternal('opendir', [rffi.CCHARP], DIRP, compilation_info=compilation_info) os_readdir = self.llexternal('readdir', [DIRP], DIRENTP, compilation_info=compilation_info) os_closedir = self.llexternal('closedir', [DIRP], rffi.INT, compilation_info=compilation_info) def os_listdir_llimpl(path): dirp = os_opendir(path) if not dirp: raise OSError(rposix.get_errno(), "os_opendir failed") rposix.set_errno(0) result = [] while True: direntp = os_readdir(dirp) if not direntp: error = rposix.get_errno() break namep = rffi.cast(rffi.CCHARP, direntp.c_d_name) name = rffi.charp2str(namep) if name != '.' and name != '..': result.append(name) os_closedir(dirp) if error: raise OSError(error, "os_readdir failed") return result return extdef([str], # a single argument which is a str [str], # returns a list of strings "ll_os.ll_os_listdir", llimpl=os_listdir_llimpl)
"KQ_EV_ADD": "EV_ADD", "KQ_EV_DELETE": "EV_DELETE", "KQ_EV_ENABLE": "EV_ENABLE", "KQ_EV_DISABLE": "EV_DISABLE", "KQ_EV_ONESHOT": "EV_ONESHOT", "KQ_EV_CLEAR": "EV_CLEAR", # "KQ_EV_SYSFLAGS": None, # Python docs says "internal event" .. not defined on FreeBSD # "KQ_EV_FLAG1": None, # Python docs says "internal event" .. not defined on FreeBSD "KQ_EV_EOF": "EV_EOF", "KQ_EV_ERROR": "EV_ERROR" } for symbol in symbol_map.values(): setattr(CConfig, symbol, rffi_platform.DefinedConstantInteger(symbol)) cconfig = rffi_platform.configure(CConfig) kevent = cconfig["kevent"] timespec = cconfig["timespec"] for symbol in symbol_map: globals()[symbol] = cconfig[symbol_map[symbol]] syscall_kqueue = rffi.llexternal("kqueue", [], rffi.INT, compilation_info=eci) syscall_kevent = rffi.llexternal("kevent", [ rffi.INT, lltype.Ptr(rffi.CArray(kevent)), rffi.INT, lltype.Ptr(rffi.CArray(kevent)), rffi.INT, lltype.Ptr(timespec) ],
('wHighVersion', rffi.USHORT), ('szDescription', rffi.CFixedArray(lltype.Char, 1)), # (WSADESCRIPTION_LEN+1) ('szSystemStatus', rffi.CFixedArray(lltype.Char, 1)), # (WSASYS_STATUS_LEN+1) ('iMaxSockets', rffi.USHORT), ('iMaxUdpDg', rffi.USHORT), ('lpVendorInfo', CCHARP) ]) class cConfig: pass cConfig.__dict__.update(platform.configure(CConfig)) sockaddr_ptr.TO.become(cConfig.sockaddr) addrinfo_ptr.TO.become(cConfig.addrinfo) # fill in missing constants with reasonable defaults cConfig.NI_MAXHOST = cConfig.NI_MAXHOST or 1025 cConfig.NI_MAXSERV = cConfig.NI_MAXSERV or 32 cConfig.INET_ADDRSTRLEN = cConfig.INET_ADDRSTRLEN or 16 for name in constant_names: value = getattr(cConfig, name) if value is not None: constants[name] = value for name, default in constants_w_defaults: value = getattr(cConfig, name)
locals()[name] = rffi_platform.ConstantInteger(name) for name in xml_model_list: locals()[name] = rffi_platform.ConstantInteger(name) for name in xml_model_list: locals()[name] = rffi_platform.ConstantInteger(name) for name in xml_model_list: locals()[name] = rffi_platform.ConstantInteger(name) for name in xml_model_list: locals()[name] = rffi_platform.ConstantInteger(name) for name in xml_model_list: locals()[name] = rffi_platform.ConstantInteger(name) for name in xml_model_list: locals()[name] = rffi_platform.ConstantInteger(name) XML_Parser_SIZE = rffi_platform.SizeOf("XML_Parser") for k, v in rffi_platform.configure(CConfigure).items(): globals()[k] = v XML_COMBINED_VERSION = 10000*XML_MAJOR_VERSION+100*XML_MINOR_VERSION+XML_MICRO_VERSION XML_Content_Ptr.TO.become(rffi.CArray(XML_Content)) XML_Encoding_Ptr = lltype.Ptr(XML_Encoding) def expat_external(*a, **kw): kw['compilation_info'] = eci return rffi.llexternal(*a, **kw) INTERNED_CCHARP = "INTERNED" HANDLERS = dict(
#pre_include_bits = ['#define _FILE_OFFSET_BITS 64'], # ^^^ nowadays it's always set in all C files we produce. includes = INCLUDES ) if sys.platform != 'win32': LL_STAT_FIELDS = STAT_FIELDS[:] if TIMESPEC is not None: class CConfig_for_timespec: _compilation_info_ = compilation_info TIMESPEC = TIMESPEC TIMESPEC = lltype.Ptr( platform.configure(CConfig_for_timespec)['TIMESPEC']) def _expand(lst, originalname, timespecname): for i, (_name, _TYPE) in enumerate(lst): if _name == originalname: # replace the 'st_atime' field of type rffi.DOUBLE # with a field 'st_atim' of type 'struct timespec' lst[i] = (timespecname, TIMESPEC.TO) break _expand(LL_STAT_FIELDS, 'st_atime', 'st_atim') _expand(LL_STAT_FIELDS, 'st_mtime', 'st_mtim') _expand(LL_STAT_FIELDS, 'st_ctime', 'st_ctim') del _expand else:
from pypy.rpython.extregistry import ExtRegistryEntry from pypy.annotation import model as annmodel from pypy.rpython import rclass from pypy.rlib import rtermios, rposix from pypy.rpython.tool import rffi_platform from pypy.translator.tool.cbuild import ExternalCompilationInfo eci = ExternalCompilationInfo(includes=['termios.h', 'unistd.h']) class CConfig: _compilation_info_ = eci NCCS = rffi_platform.DefinedConstantInteger('NCCS') NCCS = rffi_platform.configure(CConfig)['NCCS'] TCFLAG_T = rffi.UINT CC_T = rffi.UCHAR SPEED_T = rffi.UINT INT = rffi.INT TERMIOSP = rffi.CStructPtr('termios', ('c_iflag', TCFLAG_T), ('c_oflag', TCFLAG_T), ('c_cflag', TCFLAG_T), ('c_lflag', TCFLAG_T), ('c_cc', lltype.FixedSizeArray(CC_T, NCCS))) def c_external(name, args, result): return rffi.llexternal(name, args, result, compilation_info=eci)
INCLUDES = ['sys/types.h', 'sys/stat.h', 'unistd.h'] compilation_info = ExternalCompilationInfo( pre_include_bits=['#define _FILE_OFFSET_BITS 64'], includes=INCLUDES) from pypy.rpython.tool import rffi_platform as platform class CConfig: # This must be set to 64 on some systems to enable large file support. _compilation_info_ = compilation_info STAT_STRUCT = platform.Struct('struct %s' % _name_struct_stat, LL_STAT_FIELDS) config = platform.configure(CConfig) STAT_STRUCT = lltype.Ptr(config['STAT_STRUCT']) def build_stat_result(st): # only for LL backends if TIMESPEC is not None: atim = st.c_st_atim atime = atim.c_tv_sec + 1E-9 * atim.c_tv_nsec mtim = st.c_st_mtim mtime = mtim.c_tv_sec + 1E-9 * mtim.c_tv_nsec ctim = st.c_st_ctim ctime = ctim.c_tv_sec + 1E-9 * ctim.c_tv_nsec else: atime = st.c_st_atime
def register_os_utime(self): UTIMBUFP = lltype.Ptr(self.UTIMBUF) os_utime = self.llexternal('utime', [rffi.CCHARP, UTIMBUFP], rffi.INT) class CConfig: _compilation_info_ = ExternalCompilationInfo( includes=['sys/time.h'] ) HAVE_UTIMES = platform.Has('utimes') config = platform.configure(CConfig) if config['HAVE_UTIMES']: class CConfig: _compilation_info_ = ExternalCompilationInfo( includes = ['sys/time.h'] ) TIMEVAL = platform.Struct('struct timeval', [('tv_sec', rffi.LONG), ('tv_usec', rffi.LONG)]) config = platform.configure(CConfig) TIMEVAL = config['TIMEVAL'] TIMEVAL2P = rffi.CArrayPtr(TIMEVAL) os_utimes = self.llexternal('utimes', [rffi.CCHARP, TIMEVAL2P], rffi.INT, compilation_info=CConfig._compilation_info_) def os_utime_platform(path, actime, modtime): import math l_times = lltype.malloc(TIMEVAL2P.TO, 2, flavor='raw') fracpart, intpart = math.modf(actime) l_times[0].c_tv_sec = int(intpart) l_times[0].c_tv_usec = int(fracpart * 1E6) fracpart, intpart = math.modf(modtime) l_times[1].c_tv_sec = int(intpart) l_times[1].c_tv_usec = int(fracpart * 1E6) error = os_utimes(path, l_times) lltype.free(l_times, flavor='raw') return error else: # we only have utime(), which does not allow sub-second resolution def os_utime_platform(path, actime, modtime): l_utimbuf = lltype.malloc(UTIMBUFP.TO, flavor='raw') l_utimbuf.c_actime = int(actime) l_utimbuf.c_modtime = int(modtime) error = os_utime(path, l_utimbuf) lltype.free(l_utimbuf, flavor='raw') return error def os_utime_llimpl(path, tp): # NB. this function is specialized; we get one version where # tp is known to be None, and one version where it is known # to be a tuple of 2 floats. if tp is None: error = os_utime(path, lltype.nullptr(UTIMBUFP.TO)) else: actime, modtime = tp error = os_utime_platform(path, actime, modtime) error = rffi.cast(lltype.Signed, error) if error == -1: raise OSError(rposix.get_errno(), "os_utime failed") os_utime_llimpl._annspecialcase_ = 'specialize:argtype(1)' s_string = SomeString() s_tuple_of_2_floats = SomeTuple([SomeFloat(), SomeFloat()]) def os_utime_normalize_args(s_path, s_times): # special handling of the arguments: they can be either # [str, (float, float)] or [str, s_None], and get normalized # to exactly one of these two. if not s_string.contains(s_path): raise Exception("os.utime() arg 1 must be a string, got %s" % ( s_path,)) case1 = s_None.contains(s_times) case2 = s_tuple_of_2_floats.contains(s_times) if case1 and case2: return [s_string, s_ImpossibleValue] #don't know which case yet elif case1: return [s_string, s_None] elif case2: return [s_string, s_tuple_of_2_floats] else: raise Exception("os.utime() arg 2 must be None or a tuple of " "2 floats, got %s" % (s_times,)) return extdef(os_utime_normalize_args, s_None, "ll_os.ll_os_utime", llimpl=os_utime_llimpl)
""" _compilation_info_ = eci # XXX If Z_PREFIX was defined for the libz build, then these types are # named z_uInt, z_uLong, and z_Bytef instead. uInt = rffi_platform.SimpleType('uInt', rffi.UINT) uLong = rffi_platform.SimpleType('uLong', rffi.ULONG) Bytef = rffi_platform.SimpleType('Bytef', rffi.UCHAR) voidpf = rffi_platform.SimpleType('voidpf', rffi.VOIDP) ZLIB_VERSION = rffi_platform.DefinedConstantString('ZLIB_VERSION') for _name in constantnames: setattr(SimpleCConfig, _name, rffi_platform.ConstantInteger(_name)) config = rffi_platform.configure(SimpleCConfig) voidpf = config['voidpf'] uInt = config['uInt'] uLong = config['uLong'] Bytef = config['Bytef'] Bytefp = lltype.Ptr(lltype.Array(Bytef, hints={'nolength': True})) ZLIB_VERSION = config['ZLIB_VERSION'] for _name in constantnames: globals()[_name] = config[_name] # The following parameter is copied from zutil.h, version 0.95, # according to CPython's zlibmodule.c DEFLATED = Z_DEFLATED if MAX_MEM_LEVEL >= 8:
def configure_types(): for config in (CConfig, CConfig2): for name, TYPE in rffi_platform.configure(config).iteritems(): if name in TYPES: TYPES[name].become(TYPE)
else: fileno = rffi.llexternal('fileno', [FILEP], rffi.INT) constant_names = """ Py_TPFLAGS_READY Py_TPFLAGS_READYING Py_TPFLAGS_HAVE_GETCHARBUFFER METH_COEXIST METH_STATIC METH_CLASS METH_NOARGS METH_VARARGS METH_KEYWORDS METH_O Py_TPFLAGS_HEAPTYPE Py_TPFLAGS_HAVE_CLASS Py_LT Py_LE Py_EQ Py_NE Py_GT Py_GE """.split() for name in constant_names: setattr(CConfig_constants, name, rffi_platform.ConstantInteger(name)) udir.join('pypy_decl.h').write("/* Will be filled later */") udir.join('pypy_macros.h').write("/* Will be filled later */") globals().update(rffi_platform.configure(CConfig_constants)) def copy_header_files(dstdir): assert dstdir.check(dir=True) headers = include_dir.listdir('*.h') + include_dir.listdir('*.inl') for name in ("pypy_decl.h", "pypy_macros.h"): headers.append(udir.join(name)) for header in headers: target = dstdir.join(header.basename) try: header.copy(dstdir) except py.error.EACCES: target.remove() # maybe it was a read-only file header.copy(dstdir) target.chmod(0444) # make the file read-only, to make sure that nobody # edits it by mistake
# This must be set to 64 on some systems to enable large file support. pre_include_bits=['#define _FILE_OFFSET_BITS 64'], includes=INCLUDES) if sys.platform != 'win32': LL_STAT_FIELDS = STAT_FIELDS[:] if TIMESPEC is not None: class CConfig_for_timespec: _compilation_info_ = compilation_info TIMESPEC = TIMESPEC TIMESPEC = lltype.Ptr( platform.configure(CConfig_for_timespec)['TIMESPEC']) def _expand(lst, originalname, timespecname): for i, (_name, _TYPE) in enumerate(lst): if _name == originalname: # replace the 'st_atime' field of type rffi.DOUBLE # with a field 'st_atim' of type 'struct timespec' lst[i] = (timespecname, TIMESPEC.TO) break _expand(LL_STAT_FIELDS, 'st_atime', 'st_atim') _expand(LL_STAT_FIELDS, 'st_mtime', 'st_mtim') _expand(LL_STAT_FIELDS, 'st_ctime', 'st_ctim') del _expand else:
('release', rffi.VOIDP), ]) for name in ['XML_PARAM_ENTITY_PARSING_NEVER', 'XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE', 'XML_PARAM_ENTITY_PARSING_ALWAYS']: locals()[name] = rffi_platform.ConstantInteger(name) XML_MAJOR_VERSION = rffi_platform.ConstantInteger('XML_MAJOR_VERSION') XML_MINOR_VERSION = rffi_platform.ConstantInteger('XML_MINOR_VERSION') XML_MICRO_VERSION = rffi_platform.ConstantInteger('XML_MICRO_VERSION') XML_FALSE = rffi_platform.ConstantInteger('XML_FALSE') XML_TRUE = rffi_platform.ConstantInteger('XML_TRUE') for name in xml_error_list: locals()[name] = rffi_platform.ConstantInteger(name) for k, v in rffi_platform.configure(CConfigure).items(): globals()[k] = v XML_COMBINED_VERSION = 10000*XML_MAJOR_VERSION+100*XML_MINOR_VERSION+XML_MICRO_VERSION XML_Content_Ptr.TO.become(rffi.CArray(XML_Content)) XML_Encoding_Ptr = lltype.Ptr(XML_Encoding) def expat_external(*a, **kw): kw['compilation_info'] = eci return rffi.llexternal(*a, **kw) INTERNED_CCHARP = "INTERNED" HANDLERS = dict(
eci = ExternalCompilationInfo(includes=["pcre.h"], \ include_dirs=Config.LIBPCRE_INCLUDE_DIRS, \ library_dirs=Config.LIBPCRE_LIBRARY_DIRS, \ libraries=Config.LIBPCRE_LIBRARIES, \ link_extra=Config.LIBPCRE_LINK_FLAGS, \ link_files=[Config.LIBPCRE_A]) class CConfig: _compilation_info_ = eci PCRE_DOTALL = platform.DefinedConstantInteger("PCRE_DOTALL") PCRE_MULTILINE = platform.DefinedConstantInteger("PCRE_MULTILINE") PCRE_INFO_CAPTURECOUNT = platform.DefinedConstantInteger("PCRE_INFO_CAPTURECOUNT") PCRE_ANCHORED = platform.DefinedConstantInteger("PCRE_ANCHORED") PCRE_ERROR_NOMATCH = platform.DefinedConstantInteger("PCRE_ERROR_NOMATCH") cconfig = platform.configure(CConfig) PCREP = rffi.COpaquePtr("pcre") PCRE_DOTALL = cconfig["PCRE_DOTALL"] PCRE_MULTILINE = cconfig["PCRE_MULTILINE"] PCRE_INFO_CAPTURECOUNT = cconfig["PCRE_INFO_CAPTURECOUNT"] PCRE_ANCHORED = cconfig["PCRE_ANCHORED"] PCRE_ERROR_NOMATCH = cconfig["PCRE_ERROR_NOMATCH"] pcre_compile = rffi.llexternal("pcre_compile", \ [rffi.CCHARP, rffi.INT, rffi.CCHARPP, rffi.INTP, rffi.VOIDP], PCREP, compilation_info=eci) pcre_fullinfo = rffi.llexternal("pcre_fullinfo", \ [PCREP, rffi.VOIDP, rffi.INT, rffi.INTP], rffi.INT, compilation_info=eci) pcre_exec = rffi.llexternal("pcre_exec", \ [PCREP, rffi.VOIDP, rffi.CCHARP, rffi.INT, rffi.INT, rffi.INT, rffi.INTP, rffi.INT], \ rffi.INT, compilation_info=eci)
_name_struct_stat = 'stat' INCLUDES = ['sys/types.h', 'sys/stat.h', 'unistd.h'] compilation_info = ExternalCompilationInfo( # This must be set to 64 on some systems to enable large file support. #pre_include_bits = ['#define _FILE_OFFSET_BITS 64'], # ^^^ nowadays it's always set in all C files we produce. includes=INCLUDES) if TIMESPEC is not None: class CConfig_for_timespec: _compilation_info_ = compilation_info TIMESPEC = TIMESPEC TIMESPEC = lltype.Ptr(platform.configure(CConfig_for_timespec)['TIMESPEC']) def posix_declaration(try_to_add=None): global STAT_STRUCT LL_STAT_FIELDS = STAT_FIELDS[:] if try_to_add: LL_STAT_FIELDS.append(try_to_add) if TIMESPEC is not None: def _expand(lst, originalname, timespecname): for i, (_name, _TYPE) in enumerate(lst): if _name == originalname: # replace the 'st_atime' field of type rffi.DOUBLE
def make_utime_impl(traits): from pypy.rlib import rwin32 win32traits = make_win32_traits(traits) from pypy.rpython.module.ll_os_stat import time_t_to_FILE_TIME class CConfig: _compilation_info_ = ExternalCompilationInfo(includes=['windows.h'], ) FILE_WRITE_ATTRIBUTES = platform.ConstantInteger( 'FILE_WRITE_ATTRIBUTES') OPEN_EXISTING = platform.ConstantInteger('OPEN_EXISTING') FILE_FLAG_BACKUP_SEMANTICS = platform.ConstantInteger( 'FILE_FLAG_BACKUP_SEMANTICS') globals().update(platform.configure(CConfig)) CreateFile = rffi.llexternal('CreateFile' + win32traits.apisuffix, [ traits.CCHARP, rwin32.DWORD, rwin32.DWORD, rwin32.LPSECURITY_ATTRIBUTES, rwin32.DWORD, rwin32.DWORD, rwin32.HANDLE ], rwin32.HANDLE, calling_conv='win') GetSystemTime = rffi.llexternal('GetSystemTime', [lltype.Ptr(rwin32.SYSTEMTIME)], lltype.Void, calling_conv='win') SystemTimeToFileTime = rffi.llexternal( 'SystemTimeToFileTime', [lltype.Ptr(rwin32.SYSTEMTIME), lltype.Ptr(rwin32.FILETIME)], rwin32.BOOL, calling_conv='win') SetFileTime = rffi.llexternal('SetFileTime', [ rwin32.HANDLE, lltype.Ptr(rwin32.FILETIME), lltype.Ptr(rwin32.FILETIME), lltype.Ptr(rwin32.FILETIME) ], rwin32.BOOL, calling_conv='win') @specialize.argtype(1) def os_utime_llimpl(path, tp): hFile = CreateFile(path, FILE_WRITE_ATTRIBUTES, 0, None, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, rwin32.NULL_HANDLE) if hFile == rwin32.INVALID_HANDLE_VALUE: raise rwin32.lastWindowsError() ctime = lltype.nullptr(rwin32.FILETIME) atime = lltype.malloc(rwin32.FILETIME, flavor='raw') mtime = lltype.malloc(rwin32.FILETIME, flavor='raw') try: if tp is None: now = lltype.malloc(rwin32.SYSTEMTIME, flavor='raw') try: GetSystemTime(now) if (not SystemTimeToFileTime(now, atime) or not SystemTimeToFileTime(now, mtime)): raise rwin32.lastWindowsError() finally: lltype.free(now, flavor='raw') else: actime, modtime = tp time_t_to_FILE_TIME(actime, atime) time_t_to_FILE_TIME(modtime, mtime) if not SetFileTime(hFile, ctime, atime, mtime): raise rwin32.lastWindowsError() finally: rwin32.CloseHandle(hFile) lltype.free(atime, flavor='raw') lltype.free(mtime, flavor='raw') return os_utime_llimpl
def setup(): INSPECT = {'b': 'signed char', 'h': 'signed short', 'i': 'signed int', 'l': 'signed long', 'q': 'signed long long', 'B': 'unsigned char', 'H': 'unsigned short', 'I': 'unsigned int', 'L': 'unsigned long', 'Q': 'unsigned long long', 'P': 'char *', 'f': 'float', 'd': 'double', '?': '_Bool', } pre_include_bits = [""" #ifdef _MSC_VER #define _Bool char #endif"""] field_names = dict.fromkeys(INSPECT) for fmtchar, ctype in INSPECT.iteritems(): field_name = ctype.replace(" ", "_").replace("*", "star") field_names[fmtchar] = field_name pre_include_bits.append(""" struct about_%s { char pad; %s field; }; """ % (field_name, ctype)) class CConfig: _compilation_info_ = ExternalCompilationInfo( pre_include_bits = pre_include_bits ) for fmtchar, ctype in INSPECT.items(): setattr(CConfig, field_names[fmtchar], rffi_platform.Struct( "struct about_%s" % (field_names[fmtchar],), [('field', lltype.FixedSizeArray(rffi.CHAR, 1))])) cConfig = rffi_platform.configure(CConfig) for fmtchar, ctype in INSPECT.items(): S = cConfig[field_names[fmtchar]] alignment = rffi.offsetof(S, 'c_field') size = rffi.sizeof(S.c_field) signed = 'a' <= fmtchar <= 'z' if fmtchar == 'f': pack = pack_float unpack = unpack_float elif fmtchar == 'd': pack = pack_double unpack = unpack_double elif fmtchar == '?': pack = std.pack_bool unpack = std.unpack_bool else: pack = std.make_int_packer(size, signed, True) unpack = std.make_int_unpacker(size, signed) native_fmttable[fmtchar] = {'size': size, 'alignment': alignment, 'pack': pack, 'unpack': unpack}
# This must be set to 64 on some systems to enable large file support. pre_include_bits = ['#define _FILE_OFFSET_BITS 64'], includes = INCLUDES ) if sys.platform != 'win32': LL_STAT_FIELDS = STAT_FIELDS[:] if TIMESPEC is not None: class CConfig_for_timespec: _compilation_info_ = compilation_info TIMESPEC = TIMESPEC TIMESPEC = lltype.Ptr( platform.configure(CConfig_for_timespec)['TIMESPEC']) def _expand(lst, originalname, timespecname): for i, (_name, _TYPE) in enumerate(lst): if _name == originalname: # replace the 'st_atime' field of type rffi.DOUBLE # with a field 'st_atim' of type 'struct timespec' lst[i] = (timespecname, TIMESPEC.TO) break _expand(LL_STAT_FIELDS, 'st_atime', 'st_atim') _expand(LL_STAT_FIELDS, 'st_mtime', 'st_mtim') _expand(LL_STAT_FIELDS, 'st_ctime', 'st_ctim') del _expand else:
from pypy.rpython.extregistry import ExtRegistryEntry from pypy.annotation import model as annmodel from pypy.rpython import rclass from pypy.rlib import rtermios, rposix from pypy.rpython.tool import rffi_platform from pypy.translator.tool.cbuild import ExternalCompilationInfo eci = ExternalCompilationInfo( includes = ['termios.h', 'unistd.h'] ) class CConfig: _compilation_info_ = eci NCCS = rffi_platform.DefinedConstantInteger('NCCS') NCCS = rffi_platform.configure(CConfig)['NCCS'] TCFLAG_T = rffi.UINT CC_T = rffi.UCHAR SPEED_T = rffi.UINT INT = rffi.INT TERMIOSP = rffi.CStructPtr('termios', ('c_iflag', TCFLAG_T), ('c_oflag', TCFLAG_T), ('c_cflag', TCFLAG_T), ('c_lflag', TCFLAG_T), ('c_cc', lltype.FixedSizeArray(CC_T, NCCS))) def c_external(name, args, result): return rffi.llexternal(name, args, result, compilation_info=eci) c_tcsetattr = c_external('tcsetattr', [INT, INT, TERMIOSP], INT) c_cfgetispeed = c_external('cfgetispeed', [TERMIOSP], SPEED_T)
if _WIN: from pypy.rlib import rwin32 eci = ExternalCompilationInfo( includes=['windows.h', 'wincrypt.h'], libraries=['advapi32'], ) class CConfig: _compilation_info_ = eci PROV_RSA_FULL = rffi_platform.ConstantInteger("PROV_RSA_FULL") CRYPT_VERIFYCONTEXT = rffi_platform.ConstantInteger( "CRYPT_VERIFYCONTEXT") globals().update(rffi_platform.configure(CConfig)) HCRYPTPROV = rwin32.ULONG_PTR CryptAcquireContext = rffi.llexternal('CryptAcquireContextA', [ rffi.CArrayPtr(HCRYPTPROV), rwin32.LPCSTR, rwin32.LPCSTR, rwin32.DWORD, rwin32.DWORD ], rwin32.BOOL, calling_conv='win', compilation_info=eci) CryptGenRandom = rffi.llexternal( 'CryptGenRandom', [HCRYPTPROV, rwin32.DWORD, rffi.CArrayPtr(rwin32.BYTE)],
eci = eci.merge(RSDL.eci) eci = eci.merge(eci) eci = eci.merge(eci) ChunkPtr = lltype.Ptr(lltype.ForwardReference()) class CConfig: _compilation_info_ = eci Chunk = platform.Struct('Mix_Chunk', [('allocated', rffi.INT), ('abuf', RSDL.Uint8P), ('alen', RSDL.Uint32), ('volume', RSDL.Uint8)]) globals().update(platform.configure(CConfig)) ChunkPtr.TO.become(Chunk) Buffer = rffi.CArray(RSDL.Uint8) def external(name, args, result): return rffi.llexternal(name, args, result, compilation_info=eci) OpenAudio = external('Mix_OpenAudio', [rffi.INT, RSDL.Uint16, rffi.INT, rffi.INT], rffi.INT) CloseAudio = external('Mix_CloseAudio', [], lltype.Void)
JSType = platform.SimpleType('JSType', rffi.INT) JSPropertyAttributes = platform.SimpleType('JSPropertyAttributes', rffi.INT) c_bool = platform.SimpleType('bool', rffi.INT) for name in [ 'kJSTypeUndefined', 'kJSTypeNull', 'kJSTypeBoolean', 'kJSTypeNumber', 'kJSTypeString', 'kJSTypeObject', 'kJSPropertyAttributeNone', 'kJSPropertyAttributeReadOnly', 'kJSPropertyAttributeDontEnum', 'kJSPropertyAttributeDontDelete' ]: setattr(Configure, name, platform.ConstantInteger(name)) globals().update(platform.configure(Configure)) NULL = lltype.nullptr(rffi.VOIDP.TO) # ------------------------------------------------------------------------------ # globals # ------------------------------------------------------------------------------ _JSEvaluateScript = external('JSEvaluateScript', [ JSContextRef, JSStringRef, JSObjectRef, JSStringRef, rffi.INT, JSValueRefP ], JSValueRef) # args are: context, script, this (can be NULL), # sourceURL (can be NULL, for exceptions), startingLineNumber, # exception pointer (can be NULL)
"KQ_EV_ADD": "EV_ADD", "KQ_EV_DELETE": "EV_DELETE", "KQ_EV_ENABLE": "EV_ENABLE", "KQ_EV_DISABLE": "EV_DISABLE", "KQ_EV_ONESHOT": "EV_ONESHOT", "KQ_EV_CLEAR": "EV_CLEAR", # "KQ_EV_SYSFLAGS": None, # Python docs says "internal event" .. not defined on FreeBSD # "KQ_EV_FLAG1": None, # Python docs says "internal event" .. not defined on FreeBSD "KQ_EV_EOF": "EV_EOF", "KQ_EV_ERROR": "EV_ERROR" } for symbol in symbol_map.values(): setattr(CConfig, symbol, rffi_platform.DefinedConstantInteger(symbol)) cconfig = rffi_platform.configure(CConfig) kevent = cconfig["kevent"] timespec = cconfig["timespec"] for symbol in symbol_map: globals()[symbol] = cconfig[symbol_map[symbol]] syscall_kqueue = rffi.llexternal( "kqueue", [], rffi.INT, compilation_info=eci )