Index: ChangeLog ================================================================== --- ChangeLog +++ ChangeLog @@ -1,9 +1,36 @@ Legend: * Changes of existing features or bugfixes. + New features. +ObjFW 0.4-alpha1 -> 0.4-alpha2, XX.XX.2011 + * Fixed a nasty typo in OFDate that could lead to date differences being wrong + about a second. + * Possible SIGPIPEs are now ignored when using OFStream. + * Documentation fixes. + * Replaced -[sleepForNMilliseconds:] with + -[sleepForTimeInterval:microseconds:]. + + Added +[sleepUntilDate] to OFDate. + * Some systems don't allow usleep for values > 1000000, so we use sleep and + usleep sequentially now to sleep the correct time. + + Family is now autodetected in -[bindService:onNode:]. + * -[writeLine:] does not send two packets anymore. + + -framework is now allowed in ObjFW compile. + * errNo of socket related exceptions is now correctly set to ENOTCONN on Win32. + * Fixed missing retain + autorelease in TLS-object handling. + * Renamed +[tlsKey] to +[TLSKey] to conform to the convention. + * Added missing files to .xcodeproj. + * Got rid of a few useless #ifdefs. + * Fixed a missing include (about which for some strange reason only clang + complains). + + Added + as a prefix in -[OFString decimalValue]. + * enums are now defined using typedef. + * Updated the buildsys, fixes make install when only building a static library. + * Made OFBlocks compile with ObjFW-RT. + + Added +[thread] to OFThread and allow -[init]. + * Removed useless variables from objfw-compile. + ObjFW 0.3.1 -> 0.4-alpha1, 03.01.2011 * ObjFW is now available under the terms of the QPL, GPLv2 and GPLv3. + Support for blocks was added, including a blocks runtime. + Added support for the new GNU runtime, introduced in GCC 4.6. * Objects returned from collections are no longer retained and autoreleased. Index: ObjFW.xcodeproj/project.pbxproj ================================================================== --- ObjFW.xcodeproj/project.pbxproj +++ ObjFW.xcodeproj/project.pbxproj @@ -88,32 +88,32 @@ }; 4BD86D711237A65E00ED9912 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4BD86D4C1237A58400ED9912 /* libobjfw */; + remoteGlobalIDString = 4BD86D4C1237A58400ED9912; remoteInfo = libobjfw; }; 4BD86D731237A66300ED9912 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4BD86D4C1237A58400ED9912 /* libobjfw */; + remoteGlobalIDString = 4BD86D4C1237A58400ED9912; remoteInfo = libobjfw; }; 4BD86D751237A66600ED9912 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4B08AE9E109AE10E00989F6E /* Framework */; + remoteGlobalIDString = 4B08AE9E109AE10E00989F6E; remoteInfo = Framework; }; 4BD86D771237A66D00ED9912 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4BD86D6E1237A65300ED9912 /* Tests */; + remoteGlobalIDString = 4BD86D6E1237A65300ED9912; remoteInfo = Tests; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ @@ -128,12 +128,10 @@ 4B6799581099E7C50041064A /* objc_sync.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = objc_sync.m; path = src/objc_sync.m; sourceTree = ""; }; 4B67995A1099E7C50041064A /* OFArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFArray.h; path = src/OFArray.h; sourceTree = ""; }; 4B67995B1099E7C50041064A /* OFArray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFArray.m; path = src/OFArray.m; sourceTree = ""; }; 4B67995C1099E7C50041064A /* OFAutoreleasePool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFAutoreleasePool.h; path = src/OFAutoreleasePool.h; sourceTree = ""; }; 4B67995D1099E7C50041064A /* OFAutoreleasePool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFAutoreleasePool.m; path = src/OFAutoreleasePool.m; sourceTree = ""; }; - 4B67995E1099E7C50041064A /* OFConstString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFConstString.h; path = src/OFConstString.h; sourceTree = ""; }; - 4B67995F1099E7C50041064A /* OFConstString.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFConstString.m; path = src/OFConstString.m; sourceTree = ""; }; 4B6799601099E7C50041064A /* OFDataArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFDataArray.h; path = src/OFDataArray.h; sourceTree = ""; }; 4B6799611099E7C50041064A /* OFDataArray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFDataArray.m; path = src/OFDataArray.m; sourceTree = ""; }; 4B6799621099E7C50041064A /* OFDictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFDictionary.h; path = src/OFDictionary.h; sourceTree = ""; }; 4B6799631099E7C50041064A /* OFDictionary.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFDictionary.m; path = src/OFDictionary.m; sourceTree = ""; }; 4B6799641099E7C50041064A /* OFExceptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFExceptions.h; path = src/OFExceptions.h; sourceTree = ""; }; @@ -203,10 +201,16 @@ 4BAF5F4A123460C900F4E111 /* OFStreamSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFStreamSocket.m; path = src/OFStreamSocket.m; sourceTree = ""; }; 4BBA36C411406AB700CBA3AC /* atomic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = atomic.h; path = src/atomic.h; sourceTree = ""; }; 4BBA36C511406AB700CBA3AC /* macros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = macros.h; path = src/macros.h; sourceTree = ""; }; 4BD86D801237A6C600ED9912 /* OFBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFBlock.h; path = src/OFBlock.h; sourceTree = SOURCE_ROOT; }; 4BD86D811237A6C600ED9912 /* OFBlock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFBlock.m; path = src/OFBlock.m; sourceTree = SOURCE_ROOT; }; + 4BE5F0D712DF4225005C7A0C /* OFConstantString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFConstantString.h; path = src/OFConstantString.h; sourceTree = SOURCE_ROOT; }; + 4BE5F0D812DF4225005C7A0C /* OFConstantString.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFConstantString.m; path = src/OFConstantString.m; sourceTree = SOURCE_ROOT; }; + 4BE5F0D912DF4225005C7A0C /* OFDate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFDate.h; path = src/OFDate.h; sourceTree = SOURCE_ROOT; }; + 4BE5F0DA12DF4225005C7A0C /* OFDate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFDate.m; path = src/OFDate.m; sourceTree = SOURCE_ROOT; }; + 4BE5F0E412DF4259005C7A0C /* OFBlockTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFBlockTests.m; path = tests/OFBlockTests.m; sourceTree = SOURCE_ROOT; }; + 4BE5F0E512DF4259005C7A0C /* OFDateTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFDateTests.m; path = tests/OFDateTests.m; sourceTree = SOURCE_ROOT; }; 4BF1BCBF11C9663F0025511F /* objfw-defs.h.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "objfw-defs.h.in"; path = "src/objfw-defs.h.in"; sourceTree = ""; }; 4BF1BCC011C9663F0025511F /* OFHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFHash.h; path = src/OFHash.h; sourceTree = ""; }; 4BF1BCC111C9663F0025511F /* OFHash.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFHash.m; path = src/OFHash.m; sourceTree = ""; }; 4BF1BCC211C9663F0025511F /* OFMD5Hash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFMD5Hash.h; path = src/OFMD5Hash.h; sourceTree = ""; }; 4BF1BCC311C9663F0025511F /* OFMD5Hash.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFMD5Hash.m; path = src/OFMD5Hash.m; sourceTree = ""; }; @@ -245,14 +249,16 @@ 4B67995C1099E7C50041064A /* OFAutoreleasePool.h */, 4B67995D1099E7C50041064A /* OFAutoreleasePool.m */, 4BD86D801237A6C600ED9912 /* OFBlock.h */, 4BD86D811237A6C600ED9912 /* OFBlock.m */, 4BAF5F46123460C900F4E111 /* OFCollection.h */, - 4B67995E1099E7C50041064A /* OFConstString.h */, - 4B67995F1099E7C50041064A /* OFConstString.m */, + 4BE5F0D712DF4225005C7A0C /* OFConstantString.h */, + 4BE5F0D812DF4225005C7A0C /* OFConstantString.m */, 4B6799601099E7C50041064A /* OFDataArray.h */, 4B6799611099E7C50041064A /* OFDataArray.m */, + 4BE5F0D912DF4225005C7A0C /* OFDate.h */, + 4BE5F0DA12DF4225005C7A0C /* OFDate.m */, 4B6799621099E7C50041064A /* OFDictionary.h */, 4B6799631099E7C50041064A /* OFDictionary.m */, 4B0108C910EB8C9300631877 /* OFEnumerator.h */, 4B0108CA10EB8C9300631877 /* OFEnumerator.m */, 4B6799641099E7C50041064A /* OFExceptions.h */, @@ -330,11 +336,13 @@ isa = PBXGroup; children = ( 4B6EF6831235359D0076B512 /* Plugin */, 4B6EF682123535960076B512 /* objc_sync */, 4B6EF66E1235358D0076B512 /* OFArrayTests.m */, + 4BE5F0E412DF4259005C7A0C /* OFBlockTests.m */, 4B6EF66F1235358D0076B512 /* OFDataArrayTests.m */, + 4BE5F0E512DF4259005C7A0C /* OFDateTests.m */, 4B6EF6701235358D0076B512 /* OFDictionaryTests.m */, 4B6EF6711235358D0076B512 /* OFFileTests.m */, 4B6EF6721235358D0076B512 /* OFListTests.m */, 4B6EF6731235358D0076B512 /* OFMD5HashTests.m */, 4B6EF6741235358D0076B512 /* OFNumberTests.m */, @@ -424,11 +432,18 @@ /* Begin PBXProject section */ 08FB7793FE84155DC02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 1DEB919308733D9F0010E9CD /* Build configuration list for PBXProject "ObjFW" */; compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 08FB7794FE84155DC02AAC07 /* ObjFW */; projectDirPath = ""; projectRoot = ""; targets = ( 4BD86D601237A5B200ED9912 /* All */, Index: buildsys.mk.in ================================================================== --- buildsys.mk.in +++ buildsys.mk.in @@ -135,11 +135,11 @@ fi .c.c.dep .cc.cc.dep .cxx.cxx.dep .m.m.dep .mm.mm.dep .S.S.dep: ${CPP} ${CPPFLAGS} -M $< | \ sed 's/^\([^\.]*\)\.o:/\1.o \1.lib.o \1.plugin.o:/' >$@ || \ - (rm -f $@; exit 1) + { rm -f $@; false; } pre-depend: ${PROG} ${PROG_NOINST}: ${EXT_DEPS} ${OBJS} ${LINK_STATUS} @@ -362,11 +362,11 @@ ${DIR_LEAVE}; \ done for i in ${LIB}; do \ ${INSTALL_STATUS}; \ - if ${MKDIR_P} ${DESTDIR}${libdir} && ${INSTALL_LIB}; then \ + if ${MKDIR_P} ${DESTDIR}${libdir} ${INSTALL_LIB}; then \ ${INSTALL_OK}; \ else \ ${INSTALL_FAILED}; \ fi \ done @@ -443,11 +443,11 @@ ${DIR_LEAVE}; \ done for i in ${LIB}; do \ if test -f ${DESTDIR}${libdir}/$$i; then \ - if ${UNINSTALL_LIB}; then \ + if : ${UNINSTALL_LIB}; then \ ${DELETE_OK}; \ else \ ${DELETE_FAILED}; \ fi \ fi; \ Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -253,11 +253,11 @@ AS_HELP_STRING([--disable-threads], [disable thread support])) AS_IF([test x"$enable_threads" != x"no"], [ case "$host_os" in mingw*) AC_MSG_CHECKING(for threads) - AC_MSG_RESULT(win32) + AC_MSG_RESULT(WinAPI) ;; *) ACX_PTHREAD([ CPPLAGS="$CPPFLAGS $PTHREAD_CFLAGS" LIBS="$LIBS $PTHREAD_LIBS" Index: m4/buildsys.m4 ================================================================== --- m4/buildsys.m4 +++ m4/buildsys.m4 @@ -99,12 +99,12 @@ LIB_SUFFIX='.dylib' LDFLAGS_RPATH='-Wl,-rpath,${libdir}' PLUGIN_CFLAGS='-fPIC -DPIC' PLUGIN_LDFLAGS='-bundle -undefined dynamic_lookup' PLUGIN_SUFFIX='.impl' - INSTALL_LIB='${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib && ${LN_S} -f $${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.dylib && ${LN_S} -f $${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib ${DESTDIR}${libdir}/$$i' - UNINSTALL_LIB='rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.dylib ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib' + INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib && ${LN_S} -f $${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.dylib && ${LN_S} -f $${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib ${DESTDIR}${libdir}/$$i' + UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.dylib ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib' CLEAN_LIB='' ;; solaris*) AC_MSG_RESULT(Solaris) LIB_CFLAGS='-fPIC -DPIC' @@ -113,12 +113,12 @@ LIB_SUFFIX='.so' LDFLAGS_RPATH='-Wl,-rpath,${libdir}' PLUGIN_CFLAGS='-fPIC -DPIC' PLUGIN_LDFLAGS='-shared' PLUGIN_SUFFIX='.so' - INSTALL_LIB='${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR} && rm -f ${DESTDIR}${libdir}/$$i && ${LN_S} $$i.${LIB_MAJOR}.${LIB_MINOR} ${DESTDIR}${libdir}/$$i' - UNINSTALL_LIB='rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}' + INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR} && rm -f ${DESTDIR}${libdir}/$$i && ${LN_S} $$i.${LIB_MAJOR}.${LIB_MINOR} ${DESTDIR}${libdir}/$$i' + UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}' CLEAN_LIB='' ;; openbsd* | mirbsd*) AC_MSG_RESULT(OpenBSD) LIB_CFLAGS='-fPIC -DPIC' @@ -127,12 +127,12 @@ LIB_SUFFIX='.so.${LIB_MAJOR}.${LIB_MINOR}' LDFLAGS_RPATH='-Wl,-rpath,${libdir}' PLUGIN_CFLAGS='-fPIC -DPIC' PLUGIN_LDFLAGS='-shared' PLUGIN_SUFFIX='.so' - INSTALL_LIB='${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i' - UNINSTALL_LIB='rm -f ${DESTDIR}${libdir}/$$i' + INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i' + UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i' CLEAN_LIB='' ;; cygwin* | mingw*) AC_MSG_RESULT(Win32) LIB_CFLAGS='' @@ -141,12 +141,12 @@ LIB_SUFFIX='.dll' LDFLAGS_RPATH='-Wl,-rpath,${libdir}' PLUGIN_CFLAGS='' PLUGIN_LDFLAGS='-shared' PLUGIN_SUFFIX='.dll' - INSTALL_LIB='${MKDIR_P} ${DESTDIR}${bindir} && ${INSTALL} -m 755 $$i ${DESTDIR}${bindir}/$$i && ${INSTALL} -m 755 $$i.a ${DESTDIR}${libdir}/$$i.a' - UNINSTALL_LIB='rm -f ${DESTDIR}${bindir}/$$i ${DESTDIR}${libdir}/$$i.a' + INSTALL_LIB='&& ${MKDIR_P} ${DESTDIR}${bindir} && ${INSTALL} -m 755 $$i ${DESTDIR}${bindir}/$$i && ${INSTALL} -m 755 $$i.a ${DESTDIR}${libdir}/$$i.a' + UNINSTALL_LIB='&& rm -f ${DESTDIR}${bindir}/$$i ${DESTDIR}${libdir}/$$i.a' CLEAN_LIB='${LIB}.a' ;; *) AC_MSG_RESULT(GNU) LIB_CFLAGS='-fPIC -DPIC' @@ -155,12 +155,12 @@ LIB_SUFFIX='.so' LDFLAGS_RPATH='-Wl,-rpath,${libdir}' PLUGIN_CFLAGS='-fPIC -DPIC' PLUGIN_LDFLAGS='-shared' PLUGIN_SUFFIX='.so' - INSTALL_LIB='${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.0 && ${LN_S} -f $$i.${LIB_MAJOR}.${LIB_MINOR}.0 ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} && ${LN_S} -f $$i.${LIB_MAJOR}.${LIB_MINOR}.0 ${DESTDIR}${libdir}/$$i' - UNINSTALL_LIB='rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.0' + INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.0 && ${LN_S} -f $$i.${LIB_MAJOR}.${LIB_MINOR}.0 ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} && ${LN_S} -f $$i.${LIB_MAJOR}.${LIB_MINOR}.0 ${DESTDIR}${libdir}/$$i' + UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.0' CLEAN_LIB='' ;; esac AC_SUBST(LIB_CFLAGS) Index: src/OFBlock.m ================================================================== --- src/OFBlock.m +++ src/OFBlock.m @@ -59,14 +59,17 @@ void *protocols, *gc_object_type; long abi_version; void *ivar_offsets, *properties; }; +#ifndef OF_OBJFW_RUNTIME +/* ObjFW-RT already defines those */ enum objc_abi_class_info { OBJC_CLASS_INFO_CLASS = 0x01, OBJC_CLASS_INFO_METACLASS = 0x02 }; +#endif extern void __objc_exec_class(void*); /* Begin of ObjC module */ static struct objc_abi_metaclass _NSConcreteStackBlock_metaclass = { @@ -179,21 +182,15 @@ if (block->isa == (Class)&_NSConcreteMallocBlock) { #if defined(OF_ATOMIC_OPS) of_atomic_inc_int(&block->flags); #else -# ifdef OF_THREADS unsigned hash = SPINLOCK_HASH(block); assert(of_spinlock_lock(&spinlocks[hash])); -# endif - block->flags++; - -# ifdef OF_THREADS assert(of_spinlock_unlock(&spinlocks[hash])); -# endif #endif } return block; } @@ -212,30 +209,22 @@ block->descriptor->dispose_helper(block); free(block); } #else -# ifdef OF_THREADS unsigned hash = SPINLOCK_HASH(block); assert(of_spinlock_lock(&spinlocks[hash])); -# endif - if ((--block->flags & OF_BLOCK_REFCOUNT_MASK) == 0) { -# ifdef OF_THREADS assert(of_spinlock_unlock(&spinlocks[hash])); -# endif if (block->flags & OF_BLOCK_HAS_COPY_DISPOSE) block->descriptor->dispose_helper(block); free(block); } - -# ifdef OF_THREADS assert(of_spinlock_unlock(&spinlocks[hash])); -# endif #endif } void _Block_object_assign(void *dst_, const void *src_, const int flags_) @@ -333,11 +322,11 @@ free(tmp); objc_registerClassPair((Class)&_NSConcreteMallocBlock); } #endif -#if !defined(OF_ATOMIC_OPS) && defined(OF_THREADS) +#if !defined(OF_ATOMIC_OPS) + (void)initialize { size_t i; for (i = 0; i < NUM_SPINLOCKS; i++) Index: src/OFConstantString.m ================================================================== --- src/OFConstantString.m +++ src/OFConstantString.m @@ -51,18 +51,18 @@ @throw [OFNotImplementedException newWithClass: isa selector: _cmd]; } - initWithCString: (const char*)str - encoding: (enum of_string_encoding)encoding; + encoding: (of_string_encoding_t)encoding; { @throw [OFNotImplementedException newWithClass: isa selector: _cmd]; } - initWithCString: (const char*)str - encoding: (enum of_string_encoding)encoding + encoding: (of_string_encoding_t)encoding length: (size_t)len { @throw [OFNotImplementedException newWithClass: isa selector: _cmd]; } Index: src/OFDataArray.m ================================================================== --- src/OFDataArray.m +++ src/OFDataArray.m @@ -207,11 +207,11 @@ data = [self resizeMemory: data toNItems: count withSize: itemSize]; } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ - [e dealloc]; + [e release]; } } - (void)removeNItems: (size_t)nitems atIndex: (size_t)index @@ -227,11 +227,11 @@ data = [self resizeMemory: data toNItems: count withSize: itemSize]; } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ - [e dealloc]; + [e release]; } } - copy { Index: src/OFDate.h ================================================================== --- src/OFDate.h +++ src/OFDate.h @@ -222,16 +222,16 @@ * \return The microseconds part of the seconds since 1970-01-01T00:00:00Z */ - (uint32_t)microsecondsOfTimeIntervalSince1970; /** - * \return The seconds the date is after the receiver + * \return The seconds the receiver is after the date. */ - (int64_t)timeIntervalSinceDate: (OFDate*)date; /** - * \return The microseconds part of the seconds the date is after the receiver + * \return The microseconds part of the seconds the receiver is after the date */ - (uint32_t)microsecondsOfTimeIntervalSinceDate: (OFDate*)date; /** * Returns a new date with the specified time interval added. Index: src/OFDate.m ================================================================== --- src/OFDate.m +++ src/OFDate.m @@ -463,11 +463,11 @@ while (usec_ > 999999) { usec_ -= 1000000; sec_++; } - while (usec < 0) { + while (usec_ < 0) { usec_ += 1000000; sec_--; } return sec_; @@ -478,11 +478,11 @@ int32_t usec_ = (int32_t)usec - date->usec; while (usec_ > 999999) usec_ -= 1000000; - while (usec < 0) + while (usec_ < 0) usec_ += 1000000; return usec_; } Index: src/OFExceptions.h ================================================================== --- src/OFExceptions.h +++ src/OFExceptions.h @@ -326,10 +326,11 @@ * \brief An exception indicating a read or write to a stream failed. */ @interface OFReadOrWriteFailedException: OFException { size_t requestedSize; +@public int errNo; } #ifdef OF_HAVE_PROPERTIES @property (readonly) size_t requestedSize; @@ -1040,46 +1041,40 @@ */ @interface OFBindFailedException: OFException { OFString *node; OFString *service; - int family; int errNo; } #ifdef OF_HAVE_PROPERTIES @property (readonly, nonatomic) OFString *node; @property (readonly, nonatomic) OFString *service; -@property (readonly) int family; @property (readonly) int errNo; #endif /** * \param class_ The class of the object which caused the exception * \param node The node on which binding failed * \param service The service on which binding failed - * \param family The family for which binnding failed * \return A new bind failed exception */ + newWithClass: (Class)class_ node: (OFString*)node - service: (OFString*)service - family: (int)family; + service: (OFString*)service; /** * Initializes an already allocated bind failed exception. * * \param class_ The class of the object which caused the exception * \param node The node on which binding failed * \param service The service on which binding failed - * \param family The family for which binnding failed * \return An initialized bind failed exception */ - initWithClass: (Class)class_ node: (OFString*)node - service: (OFString*)service - family: (int)family; + service: (OFString*)service; /** * \return The errno from when the exception was created */ - (int)errNo; @@ -1091,15 +1086,10 @@ /** * \return The service on which binding failed */ - (OFString*)service; - -/** - * \return The family for which binding failed - */ -- (int)family; @end /** * \brief An exception indicating that listening on the socket failed. */ Index: src/OFExceptions.m ================================================================== --- src/OFExceptions.m +++ src/OFExceptions.m @@ -1519,16 +1519,14 @@ @implementation OFBindFailedException + newWithClass: (Class)class_ node: (OFString*)node service: (OFString*)service - family: (int)family { return [[self alloc] initWithClass: class_ node: node - service: service - family: family]; + service: service]; } - initWithClass: (Class)class_ { Class c = isa; @@ -1538,18 +1536,16 @@ } - initWithClass: (Class)class_ node: (OFString*)node_ service: (OFString*)service_ - family: (int)family_ { self = [super initWithClass: class_]; @try { node = [node_ copy]; service = [service_ copy]; - family = family_; errNo = GET_SOCK_ERRNO; } @catch (id e) { [self release]; @throw e; } @@ -1569,13 +1565,13 @@ { if (description != nil) return description; description = [[OFString alloc] initWithFormat: - @"Binding service %s on node %s using family %d failed in class " - @"%s! " ERRFMT, [service cString], [node cString], family, - class_getName(inClass), ERRPARAM]; + @"Binding service %s on node %s failed in class %s! " ERRFMT, + [service cString], [node cString], class_getName(inClass), + ERRPARAM]; return description; } - (int)errNo @@ -1590,15 +1586,10 @@ - (OFString*)service { return service; } - -- (int)family -{ - return family; -} @end @implementation OFListenFailedException + newWithClass: (Class)class_ backLog: (int)backlog Index: src/OFMutableString.m ================================================================== --- src/OFMutableString.m +++ src/OFMutableString.m @@ -403,11 +403,11 @@ @try { string = [self resizeMemory: string toSize: length + 1]; } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ - [e dealloc]; + [e release]; } } - (void)removeCharactersInRange: (of_range_t)range { @@ -520,11 +520,11 @@ @try { string = [self resizeMemory: string toSize: length + 1]; } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ - [e dealloc]; + [e release]; } } - (void)removeTrailingWhitespaces { @@ -545,11 +545,11 @@ @try { string = [self resizeMemory: string toSize: length + 1]; } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ - [e dealloc]; + [e release]; } } - (void)removeLeadingAndTrailingWhitespaces { @@ -579,14 +579,14 @@ @try { string = [self resizeMemory: string toSize: length + 1]; } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ - [e dealloc]; + [e release]; } } - copy { return [[OFString alloc] initWithString: self]; } @end Index: src/OFNumber.h ================================================================== --- src/OFNumber.h +++ src/OFNumber.h @@ -16,11 +16,14 @@ #include #import "OFObject.h" -enum of_number_type { +/** + * \brief The type of a number. + */ +typedef enum of_number_type_t { OF_NUMBER_BOOL, OF_NUMBER_CHAR, OF_NUMBER_SHORT, OF_NUMBER_INT, OF_NUMBER_LONG, @@ -43,11 +46,11 @@ OF_NUMBER_PTRDIFF, OF_NUMBER_INTPTR, OF_NUMBER_UINTPTR, OF_NUMBER_FLOAT, OF_NUMBER_DOUBLE, -}; +} of_number_type_t; /** * \brief Provides a way to store a number in an object. */ @interface OFNumber: OFObject @@ -78,11 +81,11 @@ intptr_t intptr; uintptr_t uintptr; float float_; double double_; } value; - enum of_number_type type; + of_number_type_t type; } /** * \param bool_ A BOOL which the OFNumber should contain * \return A new autoreleased OFNumber @@ -446,14 +449,13 @@ * \return An initialized OFNumber */ - initWithDouble: (double)double_; /** - * \return An enum of type of_number_type indicating the type of contained - * number of the OFNumber + * \return An of_number_type_t indicating the type of the number */ -- (enum of_number_type)type; +- (of_number_type_t)type; /** * \return The OFNumber as a BOOL */ - (BOOL)boolValue; Index: src/OFNumber.m ================================================================== --- src/OFNumber.m +++ src/OFNumber.m @@ -700,11 +700,11 @@ type = OF_NUMBER_DOUBLE; return self; } -- (enum of_number_type)type +- (of_number_type_t)type { return type; } - (BOOL)boolValue Index: src/OFObject.m ================================================================== --- src/OFObject.m +++ src/OFObject.m @@ -58,11 +58,11 @@ struct pre_ivar { void **memchunks; size_t memchunks_size; int32_t retain_count; -#if !defined(OF_ATOMIC_OPS) && defined(OF_THREADS) +#if !defined(OF_ATOMIC_OPS) of_spinlock_t retain_spinlock; #endif }; /* Hopefully no arch needs more than 16 bytes padding */ @@ -146,11 +146,11 @@ ((struct pre_ivar*)instance)->memchunks = NULL; ((struct pre_ivar*)instance)->memchunks_size = 0; ((struct pre_ivar*)instance)->retain_count = 1; -#if !defined(OF_ATOMIC_OPS) && defined(OF_THREADS) +#if !defined(OF_ATOMIC_OPS) if (!of_spinlock_new(&((struct pre_ivar*)instance)->retain_spinlock)) { free(instance); @throw [OFInitializationFailedException newWithClass: self]; } #endif @@ -663,16 +663,14 @@ - retain { #if defined(OF_ATOMIC_OPS) of_atomic_inc_32(&PRE_IVAR->retain_count); -#elif defined(OF_THREADS) +#else assert(of_spinlock_lock(&PRE_IVAR->retain_spinlock)); PRE_IVAR->retain_count++; assert(of_spinlock_unlock(&PRE_IVAR->retain_spinlock)); -#else - PRE_IVAR->retain_count++; #endif return self; } @@ -685,22 +683,19 @@ - (void)release { #if defined(OF_ATOMIC_OPS) if (of_atomic_dec_32(&PRE_IVAR->retain_count) <= 0) [self dealloc]; -#elif defined(OF_THREADS) +#else size_t c; assert(of_spinlock_lock(&PRE_IVAR->retain_spinlock)); c = --PRE_IVAR->retain_count; assert(of_spinlock_unlock(&PRE_IVAR->retain_spinlock)); if (!c) [self dealloc]; -#else - if (--PRE_IVAR->retain_count <= 0) - [self dealloc]; #endif } - autorelease { Index: src/OFStream.h ================================================================== --- src/OFStream.h +++ src/OFStream.h @@ -15,12 +15,12 @@ */ #include #import "OFObject.h" +#import "OFString.h" -@class OFString; @class OFDataArray; /** * \brief A base class for different types of streams. * @@ -183,11 +183,11 @@ * * \param encoding The encoding used by the stream * \return The line that was read, autoreleased, or nil if the end of the * stream has been reached. */ -- (OFString*)readLineWithEncoding: (enum of_string_encoding)encoding; +- (OFString*)readLineWithEncoding: (of_string_encoding_t)encoding; /** * Read until the specified string or \\0 is found or the end of stream occurs. * * \param delimiter The delimiter @@ -203,11 +203,11 @@ * \param encoding The encoding used by the stream * \return The line that was read, autoreleased, or nil if the end of the * stream has been reached. */ - (OFString*)readTillDelimiter: (OFString*)delimiter - withEncoding: (enum of_string_encoding)encoding; + withEncoding: (of_string_encoding_t)encoding; /** * \return A boolean whether writes are buffered */ - (BOOL)buffersWrites; Index: src/OFStream.m ================================================================== --- src/OFStream.m +++ src/OFStream.m @@ -22,10 +22,14 @@ #include #include #include #include + +#ifndef _WIN32 +# include +#endif #import "OFStream.h" #import "OFString.h" #import "OFDataArray.h" #import "OFExceptions.h" @@ -32,10 +36,18 @@ #import "macros.h" #import "asprintf.h" @implementation OFStream +#ifndef _WIN32 ++ (void)initialize +{ + if (self == [OFStream class]) + signal(SIGPIPE, SIG_IGN); +} +#endif + - init { if (isa == [OFStream class]) { Class c = isa; [self release]; @@ -240,11 +252,11 @@ - (OFString*)readLine { return [self readLineWithEncoding: OF_STRING_ENCODING_UTF_8]; } -- (OFString*)readLineWithEncoding: (enum of_string_encoding)encoding +- (OFString*)readLineWithEncoding: (of_string_encoding_t)encoding { size_t i, len, ret_len; char *ret_c, *tmp, *tmp2; OFString *ret; @@ -388,11 +400,11 @@ return [self readTillDelimiter: delimiter withEncoding: OF_STRING_ENCODING_UTF_8]; } - (OFString*)readTillDelimiter: (OFString*)delimiter - withEncoding: (enum of_string_encoding)encoding + withEncoding: (of_string_encoding_t)encoding { const char *delim; size_t i, j, delim_len, len, ret_len; char *ret_c, *tmp, *tmp2; OFString *ret; @@ -630,14 +642,24 @@ fromBuffer: [str cString]]; } - (size_t)writeLine: (OFString*)str { - size_t ret = [self writeString: str]; - [self writeInt8: '\n']; + size_t len = [str cStringLength]; + char *buf; + + buf = [self allocMemoryWithSize: len + 1]; + + @try { + memcpy(buf, [str cString], len); + buf[len] = '\n'; - return ret + 1; + return [self writeNBytes: len + 1 + fromBuffer: buf]; + } @finally { + [self freeMemory: buf]; + } } - (size_t)writeFormat: (OFString*)fmt, ... { va_list args; Index: src/OFStreamSocket.m ================================================================== --- src/OFStreamSocket.m +++ src/OFStreamSocket.m @@ -66,17 +66,25 @@ ssize_t ret; if (sock == INVALID_SOCKET) @throw [OFNotConnectedException newWithClass: isa]; + if (eos) { + OFReadFailedException *e; + + e = [OFReadFailedException newWithClass: isa + requestedSize: size]; #ifndef _WIN32 - /* FIXME: We want a sane error message on Win32 as well */ - if (eos) - errno = ENOTCONN; + e->errNo = ENOTCONN; +#else + e->errNo = WSAENOTCONN; #endif - if (eos || (ret = recv(sock, buf, size, 0)) < 0) + @throw e; + } + + if ((ret = recv(sock, buf, size, 0)) < 0) @throw [OFReadFailedException newWithClass: isa requestedSize: size]; if (ret == 0) eos = YES; @@ -90,17 +98,25 @@ ssize_t ret; if (sock == INVALID_SOCKET) @throw [OFNotConnectedException newWithClass: isa]; + if (eos) { + OFWriteFailedException *e; + + e = [OFWriteFailedException newWithClass: isa + requestedSize: size]; #ifndef _WIN32 - /* FIXME: We want a sane error message on Win32 as well */ - if (eos) - errno = ENOTCONN; + e->errNo = ENOTCONN; +#else + e->errNo = WSAENOTCONN; #endif - if (eos || (ret = send(sock, buf, size, 0)) == -1) + @throw e; + } + + if ((ret = send(sock, buf, size, 0)) == -1) @throw [OFWriteFailedException newWithClass: isa requestedSize: size]; /* This is safe, as we already checked for -1 */ return ret; Index: src/OFString.h ================================================================== --- src/OFString.h +++ src/OFString.h @@ -19,16 +19,19 @@ #import "OFObject.h" typedef uint32_t of_unichar_t; -enum of_string_encoding { +/** + * \brief The encoding of a string. + */ +typedef enum of_string_encoding_t { OF_STRING_ENCODING_UTF_8, OF_STRING_ENCODING_ISO_8859_1, OF_STRING_ENCODING_ISO_8859_15, OF_STRING_ENCODING_WINDOWS_1252 -}; +} of_string_encoding_t; extern int of_string_check_utf8(const char*, size_t); extern size_t of_string_unicode_to_utf8(of_unichar_t, char*); extern size_t of_string_utf8_to_unicode(const char*, size_t, of_unichar_t*); extern size_t of_string_position_to_index(const char*, size_t); @@ -68,11 +71,11 @@ * \param str A C string to initialize the OFString with * \param encoding The encoding of the C string * \return A new autoreleased OFString */ + stringWithCString: (const char*)str - encoding: (enum of_string_encoding)encoding; + encoding: (of_string_encoding_t)encoding; /** * Creates a new OFString from a C string with the specified encoding and * length. * @@ -80,11 +83,11 @@ * \param encoding The encoding of the C string * \param len The length of the C string * \return A new autoreleased OFString */ + stringWithCString: (const char*)str - encoding: (enum of_string_encoding)encoding + encoding: (of_string_encoding_t)encoding length: (size_t)len; /** * Creates a new OFString from a UTF-8 encoded C string with the specified * length. @@ -136,11 +139,11 @@ * \param path The path to the file * \param encoding The encoding of the file * \return A new autoreleased OFString */ + stringWithContentsOfFile: (OFString*)path - encoding: (enum of_string_encoding)encoding; + encoding: (of_string_encoding_t)encoding; /** * Initializes an already allocated OFString from a UTF-8 encoded C string. * * \param str A UTF-8 encoded C string to initialize the OFString with @@ -155,11 +158,11 @@ * \param str A C string to initialize the OFString with * \param encoding The encoding of the C string * \return An initialized OFString */ - initWithCString: (const char*)str - encoding: (enum of_string_encoding)encoding; + encoding: (of_string_encoding_t)encoding; /** * Initializes an already allocated OFString from a C string with the specified * encoding and length. * @@ -167,11 +170,11 @@ * \param encoding The encoding of the C string * \param len The length of the C string * \return An initialized OFString */ - initWithCString: (const char*)str - encoding: (enum of_string_encoding)encoding + encoding: (of_string_encoding_t)encoding length: (size_t)len; /** * Initializes an already allocated OFString from a UTF-8 encoded C string with * the specified length. @@ -247,11 +250,11 @@ * \param path The path to the file * \param encoding The encoding of the file * \return An initialized OFString */ - initWithContentsOfFile: (OFString*)path - encoding: (enum of_string_encoding)encoding; + encoding: (of_string_encoding_t)encoding; /** * \return The OFString as a UTF-8 encoded C string */ - (const char*)cString; Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -240,18 +240,18 @@ { return [[[self alloc] initWithCString: str] autorelease]; } + stringWithCString: (const char*)str - encoding: (enum of_string_encoding)encoding + encoding: (of_string_encoding_t)encoding { return [[[self alloc] initWithCString: str encoding: encoding] autorelease]; } + stringWithCString: (const char*)str - encoding: (enum of_string_encoding)encoding + encoding: (of_string_encoding_t)encoding length: (size_t)len { return [[[self alloc] initWithCString: str encoding: encoding length: len] autorelease]; @@ -299,11 +299,11 @@ { return [[[self alloc] initWithContentsOfFile: path] autorelease]; } + stringWithContentsOfFile: (OFString*)path - encoding: (enum of_string_encoding)encoding + encoding: (of_string_encoding_t)encoding { return [[[self alloc] initWithContentsOfFile: path encoding: encoding] autorelease]; } @@ -313,19 +313,19 @@ encoding: OF_STRING_ENCODING_UTF_8 length: strlen(str)]; } - initWithCString: (const char*)str - encoding: (enum of_string_encoding)encoding + encoding: (of_string_encoding_t)encoding { return [self initWithCString: str encoding: encoding length: strlen(str)]; } - initWithCString: (const char*)str - encoding: (enum of_string_encoding)encoding + encoding: (of_string_encoding_t)encoding length: (size_t)len { self = [super init]; @try { @@ -617,11 +617,11 @@ return [self initWithContentsOfFile: path encoding: OF_STRING_ENCODING_UTF_8]; } - initWithContentsOfFile: (OFString*)path - encoding: (enum of_string_encoding)encoding + encoding: (of_string_encoding_t)encoding { self = [super init]; @try { OFFile *file; @@ -974,11 +974,11 @@ - (intmax_t)decimalValue { int i = 0; intmax_t num = 0; - if (string[0] == '-') + if (string[0] == '-' || string[0] == '+') i++; for (; i < length; i++) { if (string[i] >= '0' && string[i] <= '9') { if (INTMAX_MAX / 10 < num || Index: src/OFTCPSocket.h ================================================================== --- src/OFTCPSocket.h +++ src/OFTCPSocket.h @@ -56,12 +56,11 @@ * \param node The node to bind to. Use @"0.0.0.0" for IPv4 or @"::" for IPv6 * to bind to all. * \param family The family to use (AF_INET for IPv4 or AF_INET6 for IPv6) */ - (void)bindService: (OFString*)service - onNode: (OFString*)node - withFamily: (int)family; + onNode: (OFString*)node; /** * Listen on the socket. * * \param backlog Maximum length for the queue of pending connections. Index: src/OFTCPSocket.m ================================================================== --- src/OFTCPSocket.m +++ src/OFTCPSocket.m @@ -199,53 +199,39 @@ service: service]; } - (void)bindService: (OFString*)service onNode: (OFString*)node - withFamily: (int)family { if (sock != INVALID_SOCKET) @throw [OFAlreadyConnectedException newWithClass: isa]; -#ifndef HAVE_THREADSAFE_GETADDRINFO - if (family != AF_INET) - @throw [OFBindFailedException newWithClass: isa - node: node - service: service - family: family]; -#endif - - if ((sock = socket(family, SOCK_STREAM, 0)) == INVALID_SOCKET) - @throw [OFBindFailedException newWithClass: isa - node: node - service: service - family: family]; - #ifdef HAVE_THREADSAFE_GETADDRINFO struct addrinfo hints, *res; memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = family; + hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; - if (getaddrinfo([node cString], [service cString], &hints, &res)) { - close(sock); - sock = INVALID_SOCKET; + if (getaddrinfo([node cString], [service cString], &hints, &res)) @throw [OFAddressTranslationFailedException newWithClass: isa node: node service: service]; - } + + if ((sock = socket(res->ai_family, SOCK_STREAM, 0)) == INVALID_SOCKET) + @throw [OFBindFailedException newWithClass: isa + node: node + service: service]; if (bind(sock, res->ai_addr, res->ai_addrlen) == -1) { freeaddrinfo(res); close(sock); sock = INVALID_SOCKET; @throw [OFBindFailedException newWithClass: isa node: node - service: service - family: family]; + service: service]; } freeaddrinfo(res); #else struct hostent *he; @@ -272,12 +258,10 @@ else if ((port = OF_BSWAP16_IF_LE(strtol([service cString], NULL, 10))) == 0) { # ifdef OF_THREADS [mutex unlock]; # endif - close(sock); - sock = INVALID_SOCKET; @throw [OFAddressTranslationFailedException newWithClass: isa node: node service: service]; } @@ -288,12 +272,10 @@ if (he->h_addrtype != AF_INET || he->h_addr_list[0] == NULL) { # ifdef OF_THREADS [mutex unlock]; # endif - close(sock); - sock = INVALID_SOCKET; @throw [OFAddressTranslationFailedException newWithClass: isa node: node service: service]; } @@ -301,18 +283,21 @@ memcpy(&addr.sin_addr.s_addr, he->h_addr_list[0], he->h_length); # ifdef OF_THREADS [mutex unlock]; # endif + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) + @throw [OFBindFailedException newWithClass: isa + node: node + service: service]; if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) { close(sock); sock = INVALID_SOCKET; @throw [OFBindFailedException newWithClass: isa node: node - service: service - family: family]; + service: service]; } #endif } - (void)listenWithBackLog: (int)backlog @@ -350,16 +335,16 @@ addrlen = sizeof(struct sockaddr); @try { addr = [newsock allocMemoryWithSize: sizeof(struct sockaddr)]; } @catch (id e) { - [newsock dealloc]; + [newsock release]; @throw e; } if ((s = accept(sock, addr, &addrlen)) == INVALID_SOCKET) { - [newsock dealloc]; + [newsock release]; @throw [OFAcceptFailedException newWithClass: isa]; } newsock->sock = s; newsock->sockAddr = addr; Index: src/OFThread.h ================================================================== --- src/OFThread.h +++ src/OFThread.h @@ -17,10 +17,12 @@ #import "OFObject.h" #import "OFList.h" #import "threading.h" +@class OFDate; + /** * \brief A class for Thread Local Storage keys. */ @interface OFTLSKey: OFObject { @@ -33,17 +35,17 @@ } /** * \return A new autoreleased Thread Local Storage key */ -+ tlsKey; ++ TLSKey; /** * \param destructor A destructor that is called when the thread is terminated * \return A new autoreleased Thread Local Storage key */ -+ tlsKeyWithDestructor: (void(*)(id))destructor; ++ TLSKeyWithDestructor: (void(*)(id))destructor; + (void)callAllDestructors; /** * \return An initialized Thread Local Storage key @@ -74,13 +76,18 @@ OF_THREAD_WAITING_FOR_JOIN } running; id retval; } +/** + * \return A new, autoreleased thread + */ ++ thread; + /** * \param obj An object that is passed to the main method as a copy or nil - * \return A new autoreleased thread + * \return A new, autoreleased thread */ + threadWithObject: (id)obj; /** * Sets the Thread Local Storage for the specified key. @@ -89,14 +96,13 @@ * released. You can specify nil as object if you want the old object to be * released and don't want any new object for the TLS key. * * \param key The Thread Local Storage key * \param obj The object the Thread Local Storage key will be set to - * \return The old object, autoreleased */ -+ (id)setObject: (id)obj - forTLSKey: (OFTLSKey*)key; ++ (void)setObject: (id)obj + forTLSKey: (OFTLSKey*)key; /** * Returns the object for the specified Thread Local Storage key. * * The returned object is not retained and autoreleased for performance @@ -110,13 +116,29 @@ * \return The current thread or nil if we are in the main thread */ + (OFThread*)currentThread; /** - * Suspends execution of the current thread for N milliseconds. + * Suspends execution of the current thread for the specified time interval. + * + * \param sec The number of seconds to sleep + */ ++ (void)sleepForTimeInterval: (int64_t)sec; + +/** + * Suspends execution of the current thread for the specified time interval. + * + * \param sec The number of seconds to sleep + * \param usec The number of microseconds to sleep + */ ++ (void)sleepForTimeInterval: (int64_t)sec + microseconds: (uint32_t)usec; + +/** + * Suspends execution of the current thread until the specified date. */ -+ (void)sleepForNMilliseconds: (unsigned int)msecs; ++ (void)sleepUntilDate: (OFDate*)date; /** * Yields a processor voluntarily and moves the thread at the end of the queue * for its priority. */ Index: src/OFThread.m ================================================================== --- src/OFThread.m +++ src/OFThread.m @@ -23,10 +23,11 @@ # include #endif #import "OFThread.h" #import "OFList.h" +#import "OFDate.h" #import "OFAutoreleasePool.h" #import "OFExceptions.h" #import "threading.h" @@ -65,44 +66,88 @@ return; if (!of_tlskey_new(&thread_self)) @throw [OFInitializationFailedException newWithClass: self]; } + ++ thread +{ + return [[[self alloc] init] autorelease]; +} + threadWithObject: (id)obj { return [[[self alloc] initWithObject: obj] autorelease]; } -+ (id)setObject: (id)obj - forTLSKey: (OFTLSKey*)key ++ (void)setObject: (id)obj + forTLSKey: (OFTLSKey*)key { id old = of_tlskey_get(key->key); if (!of_tlskey_set(key->key, [obj retain])) @throw [OFInvalidArgumentException newWithClass: self selector: _cmd]; - return [old autorelease]; + [old release]; } + (id)objectForTLSKey: (OFTLSKey*)key { - return of_tlskey_get(key->key); + return [[of_tlskey_get(key->key) retain] autorelease]; } + (OFThread*)currentThread { - return of_tlskey_get(thread_self); + return [[of_tlskey_get(thread_self) retain] autorelease]; +} + ++ (void)sleepForTimeInterval: (int64_t)sec +{ + if (sec < 0) + @throw [OFOutOfRangeException newWithClass: self]; + +#ifndef _WIN32 + sleep(sec); +#else + Sleep(sec * 1000); +#endif +} + ++ (void)sleepForTimeInterval: (int64_t)sec + microseconds: (uint32_t)usec +{ + if (sec < 0) + @throw [OFOutOfRangeException newWithClass: self]; + +#ifndef _WIN32 + sleep(sec); + usleep(usec); +#else + Sleep(sec * 1000 + usec / 1000); +#endif } -+ (void)sleepForNMilliseconds: (unsigned int)msecs; ++ (void)sleepUntilDate: (OFDate*)date { + OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; + OFDate *now = [OFDate date]; + int64_t sec; + uint32_t usec; + + if ((sec = [date timeIntervalSinceDate: now]) < 0) + @throw [OFOutOfRangeException newWithClass: self]; + + usec = [date microsecondsOfTimeIntervalSinceDate: now]; + + [pool release]; + #ifndef _WIN32 - usleep(msecs * 1000); + sleep(sec); + usleep(usec); #else - Sleep(msecs); + Sleep(sec * 1000 + usec / 1000); #endif } + (void)yield { @@ -136,18 +181,10 @@ [thread release]; of_thread_exit(); } -- init -{ - Class c = isa; - [self release]; - @throw [OFNotImplementedException newWithClass: c - selector: _cmd]; -} - - initWithObject: (id)obj { self = [super init]; @try { @@ -214,16 +251,16 @@ { if (self == [OFTLSKey class]) tlskeys = [[OFList alloc] init]; } -+ tlsKey ++ TLSKey { return [[[self alloc] init] autorelease]; } -+ tlsKeyWithDestructor: (void(*)(id))destructor ++ TLSKeyWithDestructor: (void(*)(id))destructor { return [[[self alloc] initWithDestructor: destructor] autorelease]; } + (void)callAllDestructors Index: tests/OFBlockTests.m ================================================================== --- tests/OFBlockTests.m +++ tests/OFBlockTests.m @@ -23,10 +23,12 @@ #if defined(OF_OBJFW_RUNTIME) # include #elif defined(OF_OLD_GNU_RUNTIME) # include +#elif defined(OF_APPLE_RUNTIME) +# include #endif #if defined(OF_OLD_GNU_RUNTIME) || defined(OF_OBJFW_RUNTIME) # define objc_getClass objc_get_class #endif Index: tests/OFStringTests.m ================================================================== --- tests/OFStringTests.m +++ tests/OFStringTests.m @@ -226,10 +226,11 @@ [[a objectAtIndex: i++] isEqual: @""] && [[a objectAtIndex: i++] isEqual: @""]) TEST(@"-[decimalValue]", [@"1234" decimalValue] == 1234 && + [@"+123" decimalValue] == 123 && [@"-500" decimalValue] == -500 && [@"" decimalValue] == 0) TEST(@"-[hexadecimalValue]", [@"123f" hexadecimalValue] == 0x123f && Index: tests/OFTCPSocketTests.m ================================================================== --- tests/OFTCPSocketTests.m +++ tests/OFTCPSocketTests.m @@ -47,14 +47,13 @@ TEST(@"+[socket]", (server = [OFTCPSocket socket]) && (client = [OFTCPSocket socket])) msg = [OFString stringWithFormat: - @"-[bindService:onNode:withFamily:] (port %d)", port]; + @"-[bindService:onNode:] (port %d)", port]; TEST(msg, R([server bindService: service - onNode: @"127.0.0.1" - withFamily: AF_INET])) + onNode: @"127.0.0.1"])) TEST(@"-[listen]", R([server listen])) TEST(@"-[connectToService:onNode:]", R([client connectToService: service Index: tests/OFThreadTests.m ================================================================== --- tests/OFThreadTests.m +++ tests/OFThreadTests.m @@ -50,19 +50,19 @@ TEST(@"-[start]", R([t start])) TEST(@"-[join]", [[t join] isEqual: @"success"]) - TEST(@"OFTLSKey's +[tlsKey]", (key = [OFTLSKey tlsKey])) + TEST(@"OFTLSKey's +[TLSKey]", (key = [OFTLSKey TLSKey])) TEST(@"+[setObject:forTLSKey:]", R([OFThread setObject: @"setme" forTLSKey: key]) && - [[OFThread setObject: @"foo" - forTLSKey: key] isEqual: @"setme"]) + R([OFThread setObject: @"foo" + forTLSKey: key])) TEST(@"+[objectForTLSKey:]", [[OFThread objectForTLSKey: key] isEqual: @"foo"]) [pool drain]; } @end Index: utils/objfw-compile ================================================================== --- utils/objfw-compile +++ utils/objfw-compile @@ -103,10 +103,14 @@ CPPFLAGS="$CPPFLAGS -D$1" ;; -D*) CPPFLAGS="$CPPFLAGS $1" ;; + -framework) + shift + LIBS="$LIBS -framework $1" + ;; -g*) OBJCFLAGS="$OBJCFLAGS $1" ;; -I) shift @@ -178,12 +182,11 @@ else obj="${i%.m}.o" fi objs="$objs $obj" build="no" - deps=$($OBJC -E -M $CPPFLAGS $ENV_CPPFLAGS $i | \ - sed 's/.*: //' | sed 's/\\//g') + deps=$($OBJC -E -M $CPPFLAGS $i | sed 's/.*: //' | sed 's/\\//g') if test -f "$obj"; then for dep in $deps; do test "$dep" -nt $obj && build="yes" done @@ -208,9 +211,9 @@ LDFLAGS="$LDFLAGS $($OBJFW_CONFIG --lib-ldflags)" fi if test ! -f "$out_prefix$out$out_suffix" -o x"$link" = x"yes"; then status_linking $out_prefix$out$out_suffix - $OBJC -o $out_prefix$out$out_suffix $objs $LIBS $ENV_LIBS $LDFLAGS \ - $ENV_LDFLAGS || status_link_failed $out $? + $OBJC -o $out_prefix$out$out_suffix $objs $LIBS $LDFLAGS || \ + status_link_failed $out $? status_linked $out_prefix$out$out_suffix fi