17 #include "objfw-defs.h" 19 #ifndef __STDC_LIMIT_MACROS 20 # define __STDC_LIMIT_MACROS 22 #ifndef __STDC_CONSTANT_MACROS 23 # define __STDC_CONSTANT_MACROS 35 #ifdef OF_OBJFW_RUNTIME 36 # ifdef OF_COMPILING_OBJFW 39 # import <ObjFW-RT/ObjFW-RT.h> 42 #ifdef OF_APPLE_RUNTIME 43 # import <objc/objc.h> 44 # import <objc/runtime.h> 45 # import <objc/message.h> 49 # define restrict __restrict__ 50 #elif __STDC_VERSION__ < 199901L 54 #if __STDC_VERSION__ >= 201112L && !defined(static_assert) 56 # define static_assert _Static_assert 59 #if defined(OF_HAVE__THREAD_LOCAL) 60 # define OF_HAVE_COMPILER_TLS 61 # ifdef OF_HAVE_THREADS_H 64 # define thread_local _Thread_local 66 #elif defined(OF_HAVE___THREAD) 67 # define OF_HAVE_COMPILER_TLS 68 # define thread_local __thread 72 # define OF_INLINE inline __attribute__((__always_inline__)) 73 # define OF_LIKELY(cond) (__builtin_expect(!!(cond), 1)) 74 # define OF_UNLIKELY(cond) (__builtin_expect(!!(cond), 0)) 75 # define OF_CONST_FUNC __attribute__((__const__)) 76 # define OF_NO_RETURN_FUNC __attribute__((__noreturn__)) 77 # define OF_WEAK_REF(sym) __attribute__((__weakref__(sym))) 79 # define OF_INLINE inline 80 # define OF_LIKELY(cond) cond 81 # define OF_UNLIKELY(cond) cond 82 # define OF_CONST_FUNC 83 # define OF_NO_RETURN_FUNC 84 # define OF_WEAK_REF(sym) 88 # define OF_BYTE_ORDER_NATIVE OF_BYTE_ORDER_BIG_ENDIAN 90 # define OF_BYTE_ORDER_NATIVE OF_BYTE_ORDER_LITTLE_ENDIAN 93 #if __STDC_VERSION__ >= 201112L 94 # define OF_ALIGNAS(type) _Alignas(type) 96 # define OF_ALIGNAS(type) __attribute__((__aligned__(sizeof(type)))) 99 #if __STDC_VERSION__ >= 201112L && defined(OF_HAVE_MAX_ALIGN_T) 100 # define OF_BIGGEST_ALIGNMENT _Alignof(max_align_t) 102 # ifdef __BIGGEST_ALIGNMENT__ 103 # define OF_BIGGEST_ALIGNMENT __BIGGEST_ALIGNMENT__ 106 # define OF_BIGGEST_ALIGNMENT 16 111 # define __GCC_VERSION__ (__GNUC__ * 100 + __GNUC_MINOR__) 113 # define __GCC_VERSION__ 0 116 #ifndef __has_feature 117 # define __has_feature(x) 0 120 #ifndef __has_attribute 121 # define __has_attribute(x) 0 124 #if __has_feature(objc_bool) 126 # define YES __objc_yes 128 # define NO __objc_no 131 # define true ((bool)1) 133 # define false ((bool)0) 137 #if !__has_feature(objc_instancetype) 138 # define instancetype id 141 #if __has_feature(blocks) 142 # define OF_HAVE_BLOCKS 145 #if __has_feature(objc_arc) 146 # define OF_RETURNS_RETAINED __attribute__((__ns_returns_retained__)) 147 # define OF_RETURNS_NOT_RETAINED __attribute__((__ns_returns_not_retained__)) 148 # define OF_RETURNS_INNER_POINTER \ 149 __attribute__((__objc_returns_inner_pointer__)) 150 # define OF_CONSUMED __attribute__((__ns_consumed__)) 151 # define OF_WEAK_UNAVAILABLE __attribute__((__objc_arc_weak_unavailable__)) 153 # define OF_RETURNS_RETAINED 154 # define OF_RETURNS_NOT_RETAINED 155 # define OF_RETURNS_INNER_POINTER 157 # define OF_WEAK_UNAVAILABLE 162 # undef __unsafe_unretained 164 # undef __autoreleasing 165 # define __unsafe_unretained 167 # define __autoreleasing 170 #if __has_feature(objc_generics) 171 # define OF_HAVE_GENERICS 172 # define OF_GENERIC(...) <__VA_ARGS__> 174 # define OF_GENERIC(...) 177 #if __has_feature(nullability) 178 # define OF_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") 179 # define OF_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") 180 # define OF_NULLABLE_PROPERTY(...) (__VA_ARGS__, nullable) 181 # define OF_NULL_RESETTABLE_PROPERTY(...) (__VA_ARGS__, null_resettable) 183 # define OF_ASSUME_NONNULL_BEGIN 184 # define OF_ASSUME_NONNULL_END 187 # define _Null_unspecified 188 # define OF_NULLABLE_PROPERTY 189 # define OF_NULL_RESETTABLE_PROPERTY 192 # define null_unspecified 195 #if __has_feature(objc_kindof) 196 # define OF_KINDOF(cls) __kindof cls 198 # define OF_KINDOF(cls) id 201 #if defined(__clang__) || __GCC_VERSION__ >= 405 202 # define OF_UNREACHABLE __builtin_unreachable(); 204 # define OF_UNREACHABLE abort(); 207 #if defined(__clang__) || __GCC_VERSION__ >= 406 208 # define OF_SENTINEL __attribute__((__sentinel__)) 209 # define OF_NO_RETURN __attribute__((__noreturn__)) 212 # define OF_NO_RETURN 215 #if __has_attribute(__unavailable__) 216 # define OF_UNAVAILABLE __attribute__((__unavailable__)) 218 # define OF_UNAVAILABLE 221 #if __has_attribute(__objc_requires_super__) 222 # define OF_REQUIRES_SUPER __attribute__((__objc_requires_super__)) 224 # define OF_REQUIRES_SUPER 227 #if __has_attribute(__objc_root_class__) 228 # define OF_ROOT_CLASS __attribute__((__objc_root_class__)) 230 # define OF_ROOT_CLASS 233 #if __has_attribute(__objc_subclassing_restricted__) 234 # define OF_SUBCLASSING_RESTRICTED \ 235 __attribute__((__objc_subclassing_restricted__)) 237 # define OF_SUBCLASSING_RESTRICTED 240 #if __has_attribute(__objc_method_family__) 241 # define OF_METHOD_FAMILY(f) __attribute__((__objc_method_family__(f))) 243 # define OF_METHOD_FAMILY(f) 246 #if __has_attribute(__objc_designated_initializer__) 247 # define OF_DESIGNATED_INITIALIZER \ 248 __attribute__((__objc_designated_initializer__)) 250 # define OF_DESIGNATED_INITIALIZER 255 # define OF_X86_64_ASM 261 # define OF_POWERPC_ASM 264 # define OF_ARM64_ASM 270 # define OF_ARMV7_ASM 273 # define OF_ARMV6_ASM 276 # define OF_MIPS64_ASM 283 #ifdef OF_APPLE_RUNTIME 284 # if defined(OF_X86_64) || defined(OF_X86) || defined(OF_ARM64) || \ 285 defined(OF_ARM) || defined(OF_POWERPC) 286 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR 287 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET 291 # if defined(OF_X86_64) || defined(OF_X86) || \ 292 defined(OF_ARM64) || defined(OF_ARM) || defined(OF_POWERPC) || \ 294 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR 295 # if __OBJFW_RUNTIME_ABI__ >= 800 296 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET 299 # elif defined(OF_MACH_O) 300 # if defined(OF_X86_64) 301 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR 302 # if __OBJFW_RUNTIME_ABI__ >= 800 303 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET 306 # elif defined(OF_WINDOWS) 307 # if defined(OF_X86_64) || defined(OF_X86) 308 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR 309 # if __OBJFW_RUNTIME_ABI__ >= 800 310 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET 316 #define OF_RETAIN_COUNT_MAX UINT_MAX 317 #define OF_NOT_FOUND SIZE_MAX 319 #if !defined(OF_WINDOWS) && !defined(OF_MSDOS) 320 # define OF_PATH_DELIMITER '/' 321 # define OF_PATH_DELIMITER_STRING @"/" 322 # define OF_IS_PATH_DELIMITER(c) (c == '/') 324 # define OF_PATH_DELIMITER '\\' 325 # define OF_PATH_DELIMITER_STRING @"\\" 326 # define OF_IS_PATH_DELIMITER(c) (c == '\\' || c == '/') 328 #define OF_PATH_CURRENT_DIRECTORY @"." 329 #define OF_PATH_PARENT_DIRECTORY @".." 331 #define OF_ENSURE(cond) \ 334 fprintf(stderr, "Failed to ensure condition " \ 335 "in " __FILE__ ":%d:\n" #cond "\n", \ 341 #define OF_UNRECOGNIZED_SELECTOR of_method_not_found(self, _cmd); 342 #if __has_feature(objc_arc) 343 # define OF_INVALID_INIT_METHOD \ 344 [self doesNotRecognizeSelector: _cmd]; \ 348 # define OF_INVALID_INIT_METHOD \ 350 [self doesNotRecognizeSelector: _cmd]; \ 359 # define OF_DEALLOC_UNSUPPORTED \ 360 [self doesNotRecognizeSelector: _cmd]; \ 364 _Pragma("clang diagnostic push ignore \"-Wunreachable-code\""); \ 366 _Pragma("clang diagnostic pop"); 368 # define OF_DEALLOC_UNSUPPORTED \ 369 [self doesNotRecognizeSelector: _cmd]; \ 376 #define OF_PREPROCESSOR_CONCAT2(a, b) a##b 377 #define OF_PREPROCESSOR_CONCAT(a, b) OF_PREPROCESSOR_CONCAT2(a, b) 378 #define OF_CONSTRUCTOR(prio) \ 379 static void __attribute__((__constructor__(prio))) \ 380 OF_PREPROCESSOR_CONCAT(constructor, __LINE__)(void) 381 #define OF_DESTRUCTOR(prio) \ 382 static void __attribute__((__destructor__(prio))) \ 383 OF_PREPROCESSOR_CONCAT(destructor, __LINE__)(void) 385 static OF_INLINE uint16_t OF_CONST_FUNC
386 OF_BSWAP16_CONST(uint16_t i)
388 return (i & UINT16_C(0xFF00)) >> 8 |
389 (i & UINT16_C(0x00FF)) << 8;
392 static OF_INLINE uint32_t OF_CONST_FUNC
393 OF_BSWAP32_CONST(uint32_t i)
395 return (i & UINT32_C(0xFF000000)) >> 24 |
396 (i & UINT32_C(0x00FF0000)) >> 8 |
397 (i & UINT32_C(0x0000FF00)) << 8 |
398 (i & UINT32_C(0x000000FF)) << 24;
401 static OF_INLINE uint64_t OF_CONST_FUNC
402 OF_BSWAP64_CONST(uint64_t i)
404 return (i & UINT64_C(0xFF00000000000000)) >> 56 |
405 (i & UINT64_C(0x00FF000000000000)) >> 40 |
406 (i & UINT64_C(0x0000FF0000000000)) >> 24 |
407 (i & UINT64_C(0x000000FF00000000)) >> 8 |
408 (i & UINT64_C(0x00000000FF000000)) << 8 |
409 (i & UINT64_C(0x0000000000FF0000)) << 24 |
410 (i & UINT64_C(0x000000000000FF00)) << 40 |
411 (i & UINT64_C(0x00000000000000FF)) << 56;
414 static OF_INLINE uint16_t OF_CONST_FUNC
415 OF_BSWAP16_NONCONST(uint16_t i)
417 #if defined(OF_HAVE_BUILTIN_BSWAP16) 418 return __builtin_bswap16(i);
419 #elif defined(OF_X86_64_ASM) || defined(OF_X86_ASM) 425 #elif defined(OF_POWERPC_ASM) 431 #elif defined(OF_ARMV6_ASM) 438 i = (i & UINT16_C(0xFF00)) >> 8 |
439 (i & UINT16_C(0x00FF)) << 8;
444 static OF_INLINE uint32_t OF_CONST_FUNC
445 OF_BSWAP32_NONCONST(uint32_t i)
447 #if defined(OF_HAVE_BUILTIN_BSWAP32) 448 return __builtin_bswap32(i);
449 #elif defined(OF_X86_64_ASM) || defined(OF_X86_ASM) 455 #elif defined(OF_POWERPC_ASM) 461 #elif defined(OF_ARMV6_ASM) 468 i = (i & UINT32_C(0xFF000000)) >> 24 |
469 (i & UINT32_C(0x00FF0000)) >> 8 |
470 (i & UINT32_C(0x0000FF00)) << 8 |
471 (i & UINT32_C(0x000000FF)) << 24;
476 static OF_INLINE uint64_t OF_CONST_FUNC
477 OF_BSWAP64_NONCONST(uint64_t i)
479 #if defined(OF_HAVE_BUILTIN_BSWAP64) 480 return __builtin_bswap64(i);
481 #elif defined(OF_X86_64_ASM) 487 #elif defined(OF_X86_ASM) 496 i = (uint64_t)OF_BSWAP32_NONCONST((uint32_t)(i & 0xFFFFFFFF)) << 32 |
497 OF_BSWAP32_NONCONST((uint32_t)(i >> 32));
503 # define OF_BSWAP16(i) \ 504 (__builtin_constant_p(i) ? OF_BSWAP16_CONST(i) : OF_BSWAP16_NONCONST(i)) 505 # define OF_BSWAP32(i) \ 506 (__builtin_constant_p(i) ? OF_BSWAP32_CONST(i) : OF_BSWAP32_NONCONST(i)) 507 # define OF_BSWAP64(i) \ 508 (__builtin_constant_p(i) ? OF_BSWAP64_CONST(i) : OF_BSWAP64_NONCONST(i)) 510 # define OF_BSWAP16(i) OF_BSWAP16_CONST(i) 511 # define OF_BSWAP32(i) OF_BSWAP32_CONST(i) 512 # define OF_BSWAP64(i) OF_BSWAP64_CONST(i) 515 static OF_INLINE
float OF_CONST_FUNC
516 OF_BSWAP_FLOAT(
float f)
524 u.i = OF_BSWAP32(u.i);
529 static OF_INLINE
double OF_CONST_FUNC
530 OF_BSWAP_DOUBLE(
double d)
538 u.i = OF_BSWAP64(u.i);
544 # define OF_BSWAP16_IF_BE(i) OF_BSWAP16(i) 545 # define OF_BSWAP32_IF_BE(i) OF_BSWAP32(i) 546 # define OF_BSWAP64_IF_BE(i) OF_BSWAP64(i) 547 # define OF_BSWAP16_IF_LE(i) (i) 548 # define OF_BSWAP32_IF_LE(i) (i) 549 # define OF_BSWAP64_IF_LE(i) (i) 551 # define OF_BSWAP16_IF_BE(i) (i) 552 # define OF_BSWAP32_IF_BE(i) (i) 553 # define OF_BSWAP64_IF_BE(i) (i) 554 # define OF_BSWAP16_IF_LE(i) OF_BSWAP16(i) 555 # define OF_BSWAP32_IF_LE(i) OF_BSWAP32(i) 556 # define OF_BSWAP64_IF_LE(i) OF_BSWAP64(i) 559 #ifdef OF_FLOAT_BIG_ENDIAN 560 # define OF_BSWAP_FLOAT_IF_BE(i) OF_BSWAP_FLOAT(i) 561 # define OF_BSWAP_DOUBLE_IF_BE(i) OF_BSWAP_DOUBLE(i) 562 # define OF_BSWAP_FLOAT_IF_LE(i) (i) 563 # define OF_BSWAP_DOUBLE_IF_LE(i) (i) 565 # define OF_BSWAP_FLOAT_IF_BE(i) (i) 566 # define OF_BSWAP_DOUBLE_IF_BE(i) (i) 567 # define OF_BSWAP_FLOAT_IF_LE(i) OF_BSWAP_FLOAT(i) 568 # define OF_BSWAP_DOUBLE_IF_LE(i) OF_BSWAP_DOUBLE(i) 571 #define OF_ROL(value, bits) \ 572 (((bits) % (sizeof(value) * 8)) > 0 \ 573 ? ((value) << ((bits) % (sizeof(value) * 8))) | \ 574 ((value) >> (sizeof(value) * 8 - ((bits) % (sizeof(value) * 8)))) \ 576 #define OF_ROR(value, bits) \ 577 (((bits) % (sizeof(value) * 8)) > 0 \ 578 ? ((value) >> ((bits) % (sizeof(value) * 8))) | \ 579 ((value) << (sizeof(value) * 8 - ((bits) % (sizeof(value) * 8)))) \ 582 #define OF_ROUND_UP_POW2(pow2, value) (((value) + (pow2) - 1) & ~((pow2) - 1)) 584 #define OF_HASH_INIT(hash) hash = of_hash_seed; 585 #define OF_HASH_ADD(hash, byte) \ 587 hash += (uint8_t)(byte); \ 588 hash += (hash << 10); \ 589 hash ^= (hash >> 6); \ 591 #define OF_HASH_FINALIZE(hash) \ 593 hash += (hash << 3); \ 594 hash ^= (hash >> 11); \ 595 hash += (hash << 15); \ 597 #define OF_HASH_ADD_HASH(hash, other) \ 599 uint32_t otherCopy = other; \ 600 OF_HASH_ADD(hash, (otherCopy >> 24) & 0xFF); \ 601 OF_HASH_ADD(hash, (otherCopy >> 16) & 0xFF); \ 602 OF_HASH_ADD(hash, (otherCopy >> 8) & 0xFF); \ 603 OF_HASH_ADD(hash, otherCopy & 0xFF); \ 606 static OF_INLINE
bool 607 of_bitset_isset(uint8_t *storage,
size_t index)
609 return storage[index / 8] & (1 << (index % 8));
612 static OF_INLINE
void 613 of_bitset_set(uint8_t *storage,
size_t index)
615 storage[index / 8] |= (1 << (index % 8));
618 static OF_INLINE
void 619 of_bitset_clear(uint8_t *storage,
size_t index)
621 storage[index / 8] &= ~(1 << (index % 8));
624 static OF_INLINE
char *
625 of_strdup(
const char *
string)
628 size_t length = strlen(
string);
630 if ((copy = (
char *)malloc(length + 1)) == NULL)
633 memcpy(copy,
string, length + 1);
638 static OF_INLINE
void 639 of_explicit_memset(
void *buffer_,
int character,
size_t length)
641 volatile unsigned char *buffer = (
volatile unsigned char *)buffer_;
643 while (buffer < (
unsigned char *)buffer_ + length)
644 *buffer++ = character;
647 static OF_INLINE
bool 648 of_ascii_isalpha(
char c)
650 return ((c >=
'a' && c <=
'z') || (c >=
'A' && c <=
'Z'));
653 static OF_INLINE
bool 654 of_ascii_isalnum(
char c)
656 return (of_ascii_isalpha(c) || (c >=
'0' && c <=
'9'));
659 static OF_INLINE
bool 660 of_ascii_isspace(
char c)
662 return (c ==
' ' || c ==
'\t' || c ==
'\n' || c ==
'\r' || c ==
'\f' ||
666 static OF_INLINE
char 667 of_ascii_toupper(
char c)
669 return (c >=
'a' && c <=
'z' ?
'A' + (c -
'a') : c);
672 static OF_INLINE
char 673 of_ascii_tolower(
char c)
675 return (c >=
'A' && c <=
'Z' ?
'a' + (c -
'A') : c);