Index: src/OFApplication.h ================================================================== --- src/OFApplication.h +++ src/OFApplication.h @@ -134,10 +134,20 @@ void (*_Nullable _SIGHUPHandler)(id, SEL); void (*_Nullable _SIGUSR1Handler)(id, SEL); void (*_Nullable _SIGUSR2Handler)(id, SEL); #endif } + +#ifdef OF_HAVE_CLASS_PROPERTIES +@property (class, readonly, nullable, nonatomic) + OFApplication *sharedApplication; +@property (class, readonly, nullable, nonatomic) OFString *programName; +@property (class, readonly, nullable, nonatomic) + OFArray OF_GENERIC(OFString *) *arguments; +@property (class, readonly, nullable, nonatomic) + OFDictionary OF_GENERIC(OFString *, OFString *) *environment; +#endif /*! * The name of the program (argv[0]). */ @property (readonly, nonatomic) OFString *programName; Index: src/OFCryptoHash.h ================================================================== --- src/OFCryptoHash.h +++ src/OFCryptoHash.h @@ -26,10 +26,15 @@ * A cryptographic hash implementing this protocol can be copied. The entire * state is copied, allowing to calculate a new hash from there. This is * especially useful for generating many hashes with a common prefix. */ @protocol OFCryptoHash +#ifdef OF_HAVE_CLASS_PROPERTIES +@property (class, readonly, nonatomic) size_t digestSize; +@property (class, readonly, nonatomic) size_t blockSize; +#endif + /*! * A boolean whether the hash has already been calculated. */ @property (readonly, nonatomic, getter=isCalculated) bool calculated; Index: src/OFFileManager.h ================================================================== --- src/OFFileManager.h +++ src/OFFileManager.h @@ -41,10 +41,14 @@ * * @brief A class which provides management for files, e.g. reading contents of * directories, deleting files, renaming files, etc. */ @interface OFFileManager: OFObject +#ifdef OF_HAVE_CLASS_PROPERTIES +@property (class, readonly, nonatomic) OFFileManager *defaultManager; +#endif + /*! * The path of the current working directory. */ @property (readonly, nonatomic) OFString *currentDirectoryPath; Index: src/OFLocalization.h ================================================================== --- src/OFLocalization.h +++ src/OFLocalization.h @@ -41,10 +41,19 @@ OFString *_decimalPoint; OFMutableArray OF_GENERIC(OFDictionary OF_GENERIC(OFString *, id) *) *_localizedStrings; } +#ifdef OF_HAVE_CLASS_PROPERTIES +@property (class, readonly, nullable, nonatomic) + OFLocalization *sharedLocalization; +@property (class, readonly, nullable, nonatomic) OFString *language; +@property (class, readonly, nullable, nonatomic) OFString *territory; +@property (class, readonly, nonatomic) of_string_encoding_t encoding; +@property (class, readonly, nullable, nonatomic) OFString *decimalPoint; +#endif + /*! * The language of the locale for messages. * * If the language is unknown, it is `nil`. */ @@ -79,11 +88,11 @@ * case, you need to manually allocate an instance and call * @ref init once. * * @return The shared OFLocalization instance */ -+ (instancetype)sharedLocalization; ++ (nullable OFLocalization *)sharedLocalization; /*! * @brief Returns the language of the locale. * * If the language is unknown, `nil` is returned. @@ -116,11 +125,11 @@ /*! * @brief Returns the decimal point of the system's locale. * * @return The decimal point of the system's locale */ -+ (OFString *)decimalPoint; ++ (nullable OFString *)decimalPoint; #ifdef OF_HAVE_FILES /*! * @brief Adds a directory to scan for language files. * Index: src/OFMutableString.m ================================================================== --- src/OFMutableString.m +++ src/OFMutableString.m @@ -279,11 +279,11 @@ size_t length = [self length]; bool isStart = true; for (size_t i = 0; i < length; i++) { char (*function)(char) = - (isStart ? startFunction : middleFunction);; + (isStart ? startFunction : middleFunction); of_unichar_t c = characters[i]; if (c <= 0x7F) [self setCharacter: (int)function(c) atIndex: i]; Index: src/OFObject.h ================================================================== --- src/OFObject.h +++ src/OFObject.h @@ -413,10 +413,17 @@ Class _isa; #else Class _isa __attribute__((__unused__)); #endif } + +#ifdef OF_HAVE_CLASS_PROPERTIES +@property (class, readonly, nonatomic) Class class; +@property (class, readonly, nonatomic) OFString *className; +@property (class, readonly, nullable, nonatomic) Class superclass; +@property (class, readonly, nonatomic) OFString *description; +#endif /*! * The name of the object's class. */ @property (readonly, nonatomic) OFString *className; Index: src/OFRunLoop.h ================================================================== --- src/OFRunLoop.h +++ src/OFRunLoop.h @@ -54,23 +54,28 @@ OFCondition *_condition; #endif volatile bool _stop; } +#ifdef OF_HAVE_CLASS_PROPERTIES +@property (class, readonly, nullable, nonatomic) OFRunLoop *mainRunLoop; +@property (class, readonly, nullable, nonatomic) OFRunLoop *currentRunLoop; +#endif + /*! * @brief Returns the run loop for the main thread. * * @return The run loop for the main thread */ -+ (OFRunLoop *)mainRunLoop; ++ (nullable OFRunLoop *)mainRunLoop; /*! * @brief Returns the run loop for the current thread. * * @return The run loop for the current thread */ -+ (OFRunLoop *)currentRunLoop; ++ (nullable OFRunLoop *)currentRunLoop; /*! * @brief Adds an OFTimer to the run loop. * * @param timer The timer to add Index: src/OFSystemInfo.h ================================================================== --- src/OFSystemInfo.h +++ src/OFSystemInfo.h @@ -23,10 +23,32 @@ * @class OFSystemInfo OFSystemInfo.h ObjFW/OFSystemInfo.h * * @brief A class for querying information about the system. */ @interface OFSystemInfo: OFObject +#ifdef OF_HAVE_CLASS_PROPERTIES +@property (class, readonly, nonatomic) size_t pageSize; +@property (class, readonly, nonatomic) size_t numberOfCPUs; +@property (class, readonly, nullable, nonatomic) OFString *userDataPath; +@property (class, readonly, nullable, nonatomic) OFString *userConfigPath; +@property (class, readonly, nullable, nonatomic) OFString *CPUVendor; +# if defined(OF_X86_64) || defined(OF_X86) || defined(DOXYGEN) +@property (class, readonly, nonatomic) bool supportsMMX; +@property (class, readonly, nonatomic) bool supportsSSE; +@property (class, readonly, nonatomic) bool supportsSSE2; +@property (class, readonly, nonatomic) bool supportsSSE3; +@property (class, readonly, nonatomic) bool supportsSSSE3; +@property (class, readonly, nonatomic) bool supportsSSE41; +@property (class, readonly, nonatomic) bool supportsSSE42; +@property (class, readonly, nonatomic) bool supportsAVX; +@property (class, readonly, nonatomic) bool supportsAVX2; +# endif +# if defined(OF_POWERPC) || defined(OF_POWERPC64) || defined(DOXYGEN) +@property (class, readonly, nonatomic) bool supportsAltiVec; +# endif +#endif + /*! * @brief Returns the size of a page. * * @return The size of a page */ @@ -49,11 +71,11 @@ * On Windows, it uses the `APPDATA` environment variable.@n * On Haiku, it uses the `B_USER_SETTINGS_DIRECTORY` directory. * * @return The path where user data for the application can be stored */ -+ (OFString *)userDataPath; ++ (nullable OFString *)userDataPath; /*! * @brief Returns the path where user configuration for the application can be * stored. * @@ -63,11 +85,11 @@ * On Windows, it uses the `APPDATA` environment variable.@n * On Haiku, it uses the `B_USER_SETTINGS_DIRECTORY` directory. * * @return The path where user configuration for the application can be stored */ -+ (OFString *)userConfigPath; ++ (nullable OFString *)userConfigPath; /*! * @brief Returns the vendor of the CPU. * * If the vendor could not be determined, `nil` is returned instead. Index: src/OFTCPSocket.h ================================================================== --- src/OFTCPSocket.h +++ src/OFTCPSocket.h @@ -67,10 +67,15 @@ uint16_t _SOCKS5Port; #ifdef OF_WII uint16_t _port; #endif } + +#ifdef OF_HAVE_CLASS_PROPERTIES +@property (class, nullable, copy, nonatomic) OFString *SOCKS5Host; +@property (class, nonatomic) uint16_t SOCKS5Port; +#endif /*! * Whether the socket is a listening socket. */ @property (readonly, nonatomic, getter=isListening) bool listening; Index: src/OFThread.h ================================================================== --- src/OFThread.h +++ src/OFThread.h @@ -75,10 +75,18 @@ OFMutableDictionary *_threadDictionary; @private OFString *_Nullable _name; } +# ifdef OF_HAVE_CLASS_PROPERTIES +@property (class, readonly, nullable, nonatomic) OFThread *currentThread; +@property (class, readonly, nullable, nonatomic) OFThread *mainThread; +@property (class, readonly, nullable, nonatomic) + OFMutableDictionary *threadDictionary; +@property (class, nullable, copy, nonatomic) OFString *name; +# endif + /*! * The name for the thread to use when starting it. * * @note While this can be changed after the thread has been started, it will * have no effect once the thread started. If you want to change the name @@ -138,26 +146,26 @@ /*! * @brief Returns the current thread. * * @return The current thread */ -+ (OFThread *)currentThread; ++ (nullable OFThread *)currentThread; /*! * @brief Returns the main thread. * * @return The main thread */ -+ (OFThread *)mainThread; ++ (nullable OFThread *)mainThread; /*! * @brief Returns a dictionary to store thread-specific data, meaning it * returns a different dictionary for every thread. * * @return A dictionary to store thread-specific data. */ -+ (OFMutableDictionary *)threadDictionary; ++ (nullable OFMutableDictionary *)threadDictionary; #endif /*! * @brief Suspends execution of the current thread for the specified time * interval. Index: src/OFThread.m ================================================================== --- src/OFThread.m +++ src/OFThread.m @@ -175,10 +175,13 @@ } + (OFMutableDictionary *)threadDictionary { OFThread *thread = of_tlskey_get(threadSelfKey); + + if (thread == nil) + return nil; if (thread->_threadDictionary == nil) thread->_threadDictionary = [[OFMutableDictionary alloc] init]; return thread->_threadDictionary; Index: src/macros.h ================================================================== --- src/macros.h +++ src/macros.h @@ -197,10 +197,14 @@ #if __has_feature(objc_kindof) # define OF_KINDOF(cls) __kindof cls #else # define OF_KINDOF(cls) id #endif + +#if __has_feature(objc_class_property) +# define OF_HAVE_CLASS_PROPERTIES +#endif #if defined(__clang__) || OF_GCC_VERSION >= 405 # define OF_UNREACHABLE __builtin_unreachable(); #else # define OF_UNREACHABLE abort();