class signal_h(c.Test): header = c.header_test('signal.h') sig_atomic_t = c.type_test() SIG_DFL = c.macro_test() SIG_ERR = c.macro_test() SIG_IGN = c.macro_test() SIGABRT = c.macro_test() SIGFPE = c.macro_test() SIGILL = c.macro_test() SIGINT = c.macro_test() SIGSEGV = c.macro_test() SIGTERM = c.macro_test() signal = c.function_test(c.Function('void', 'int'), 'int', c.Function('void', 'int'), test=''' #include <signal.h> void foo(int x) {} int main() { void (*f)(int) = signal(SIGTERM, foo); return 0; } ''') raise_ = c.function_test('int', 'int', name='raise', test=''' #include <signal.h> int main() { signal(SIGTERM, SIG_IGN); return raise(SIGTERM) == 0 ? 0 : 1; } ''')
class sys_mman_h(c.Test): header = c.header_test('sys/mman.h') MAP_FAILED = c.macro_test() MAP_FIXED = c.macro_test() MAP_PRIVATE = c.macro_test() MAP_SHARED = c.macro_test() MCL_CURRENT = c.macro_test() MCL_FUTURE = c.macro_test() MS_ASYNC = c.macro_test() MS_INVALIDATE = c.macro_test() MS_SYNC = c.macro_test() POSIX_MADV_DONTNEED = c.macro_test() POSIX_MADV_NORMAL = c.macro_test() POSIX_MADV_RANDOM = c.macro_test() POSIX_MADV_SEQUENTIAL = c.macro_test() POSIX_MADV_WILLNEED = c.macro_test() POSIX_TYPED_MEM_ALLOCATE = c.macro_test() POSIX_TYPED_MEM_ALLOCATE_CONTIG = c.macro_test() POSIX_TYPED_MEM_MAP_ALLOCATABLE = c.macro_test() PROT_EXEC = c.macro_test() PROT_NONE = c.macro_test() PROT_READ = c.macro_test() PROT_WRITE = c.macro_test() mode_t = c.type_test() off_t = c.type_test() size_t = c.type_test() posix_typed_mem_info = c.struct_test(('size_t', 'posix_tmi_length')) mlock = c.function_test('int', 'const void*', 'size_t') mlockall = c.function_test('int', 'int') mmap = c.function_test('void*', 'size_t', 'int', 'int', 'int', 'off_t') mprotect = c.function_test('int', 'void*', 'size_t', 'int') msync = c.function_test('int', 'void*', 'size_t', 'int') munlock = c.function_test('int', 'const void*', 'size_t') munlockall = c.function_test('int', 'void') munmap = c.function_test('int', 'void*', 'size_t') posix_madvise = c.function_test('int', 'void*', 'size_t', 'int') posix_mem_offset = c.function_test('int', 'const void*', 'size_t', 'off_t*', 'size_t*', 'int*') posix_typed_mem_get_info = c.function_test('int', 'int', 'struct posix_typed_mem_info*') posix_typed_mem_open = c.function_test('int', 'const char*', 'int', 'int') shm_open = c.function_test('int', 'const char*', 'int', 'mode_t') shm_unlink = c.function_test('int', 'const char*')
class arpa_inet_h(c.Test): header = c.header_test('arpa/inet.h') in_port_t = c.type_test() in_addr_t = c.type_test() in_addr = c.struct_test(('sa_family_t', 'sin_family'), ('in_port_t', 'sin_port'), ('struct in_addr', 'sin_addr')) INET_ADDRSTRLEN = c.macro_test() INET6_ADDRSTRLEN = c.macro_test() htonl = c.function_test('uint32_t', 'uint32_t') htons = c.function_test('uint16_t', 'uint16_t') ntohl = c.function_test('uint32_t', 'uint32_t') ntohs = c.function_test('uint16_t', 'uint16_t') inet_addr = c.function_test('in_addr_t', 'constchar*') inet_ntoa = c.function_test('char*', 'struct in_addr') inet_ntop = c.function_test('const char*', 'int', 'const void*', 'char*', 'socklen_t') inet_pton = c.function_test('int', 'int', 'const char*', 'void*')
class ieeefp_h(c.Test): header = c.header_test('ieeefp.h') fp_rnd = c.type_test() fpclass_t = c.type_test() FP_CLEAR = c.macro_test() FP_DISABLE = c.macro_test() FP_ENABLE = c.macro_test() FP_SET = c.macro_test() FP_X_DNML = c.macro_test() FP_X_DZ = c.macro_test() FP_X_DZ = c.macro_test() FP_X_IMP = c.macro_test() FP_X_IMP = c.macro_test() FP_X_INV = c.macro_test() FP_X_INV = c.macro_test() FP_X_OFL = c.macro_test() FP_X_OFL = c.macro_test() FP_X_UFL = c.macro_test() FP_X_UFL = c.macro_test() fp_except = c.macro_test() finite = c.function_test('int', 'double') finitef = c.function_test('int', 'float') finitel = c.function_test('int', 'long double') fpclass = c.function_test('fpclass', 'double') fpgetmask = c.function_test('fp_except', 'void') fpgetround = c.function_test('fp_rnd', 'void') fpgetsticky = c.function_test('fp_except', 'void') fpsetmask = c.function_test('fp_except', 'fp_except') fpsetround = c.function_test('fp_rnd', 'fp_rnd') fpsetsticky = c.function_test('fp_except', 'fp_except') isinf = c.function_test('int', 'double') isinff = c.function_test('int', 'float') isinfl = c.function_test('int', 'long double') isnan = c.function_test('int', 'double') isnand = c.function_test('int', 'double') isnanf = c.function_test('int', 'float') isnanl = c.function_test('int', 'long double') unordered = c.function_test('int', 'double', 'double')
class sys_epoll_h(c.Test): header = c.header_test('sys/epoll.h') EPOLLIN = c.macro_test() EPOLLPRI = c.macro_test() EPOLLOUT = c.macro_test() EPOLLRDNORM = c.macro_test() EPOLLRDBAND = c.macro_test() EPOLLWRNORM = c.macro_test() EPOLLWRBAND = c.macro_test() EPOLLMSG = c.macro_test() EPOLLERR = c.macro_test() EPOLLHUP = c.macro_test() EPOLLONESHOT = c.macro_test() EPOLLET = c.macro_test() EPOLL_CTL_ADD = c.macro_test() EPOLL_CTL_DEL = c.macro_test() EPOLL_CTL_MOD = c.macro_test() epoll_data_t = c.type_test() epoll_event = c.struct_test(('uint32_t', 'events'), ('epoll_data_t', 'data')) epoll_create = c.function_test('int', 'int', test=''' #include <sys/epoll.h> int main(int argc, char** argv) { int efd = epoll_create(20); return (-1 == efd) ? 1 : 0; } ''') epoll_ctl = c.function_test('int', 'int', 'int', 'int', 'struct epoll_event*', test=''' #include <stdio.h> #include <sys/epoll.h> int main(int argc, char** argv) { int efd = epoll_create(20); struct epoll_event event; return epoll_ctl(efd, EPOLL_CTL_ADD, fileno(stdin), &event) == 0 ? 0 : 1; } ''') epoll_wait = c.function_test('int', 'int', 'struct epoll_event*', 'int', 'int')
class setjmp_h(c99.setjmp_h): sigjmp_buf = c.type_test() siglongjmp = c.function_test('void', 'sigjmp_buf', 'int', test=''' #include <setjmp.h> int main() { jmp_buf env; int i = sigsetjmp(env, 0); if (i == 2) return 0; siglongjmp(env, 2); return 2; } ''') @property def sigsetjmp(self): if self.siglongjmp: return c.Function('int', 'sigjmp_buf', 'int')
class stdarg_h(c.Test): header = c.header_test('stdarg.h') va_list = c.type_test() va_start = c.macro_test(test=''' #include <stdarg.h> int f(int x, ...) { int res = 0; va_list ap; va_start(ap, x); res = x == 1 && va_arg(ap, int) == 3 && va_arg(ap, int) == 'a' && va_arg(ap, double) == 4.5; va_end(ap); return res; } int main() { return f(1, 3, 'a', 4.5) == 1 ? 0 : 1; } ''') va_arg = c.macro_test(test=va_list.test) va_end = c.macro_test(test=va_list.test)
class setjmp_h(c.Test): header = c.header_test('setjmp.h') jmp_buf = c.type_test() longjmp = c.function_test('void', 'jmp_buf', 'int', test=''' #include <setjmp.h> int main() { jmp_buf env; int i = setjmp(env); if (i == 2) return 0; longjmp(env, 2); return 2; } ''') @property def setjmp(self): if self.longjmp: return c.Function('int', 'jmp_buf')
class types(c.Test): # We put char last as the signedness is platform dependent. signed_char = c.int_type_test(name='signed char') unsigned_char = c.int_type_test(name='unsigned char') char = c.int_type_test() short = c.int_type_test() signed_short = c.int_type_test(name='signed short') unsigned_short = c.int_type_test(name='unsigned short') int = c.int_type_test() signed_int = c.int_type_test(name='signed int') unsigned_int = c.int_type_test(name='unsigned int') long = c.int_type_test() signed_long = c.int_type_test(name='signed long') unsigned_long = c.int_type_test(name='unsigned long') long_long = c.int_type_test(name='long long') signed_long_long = c.int_type_test(name='signed long long') unsigned_long_long = c.int_type_test(name='unsigned long long') float = c.type_test() double = c.type_test() long_double = c.type_test(name='long double') voidp = c.type_test(name='void*') enum = c.type_test(test=''' #include <stddef.h> #include <stdio.h> typedef enum enum_t {tag} type; struct TEST { char c; type mem; }; int main() { printf("%d\\n", (int)offsetof(struct TEST, mem)); printf("%d\\n", (int)sizeof(type)); return 0; } ''') def structural_alias(self, ctype): if ctype is None: return None for name, type_ in self.int_types(): if type_ is None: continue if isinstance(ctype, c.IntType): if type_ == ctype: return name elif type_.size == ctype.size and \ type_.alignment == ctype.alignment: return name return None @fbuild.db.cachemethod def conversion_map(self, *args, **kwargs): type_pairs = [(name1, name2) for name1, type1 in self.int_types() if type1 is not None for name2, type2 in self.int_types() if type2 is not None] lines = [] for t1, t2 in type_pairs: lines.append('printf("%%d %%d\\n", ' '(int)sizeof((%(t1)s)0 + (%(t2)s)0), ' '(%(t1)s)~3 + (%(t2)s)1 < (%(t1)s)0 + (%(t2)s)0);' % { 't1': t1, 't2': t2 }) code = ''' #include <stdio.h> int main(int argc, char** argv) { %s return 0; } ''' % '\n'.join(lines) try: stdout, stderr = self.builder.tempfile_run(code, *args, **kwargs) except fbuild.ExecutionError: raise fbuild.ConfigFailed('failed to detect type conversions') lookup = {(t.size, t.signed): self.structural_alias(t) for n, t in self.int_types() if t is not None} d = {} for line, (t1, t2) in zip(stdout.decode('utf-8').split('\n'), type_pairs): size, sign = line.split() d[(t1, t2)] = lookup[(int(size), int(sign) == 1)] return d
class dirent_h(c.Test): header = c.header_test('dirent.h') DIR = c.type_test() dirent = c.struct_test(('ino_t', 'd_ino'), ('char*', 'd_name')) ino_t = c.type_test() closedir = c.function_test('int', 'DIR*', test=''' #include <dirent.h> int main() { DIR* d = opendir("."); struct dirent* s; long l; if (!d) return 1; s = readdir(d); seekdir(d, 0); l = telldir(d); rewinddir(d); return closedir(d); } ''') @property def opendir(self): if self.closedir: return c.Function('DIR*', 'const char*') @property def readdir(self): if self.closedir: return c.Function('struct dirent*', 'DIR*') readdir_r = c.function_test('int', 'DIR*', 'struct dirent*', 'struct dirent**', test=''' #include <dirent.h> int main() { DIR* d = opendir("."); struct dirent s; struct dirent* p; if (!d) return 1; if (readdir_r(d, &s, &p) != 0) return 1; return closedir(d); } ''') @property def rewinddir(self): if self.closedir: return c.Function('void', 'DIR*') @property def seekdir(self): if self.closedir: return c.Function('void', 'DIR*', 'long') @property def telldir(self): if self.closedir: return c.Function('long', 'DIR*')
class regex_h(regex_h): reg_errcode_t = c.type_test()
class pthread_h(c.Test): header = c.header_test('pthread.h') PTHREAD_BARRIER_SERIAL_THREAD = c.macro_test() PTHREAD_CANCEL_ASYNCHRONOUS = c.macro_test() PTHREAD_CANCEL_ENABLE = c.macro_test() PTHREAD_CANCEL_DEFERRED = c.macro_test() PTHREAD_CANCEL_DISABLE = c.macro_test() PTHREAD_CANCELED = c.macro_test() PTHREAD_COND_INITIALIZER = c.macro_test() PTHREAD_CREATE_DETACHED = c.macro_test() PTHREAD_CREATE_JOINABLE = c.macro_test() PTHREAD_EXPLICIT_SCHED = c.macro_test() PTHREAD_INHERIT_SCHED = c.macro_test() PTHREAD_MUTEX_DEFAULT = c.macro_test() PTHREAD_MUTEX_ERRORCHECK = c.macro_test() PTHREAD_MUTEX_INITIALIZER = c.macro_test() PTHREAD_MUTEX_NORMAL = c.macro_test() PTHREAD_MUTEX_RECURSIVE = c.macro_test() PTHREAD_ONCE_INIT = c.macro_test() PTHREAD_PRIO_INHERIT = c.macro_test() PTHREAD_PRIO_NONE = c.macro_test() PTHREAD_PRIO_PROTECT = c.macro_test() PTHREAD_PROCESS_SHARED = c.macro_test() PTHREAD_PROCESS_PRIVATE = c.macro_test() PTHREAD_SCOPE_PROCESS = c.macro_test() PTHREAD_SCOPE_SYSTEM = c.macro_test() pthread_attr_t = c.type_test() pthread_barrier_t = c.type_test() pthread_barrierattr_t = c.type_test() pthread_cond_t = c.type_test() pthread_condattr_t = c.type_test() pthread_key_t = c.type_test() pthread_mutex_t = c.type_test() pthread_mutexattr_t = c.type_test() pthread_once_t = c.type_test() pthread_rwlock_t = c.type_test() pthread_rwlockattr_t = c.type_test() pthread_spinlock_t = c.type_test() pthread_t = c.type_test() pthread_atfork = c.function_test('int', 'void (*)(void)', 'void (*)(void)', 'void (*)(void)') @property def pthread_attr_destroy(self): if self.pthread_create: return c.Function('int', 'pthread_attr_t*') pthread_attr_getdetachstate = c.function_test('int', 'const pthread_attr_t*', 'int*') pthread_attr_getguardsize = c.function_test('int', 'const pthread_attr_t*', 'size_t*') pthread_attr_getinheritsched = c.function_test('int', 'const pthread_attr_t*', 'int*') pthread_attr_getschedparam = c.function_test('int', 'const pthread_attr_t*', 'struct sched_param*') pthread_attr_getschedpolicy = c.function_test('int', 'const pthread_attr_t*', 'int*') pthread_attr_getscope = c.function_test('int', 'const pthread_attr_t*', 'int*') pthread_attr_getstack = c.function_test('int', 'const pthread_attr_t*', 'void**', 'size_t*') pthread_attr_getstackaddr = c.function_test('int', 'const pthread_attr_t*', 'void**') pthread_attr_getstacksize = c.function_test('int', 'const pthread_attr_t*', 'size_t*') @property def pthread_attr_init(self): if self.pthread_create: return c.Function('int', 'pthread_attr_t*') @property def pthread_attr_setdetachstate(self): if self.pthread_create: return c.Function('int', 'pthread_attr_t*', 'int') pthread_attr_setguardsize = c.function_test('int', 'pthread_attr_t*', 'size_t') pthread_attr_setinheritsched = c.function_test('int', 'pthread_attr_t*', 'int') pthread_attr_setschedparam = c.function_test('int', 'pthread_attr_t*', 'const struct sched_param*') pthread_attr_setschedpolicy = c.function_test('int', 'pthread_attr_t*', 'int') pthread_attr_setscope = c.function_test('int', 'pthread_attr_t*', 'int') pthread_attr_setstack = c.function_test('int', 'pthread_attr_t*', 'void*', 'size_t') pthread_attr_setstackaddr = c.function_test('int', 'pthread_attr_t*', 'void*') pthread_attr_setstacksize = c.function_test('int', 'pthread_attr_t*', 'size_t') @property def pthread_barrier_destroy(self): if self.pthread_barrier_init: return c.Function('int', 'pthread_barrier_t*') pthread_barrier_init = c.function_test('int', 'pthread_barrier_t*', 'const pthread_barrierattr_t*', 'unsigned', test=''' #include <pthread.h> int main() { pthread_barrier_t barrier; if (pthread_barrier_init(&barrier, 0, 1) != 0) return 1; if (pthread_barrier_wait(&barrier) != PTHREAD_BARRIER_SERIAL_THREAD) return 1; if (pthread_barrier_destroy(&barrier) != 0) return 1; return 0; } ''') @property def pthread_barrier_wait(self): if self.pthread_barrier_init: return c.Function('int', 'pthread_barrier_t*') pthread_barrierattr_destroy = c.function_test('int', 'pthread_barrierattr_t*') pthread_barrierattr_getpshared = c.function_test( 'int', 'const pthread_barrierattr_t*', 'int*') pthread_barrierattr_init = c.function_test('int', 'pthread_barrierattr_t*') pthread_barrierattr_setpshared = c.function_test('int', 'pthread_barrierattr_t*', 'int') pthread_cancel = c.function_test('int', 'pthread_t') pthread_cleanup_push = c.function_test('void', 'void (*)(void*)', 'void*') pthread_cleanup_pop = c.function_test('void', 'int') @property def pthread_cond_broadcast(self): if self.pthread_cond_init: return c.Function('int', 'pthread_cond_t*') @property def pthread_cond_destroy(self): if self.pthread_cond_init: return c.Function('int', 'pthread_cond_t*') pthread_cond_init = c.function_test('int', 'pthread_cond_t*', 'const pthread_condattr_t*', test=''' #include <pthread.h> int main() { pthread_cond_t cond = PTHREAD_COND_INITIALIZER; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; struct timespec t = { 0, 0 }; if (pthread_mutex_init(&mutex, 0) != 0) return 1; if (pthread_mutex_lock(&mutex) != 0) return 1; if (pthread_cond_init(&cond, 0) != 0) return 1; if (pthread_cond_broadcast(&cond) != 0) return 1; if (pthread_cond_signal(&cond) != 0) return 1; if (pthread_cond_timedwait(&cond, &mutex, &t) != 0) return 1; if (pthread_cond_wait(&cond, &mutex) != 0) return 1; if (pthread_cond_destroy(&cond) != 0) return 1; return 0; } ''') @property def pthread_cond_signal(self): if self.pthread_cond_init: return c.Function('int', 'pthread_cond_t*') @property def pthread_cond_timedwait(self): if self.pthread_cond_init: return c.Function('int', 'pthread_cond_t*', 'pthread_mutex_t*', 'const struct timespec*') @property def pthread_cond_wait(self): if self.pthread_cond_init: return c.Function('int', 'pthread_cond_t*', 'pthread_mutex_t*') pthread_condattr_destroy = c.function_test('int', 'pthread_condattr_t*') pthread_condattr_getclock = c.function_test('int', 'const pthread_condattr_t*', 'clockid_t*') pthread_condattr_getpshared = c.function_test('int', 'const pthread_condattr_t*', 'int*') pthread_condattr_init = c.function_test('int', 'pthread_condattr_t*') pthread_condattr_setclock = c.function_test('int', 'pthread_condattr_t*', 'clockid_t') pthread_condattr_setpshared = c.function_test('int', 'pthread_condattr_t*', 'int') pthread_create = c.function_test('int', 'pthread_t*', 'const pthread_attr_t*', 'void* (*)(void*)', 'void*', test=''' #include <pthread.h> void* start(void* data) { return NULL; } int main(int argc, char** argv) { pthread_t thr; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); int res = pthread_create(&thr, &attr, start, NULL); pthread_attr_destroy(&attr); return res; } ''') pthread_detach = c.function_test('int', 'pthread_t') pthread_equal = c.function_test('int', 'pthread_t', 'pthread_t') pthread_exit = c.function_test('void', 'void*') pthread_getconcurrency = c.function_test('int', 'void') pthread_getcpuclockid = c.function_test('int', 'pthread_t', 'clockid_t*') pthread_getschedparam = c.function_test('int', 'pthread_t', 'int*', 'struct sched_param*') pthread_getspecific = c.function_test('void*', 'pthread_key_t') pthread_join = c.function_test('int', 'pthread_t', 'void**') pthread_key_create = c.function_test('int', 'pthread_key_t*', 'void (*)(void*)') pthread_key_delete = c.function_test('int', 'pthread_key_t') @property def pthread_mutex_destroy(self): if self.pthread_mutex_init: return c.Function('int', 'pthread_mutex_t*') pthread_mutex_getprioceiling = c.function_test('int', 'const pthread_mutex_t*', 'int*') pthread_mutex_init = c.function_test('int', 'pthread_mutex_t*', 'const pthread_mutexattr_t*', test=''' #include <pthread.h> int main() { pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; if (pthread_mutex_init(&mutex, 0) != 0) return 1; if (pthread_mutex_lock(&mutex) != 0) return 1; if (pthread_mutex_unlock(&mutex) != 0) return 1; if (pthread_mutex_destroy(&mutex) != 0) return 1; return 0; } ''') def pthread_mutex_lock(self): if self.pthread_mutex_init: return c.Function('int', 'pthread_mutex_t*') pthread_mutex_setprioceiling = c.function_test('int', 'pthread_mutex_t*', 'int', 'int*') pthread_mutex_timedlock = c.function_test('int', 'pthread_mutex_t*', 'const struct timespec*', test=''' #include <pthread.h> int main() { pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; struct timespec t = { 0, 0 }; if (pthread_mutex_init(&mutex, 0) != 0) return 1; if (pthread_mutex_timedlock(&mutex, &t) != 0) return 1; if (pthread_mutex_unlock(&mutex) != 0) return 1; if (pthread_mutex_destroy(&mutex) != 0) return 1; return 0; } ''') pthread_mutex_trylock = c.function_test('int', 'pthread_mutex_t*', test=''' #include <pthread.h> int main() { pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; if (pthread_mutex_init(&mutex, 0) != 0) return 1; if (pthread_mutex_trylock(&mutex) != 0) return 1; if (pthread_mutex_unlock(&mutex) != 0) return 1; if (pthread_mutex_destroy(&mutex) != 0) return 1; return 0; } ''') def pthread_mutex_unlock(self): if self.pthread_mutex_init: return c.Function('int', 'pthread_mutex_t*') pthread_mutexattr_destroy = c.function_test('int', 'pthread_mutexattr_t*') pthread_mutexattr_getprioceiling = c.function_test( 'int', 'const pthread_mutexattr_t*', 'int*') pthread_mutexattr_getprotocol = c.function_test( 'int', 'const pthread_mutexattr_t*', 'int*') pthread_mutexattr_getpshared = c.function_test( 'int', 'const pthread_mutexattr_t*', 'int*') pthread_mutexattr_gettype = c.function_test('int', 'const pthread_mutexattr_t*', 'int*') pthread_mutexattr_init = c.function_test('int', 'pthread_mutexattr_t*') pthread_mutexattr_setprioceiling = c.function_test('int', 'pthread_mutexattr_t*', 'int') pthread_mutexattr_setprotocol = c.function_test('int', 'pthread_mutexattr_t*', 'int') pthread_mutexattr_setpshared = c.function_test('int', 'pthread_mutexattr_t*', 'int') pthread_mutexattr_settype = c.function_test('int', 'pthread_mutexattr_t*', 'int') pthread_once = c.function_test('int', 'pthread_once_t*', 'void (*)(void)') @property def pthread_rwlock_destroy(self): if self.pthread_rwlock_init: return c.Function('int', 'pthread_rwlock_t*') pthread_rwlock_init = c.function_test('int', 'pthread_rwlock_t*', 'const pthread_rwlockattr_t*', test=''' #include <pthread.h> int main() { pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER; if (pthread_rwlock_init(&rwlock, 0) != 0) return 1; if (pthread_rwlock_rdlock(&rwlock) != 0) return 1; if (pthread_rwlock_unlock(&rwlock) != 0) return 1; if (pthread_rwlock_wrlock(&rwlock) != 0) return 1; if (pthread_rwlock_unlock(&rwlock) != 0) return 1; if (pthread_rwlock_destroy(&rwlock) != 0) return 1; return 0; } ''') @property def pthread_rwlock_rdlock(self): if self.pthread_rwlock_init: return c.Function('int', 'pthread_rwlock_t*') pthread_rwlock_timedrdlock = c.function_test('int', 'pthread_rwlock_t*', 'const struct timespec*', test=''' #include <pthread.h> int main() { pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER; struct timespec t = { 0, 0 }; if (pthread_rwlock_init(&rwlock, 0) != 0) return 1; if (pthread_rwlock_timedrdlock(&rwlock, &t) != 0) return 1; if (pthread_rwlock_unlock(&rwlock) != 0) return 1; if (pthread_rwlock_destroy(&rwlock) != 0) return 1; return 0; } ''') pthread_rwlock_timedwrlock = c.function_test('int', 'pthread_rwlock_t*', 'const struct timespec*', test=''' #include <pthread.h> int main() { pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER; struct timespec t = { 0, 0 }; if (pthread_rwlock_init(&rwlock, 0) != 0) return 1; if (pthread_rwlock_timedwrlock(&rwlock, &t) != 0) return 1; if (pthread_rwlock_unlock(&rwlock) != 0) return 1; if (pthread_rwlock_destroy(&rwlock) != 0) return 1; return 0; } ''') pthread_rwlock_tryrdlock = c.function_test('int', 'pthread_rwlock_t*', test=''' #include <pthread.h> int main() { pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER; if (pthread_rwlock_init(&rwlock, 0) != 0) return 1; if (pthread_rwlock_tryrdlock(&rwlock) != 0) return 1; if (pthread_rwlock_unlock(&rwlock) != 0) return 1; if (pthread_rwlock_destroy(&rwlock) != 0) return 1; return 0; } ''') pthread_rwlock_trywrlock = c.function_test('int', 'pthread_rwlock_t*', test=''' #include <pthread.h> int main() { pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER; if (pthread_rwlock_init(&rwlock, 0) != 0) return 1; if (pthread_rwlock_trywrlock(&rwlock) != 0) return 1; if (pthread_rwlock_unlock(&rwlock) != 0) return 1; if (pthread_rwlock_destroy(&rwlock) != 0) return 1; return 0; } ''') @property def pthread_rwlock_unlock(self): if self.pthread_rwlock_init: return c.Function('int', 'pthread_rwlock_t*') @property def pthread_rwlock_wrlock(self): if self.pthread_rwlock_init: return c.Function('int', 'pthread_rwlock_t*') pthread_rwlockattr_destroy = c.function_test('int', 'pthread_rwlockattr_t*') pthread_rwlockattr_getpshared = c.function_test( 'int', 'const pthread_rwlockattr_t*', 'int*') pthread_rwlockattr_init = c.function_test('int', 'pthread_rwlockattr_t*') pthread_rwlockattr_setpshared = c.function_test('int', 'pthread_rwlockattr_t*', 'int') pthread_self = c.function_test('pthread_t', 'void') pthread_setcancelstate = c.function_test('int', 'int', 'int*') pthread_setcanceltype = c.function_test('int', 'int', 'int*') pthread_setconcurrency = c.function_test('int', 'int') pthread_setschedparam = c.function_test('int', 'pthread_t', 'int', 'const struct sched_param*') pthread_setschedprio = c.function_test('int', 'pthread_t', 'int') pthread_setspecific = c.function_test('int', 'pthread_key_t', 'const void*') @property def pthread_spin_destroy(self): if self.pthread_spin_init: return c.Function('int', 'pthread_spinlock_t*') pthread_spin_init = c.function_test('int', 'pthread_spinlock_t*', 'int', test=''' #include <pthread.h> int main() { pthread_spinlock_t spin; if (pthread_spin_init(&spin, 0) != 0) return 1; if (pthread_spin_lock(&spin) != 0) return 1; if (pthread_spin_unlock(&spin) != 0) return 1; if (pthread_spin_trylock(&spin) != 0) return 1; if (pthread_spin_unlock(&spin) != 0) return 1; if (pthread_spin_destroy(&spin) != 0) return 1; return 0; } ''') @property def pthread_spin_lock(self): if self.pthread_spin_init: return c.Function('int', 'pthread_spinlock_t*') @property def pthread_spin_trylock(self): if self.pthread_spin_init: return c.Function('int', 'pthread_spinlock_t*') @property def pthread_spin_unlock(self): if self.pthread_spin_init: return c.Function('int', 'pthread_spinlock_t*') pthread_testcancel = c.function_test('void', 'void')
class fcntl_h(c.Test): header = c.header_test('fcntl.h') F_DUPFD = c.variable_test() F_GETFD = c.variable_test() F_SETFD = c.variable_test() F_GETFL = c.variable_test() F_SETFL = c.variable_test() F_GETLK = c.variable_test() F_SETLK = c.variable_test() F_SETLKW = c.variable_test() F_GETOWN = c.variable_test() F_SETOWN = c.variable_test() FD_CLOEXEC = c.variable_test() F_RDLCK = c.variable_test() F_UNLCK = c.variable_test() F_WRLCK = c.variable_test() O_CREAT = c.variable_test() O_EXCL = c.variable_test() O_NOCTTY = c.variable_test() O_TRUNC = c.variable_test() O_APPEND = c.variable_test() SIO = c.variable_test() O_NONBLOCK = c.variable_test() SIO = c.variable_test() O_SYNC = c.variable_test() O_ACCMODE = c.variable_test() O_RDONLY = c.variable_test() O_RDWR = c.variable_test() O_WRONLY = c.variable_test() mode_t = c.type_test() off_t = c.type_test() pid_t = c.type_test() POSIX_FADV_NORMAL = c.variable_test() POSIX_FADV_SEQUENTIAL = c.variable_test() POSIX_FADV_RANDOM = c.variable_test() POSIX_FADV_WILLNEED = c.variable_test() POSIX_FADV_DONTNEED = c.variable_test() POSIX_FADV_NOREUSE = c.variable_test() flock = c.struct_test(('short', 'l_type'), ('short', 'l_whence'), ('off_t', 'l_start'), ('off_t', 'l_len'), ('pid_t', 'l_pid')) creat = c.function_test('int', 'const char*', 'mode_t') fcntl = c.function_test('int', 'int', 'int') @c.cacheproperty def open(self): with tempfile.NamedTemporaryFile() as f: test = ''' #include <fcntl.h> int main() { int fd; if ((fd = open("%s", O_RDONLY)) == -1) return 1; return 0; } ''' % f.name if self.builder.check_run(test, "checking open in 'fcntl.h'"): return c.function_test('int', 'const char*', 'int') posix_fadvise = c.function_test('int', 'int', 'off_t', 'off_t', 'int') posix_fallocate = c.function_test('int', 'int', 'off_t', 'off_t')
class sys_types_h(c.Test): header = c.header_test('sys/types.h') blkcnt_t = c.int_type_test() blksize_t = c.int_type_test() clock_t = c.type_test() clockid_t = c.int_type_test() dev_t = c.int_type_test() fsblkcnt_t = c.int_type_test() fsfilcnt_t = c.int_type_test() gid_t = c.int_type_test() id_t = c.int_type_test() key_t = c.type_test() mode_t = c.int_type_test() nlink_t = c.int_type_test() off_t = c.int_type_test() pid_t = c.int_type_test() pthread_attr_t = c.type_test() pthread_barrier_t = c.type_test() pthread_barrierattr_t = c.type_test() pthread_cond_t = c.type_test() pthread_condattr_t = c.type_test() pthread_mutex_t = c.type_test() pthread_mutexattr_t = c.type_test() pthread_rwlock_t = c.type_test() pthread_rwlockattr_t = c.type_test() pthread_spinlock_t = c.type_test() pthread_t = c.type_test() size_t = c.int_type_test() ssize_t = c.int_type_test() suseconds_t = c.int_type_test() time_t = c.type_test() timer_t = c.int_type_test() trace_attr_t = c.type_test() trace_event_id_t = c.type_test() trace_event_set_t = c.type_test() trace_id_t = c.type_test() uid_t = c.int_type_test() useconds_t = c.int_type_test()
class stdio_h(c.Test): header = c.header_test('stdio.h') _IOFBF = c.macro_test() _IOLBF = c.macro_test() _IONBF = c.macro_test() BUFSIZ = c.macro_test() EOF = c.macro_test() FILE = c.type_test() FILENAME_MAX = c.macro_test() FOPEN_MAX = c.macro_test() fpos_t = c.type_test() L_tmpnam = c.macro_test() NULL = c.macro_test() SEEK_CUR = c.macro_test() SEEK_END = c.macro_test() SEEK_SET = c.macro_test() size_t = c.int_type_test() stderr = c.variable_test() stdin = c.variable_test() stdout = c.variable_test() TMP_MAX = c.macro_test() remove = c.function_test('int', 'const char*', default_args=('""', )) rename = c.function_test('int', 'const char*', 'const char*') tmpfile = c.function_test('FILE*', 'void') tmpnam = c.function_test('char*', 'char*', default_args=('NULL', )) @c.cacheproperty def fclose(self): if self.fopen: return c.Function('int', 'FILE*') fflush = c.function_test('int', 'FILE*', test=''' #include <stdio.h> int main() { return fflush(stdout) == 0 ? 0 : 1; } ''') @c.cacheproperty def fopen(self): with tempfile.NamedTemporaryFile() as f: test = ''' #include <errno.h> #include <stdio.h> int main() { FILE* f; fpos_t p; if (!(f = fopen("%s", "r"))) return 1; if (ftell(f) != 0) return 1; if (fgetpos(f, &p) != 0) return 1; if (fseek(f, 1L, SEEK_CUR) != 0) return 1; if (ftell(f) != 1) return 1; if (fsetpos(f, &p) != 0) return 1; if (ftell(f) != 0) return 1; if (fflush(NULL) != 0) return 1; if (!(f = freopen(NULL, "r", f))) return 1; errno = 0; rewind(f); if (errno) return 1; if (ferror(f) != 0) return 1; if (feof(f) != 0) return 1; if (fclose(f) != 0) return 1; return 0; } ''' % f.name if self.builder.check_run(test, "checking fopen in 'stdio.h'"): return c.Function('FILE*', 'const char*', 'const char*') @c.cacheproperty def freopen(self): if self.fopen: return c.Function('FILE*', 'const char*', 'const char*', 'FILE*') setbuf = c.function_test('void', 'FILE*', 'char*', test=''' #include <stdio.h> int main() { setbuf(stdout, ""); return 0; } ''') setvbuf = c.function_test('int', 'FILE*', 'char*', 'int', 'size_t', test=''' #include <stdio.h> int main() { setvbuf(stdout, "", _IONBF, 0); return 0; } ''') fprintf = c.function_test('int', 'FILE*', 'const char*', test=''' #include <stdio.h> int main() { return fprintf(stdout, "%d %d", 5, 6) ? 0 : 1; } ''', stdout=b'5 6') fscanf = c.function_test('int', 'FILE*', 'const char*', test=''' #include <stdio.h> int main() { int x = 0, y = 0; return fscanf(stdin, "%d %d", &x, &y) && x == 5 && y == 6 ? 0 : 1; } ''', stdin=b'5 6') printf = c.function_test('int', 'const char*', test=''' #include <stdio.h> int main() { return printf("%d %d", 5, 6) ? 0 : 1; } ''', stdout=b'5 6') scanf = c.function_test('int', 'const char*', test=''' #include <stdio.h> int main() { int x = 0, y = 0; return scanf("%d %d", &x, &y) && x == 5 && y == 6 ? 0 : 1; } ''', stdin=b'5 6') sprintf = c.function_test('int', 'char*', 'const char*', test=''' #include <stdio.h> int main() { char s[50]; return sprintf(s, "%d%d", 5, 6) && s[0] == '5' && s[1] == '6' ? 0 : 1; } ''') sscanf = c.function_test('int', 'const char*', 'const char*', test=''' #include <stdio.h> int main() { int x = 0, y = 0; return sscanf("5 6", "%d %d", &x, &y) && x == 5 && y == 6 ? 0 : 1; } ''') vfprintf = c.function_test('int', 'FILE*', 'const char*', 'va_list', test=''' #include <stdarg.h> #include <stdio.h> int f(char* s, ...) { int rc; va_list ap; va_start(ap, s); rc = vfprintf(stdout, s, ap); va_end(ap); return rc; } int main() { return f("%d %d", 5, 6) ? 0 : 1; } ''', stdout=b'5 6') vprintf = c.function_test('int', 'const char*', 'va_list', test=''' #include <stdarg.h> #include <stdio.h> int f(char* s, ...) { int rc; va_list ap; va_start(ap, s); rc = vprintf(s, ap); va_end(ap); return rc; } int main() { return f("%d %d", 5, 6) ? 0 : 1; } ''', stdout=b'5 6') vsprintf = c.function_test('int', 'char*', 'const char*', 'va_list', test=''' #include <stdarg.h> #include <stdio.h> int f(char* s, ...) { int rc; va_list ap; va_start(ap, s); rc = vsprintf(s, "%d %d", ap); va_end(ap); return rc; } int main() { char s[50] = {0}; return f(s, 5, 6) && s[0] == '5' && s[1] == ' ' && s[2] == '6' && s[3] == '\\0' ? 0 : 1; } ''') fgetc = c.function_test('int', 'FILE*', test=''' #include <stdio.h> int main() { return fgetc(stdin) == '5' ? 0 : 1; } ''', stdin=b'5') fgets = c.function_test('char*', 'char*', 'int', 'FILE*', test=''' #include <stdio.h> int main() { char s[50] = {0}; return fgets(s, 4, stdin) && s[0] == '5' && s[1] == ' ' && s[2] == '6' && s[3] == '\\0' ? 0 : 1; } ''', stdin=b'5 6') fputc = c.function_test('int', 'int', 'FILE*', test=''' #include <stdio.h> int main() { return fputc('5', stdout) == '5' ? 0 : 1; } ''', stdout=b'5') fputs = c.function_test('int', 'const char*', 'FILE*', test=''' #include <stdio.h> int main() { return fputs("5 6", stdout) ? 0 : 1; } ''', stdout=b'5 6') getc = c.function_test('int', 'FILE*', test=''' #include <stdio.h> int main() { return getc(stdin) == '5' ? 0 : 1; } ''', stdin=b'5') getchar = c.function_test('int', 'void', test=''' #include <stdio.h> int main() { return getchar() == '5' ? 0 : 1; } ''', stdin=b'5') gets = c.function_test('char*', 'char*', test=''' #include <stdio.h> int main() { char s[50] = {0}; return s == gets(s) && s[0] == '5' && s[1] == ' ' && s[2] == '6' && s[3] == '\\0' ? 0 : 1; } ''', stdin=b'5 6') putc = c.function_test('int', 'int', 'FILE*', test=''' #include <stdio.h> int main() { return putc('5', stdout) == '5' ? 0 : 1; } ''', stdout=b'5') putchar = c.function_test('int', 'int', test=''' #include <stdio.h> int main() { return putchar('5') == '5' ? 0 : 1; } ''', stdout=b'5') puts = c.function_test('int', 'const char*', test=''' #include <stdio.h> int main() { return puts("5 6") ? 0 : 1; } ''', stdout=b'5 6\n') ungetc = c.function_test('int', 'int', 'FILE*', test=''' #include <stdio.h> int main() { if (ungetc('5', stdin) != '5') return 1; return getc(stdin) == '5' ? 0 : 1; } ''') fread = c.function_test('size_t', 'void*', 'size_t', 'size_t', 'FILE*', test=''' #include <stdio.h> int main() { char s[50] = {0}; return fread(s, sizeof(char), 3, stdin) == 3 && s[0] == '5' && s[1] == ' ' && s[2] == '6' ? 0 : 1; } ''', stdin=b'5 6') fwrite = c.function_test('size_t', 'const void*', 'size_t', 'size_t', 'FILE*', test=''' #include <stdio.h> int main() { return fwrite("5 6", sizeof(char), 3, stdout) == 3 ? 0 : 1; } ''', stdout=b'5 6') @c.cacheproperty def fgetpos(self): if self.fopen: return c.Function('int', 'FILE*', 'fpos_t*', 'fgetpos') @c.cacheproperty def fseek(self): if self.fopen: return c.Function('int', 'FILE*', 'long int', 'int', 'fseek') @c.cacheproperty def fsetpos(self): if self.fopen: return c.Function('int', 'FILE*', 'const fpos_t*', 'fsetpos') @c.cacheproperty def ftell(self): if self.fopen: return c.Function('long int', 'FILE*', 'ftell') @c.cacheproperty def rewind(self): if self.fopen: return c.Function('void', 'FILE*', 'rewind') clearerr = c.function_test('void', 'FILE*', test=''' #include <stdio.h> int main() { clearerr(stdout); return 0; } ''') @property def feof(self): if self.fopen: return c.function_test('int', 'FILE*') @property def ferror(self): if self.fopen: return c.Function('int', 'FILE*') perror = c.function_test('void', 'const char*', default_args=('""', ))
class stdlib_h(c.Test): header = c.header_test('stdlib.h') EXIT_FAILURE = c.macro_test() EXIT_SUCCESS = c.macro_test() MB_CUR_MAX = c.macro_test() NULL = c.macro_test() RAND_MAX = c.macro_test() div_t = c.type_test() ldiv_t = c.type_test() size_t = c.int_type_test() wchar_t = c.int_type_test() atof = c.function_test('double', 'const char*', test=''' #include <stdlib.h> int main() { return atof("0.5") == 0.5 ? 0 : 1; } ''') atoi = c.function_test('int', 'const char*', test=''' #include <stdlib.h> int main() { return atoi("1234") == 1234 ? 0 : 1; } ''') atol = c.function_test('long int', 'const char*', test=''' #include <stdlib.h> int main() { return atol("1234") == 1234L ? 0 : 1; } ''') strtod = c.function_test('double', 'const char*', 'char**', test=''' #include <stdlib.h> int main() { char* s1 = "0.5"; char* s2 = "abc"; char* endp; double d = strtod(s1, &endp); if (s1 != endp && *endp == '\\0' && d == 0.5) { d = strtod(s2, &endp); return s1 == endp || *endp != '\\0' ? 0 : 1; } return 1; } ''') strtol = c.function_test('long int', 'const char*', 'char**', 'int', test=''' #include <stdlib.h> int main() { char* s1 = "15"; char* s2 = "abc"; char* endp; long int d = strtol(s1, &endp, 8); if (s1 != endp && *endp == '\\0' && d == 13l) { d = strtol(s2, &endp, 8); return s1 == endp || *endp != '\\0' ? 0 : 1; } return 1; } ''') strtoul = c.function_test('unsigned long int', 'const char*', 'char**', 'int', test=''' #include <stdlib.h> int main() { char* s1 = "15"; char* s2 = "abc"; char* endp; unsigned long int d = strtoul(s1, &endp, 8); if (s1 != endp && *endp == '\\0' && d == 13ul) { d = strtoul(s2, &endp, 8); return s1 == endp || *endp != '\\0' ? 0 : 1; } return 1; } ''') rand = c.function_test('int', 'void') srand = c.function_test('void', 'unsigned int') calloc = c.function_test('void*', 'size_t', 'size_t') free = c.function_test('void', 'void* ptr', test=''' #include <stdlib.h> int main() { void* p = malloc(5); if (!p) return 1; free(p); return 0; } ''') malloc = c.function_test('void*', 'size_t', test=free.test) realloc = c.function_test('void*', 'void*', 'size_t', test=''' #include <stdlib.h> int main() { void* p = malloc(5); if (!p) return 1; p = realloc(p, 6); if (!p) return 1; free(p); return 0; } ''') @c.cacheproperty def abort(self): self.ctx.logger.check("checking abort in 'stdlib.h'") with self.builder.tempfile(''' #include <stdlib.h> #ifdef _WIN32 #include <windows.h> #endif int main() { #ifdef _WIN32 /* Turn off the windows error box */ DWORD dwMode = SetErrorMode(SEM_NOGPFAULTERRORBOX); SetErrorMode(dwMode | SEM_NOGPFAULTERRORBOX); #endif abort(); return 0; } ''') as src: dst = src.parent / 'temp' try: obj = self.builder.uncached_compile(src, quieter=1) exe = self.builder.uncached_link_exe(dst, [obj], quieter=1) except fbuild.ExecutionError: pass else: try: self.builder.ctx.execute([exe], quieter=1) except fbuild.ExecutionError as e: self.ctx.logger.passed() return c.Function('void', 'void') self.ctx.logger.failed() atexit = c.function_test('int', 'void (*f)(void)', test=''' #include <stdio.h> #include <stdlib.h> void f() { printf("passed"); } int main() { atexit(&f); return 0; } ''', stdout=b'passed') exit = c.function_test('void', 'int', test=''' #include <stdlib.h> int main() { exit(0); return 1; } ''') getenv = c.function_test('char*', 'const char*', default_args=('""', )) system = c.function_test('int', 'const char*', default_args=('NULL', )) bsearch = c.function_test('void*', 'const void*', 'const void*', 'size_t', 'size_t', 'int (*f)(const void*, const void*)', test=''' #include <stdlib.h> int f(const void* a, const void* b) { return *(int*)a - *(int*)b; } int main() { int a[] = {0, 1, 2, 3, 4}; int b = 3; int* c = (int*)bsearch(&b, a, 5, sizeof(a[0]), &f); return c && c == &a[3] && *c == 3 ? 0 : 1; } ''') qsort = c.function_test('void', 'void*', 'size_t', 'size_t', 'int (*f)(const void*, const void*)', test=''' #include <stdlib.h> int f(const void* a, const void* b) { return *(int*)a - *(int*)b; } int main() { int a[] = {4, 3, 2, 1, 0}; qsort(a, 5, sizeof(a[0]), f); return a[0] == 0 && a[1] == 1 && a[2] == 2 && a[3] == 3 && a[4] == 4 ? 0 : 1; } ''') abs = c.function_test('int', 'int') div = c.function_test('div_t', 'int', 'int', default_args=(4, 2)) labs = c.function_test('long int', 'long int') ldiv = c.function_test('ldiv_t', 'long int', 'long int', default_args=(4, 2)) mblen = c.function_test('int', 'const char*', 'size_t', default_args=('""', 0)) mbtowc = c.function_test('int', 'wchar_t*', 'const char*', 'size_t', test=''' #include <stdlib.h> int main() { wchar_t s[50]; return mbtowc(s, "5", 50) == 1 && s[0] == L'5' ? 0 : 1; } ''') wctomb = c.function_test('int', 'char*', 'wchar_t') mbstowcs = c.function_test('size_t', 'wchar_t*', 'const char*', 'size_t', test=''' #include <stdlib.h> int main() { wchar_t s[50]; return mbstowcs(s, "5 6", 50) == 3 && s[0] == L'5' && s[1] == L' ' && s[2] == L'6' && s[3] == L'\\0' ? 0 : 1; } ''') wcstombs = c.function_test('size_t', 'char*', 'const wchar_t*', 'size_t', test=''' #include <stdlib.h> int main() { char s[50]; return wcstombs(s, L"5 6", 50) == 3 && s[0] == '5' && s[1] == ' ' && s[2] == '6' && s[3] == '\\0' ? 0 : 1; } ''')
class sys_dir_h(c.Test): header = c.header_test('sys/dir.h') DIR = c.type_test()
class sys_types_h(sys_types_h): u_int32_t = c.type_test() u_int64_t = c.type_test()
class errno_h(errno_h): # error_t is supported on some posix libraries. error_t = c.type_test()