Index: .fossil-settings/clean-glob ================================================================== --- .fossil-settings/clean-glob +++ .fossil-settings/clean-glob @@ -6,10 +6,11 @@ *.exe *.framework *.library *.map *.o +*.sl *.so *.so.* */.deps .deps aclocal.m4 @@ -25,12 +26,14 @@ extra.mk generators/library/gen_libraries generators/unicode/gen_tables src/Info.plist src/bridge/Info.plist +src/libobjfw.* src/objfw-defs.h src/runtime/Info.plist +src/runtime/libobjfwrt.* tests/DerivedData tests/EBOOT.PBP tests/Info.plist tests/PARAM.SFO tests/objc_sync/objc_sync Index: .fossil-settings/ignore-glob ================================================================== --- .fossil-settings/ignore-glob +++ .fossil-settings/ignore-glob @@ -7,10 +7,11 @@ *.framework *.library *.map *.o *.orig +*.sl *.so *.so.* */.deps .deps .git @@ -27,12 +28,14 @@ extra.mk generators/library/gen_libraries generators/unicode/gen_tables src/Info.plist src/bridge/Info.plist +src/libobjfw.* src/objfw-defs.h src/runtime/Info.plist +src/runtime/libobjfwrt.* tests/DerivedData tests/EBOOT.PBP tests/Info.plist tests/PARAM.SFO tests/iOS.xcodeproj/*.pbxuser Index: .gitignore ================================================================== --- .gitignore +++ .gitignore @@ -7,10 +7,11 @@ *.framework *.library *.map *.o *.orig +*.sl *.so *.so.* .deps .fslckout _FOSSIL_ @@ -27,12 +28,14 @@ extra.mk generators/library/gen_libraries generators/unicode/gen_tables src/Info.plist src/bridge/Info.plist +src/libobjfw.* src/objfw-defs.h src/runtime/Info.plist +src/runtime/libobjfwrt.* tests/DerivedData tests/EBOOT.PBP tests/Info.plist tests/PARAM.SFO tests/iOS.xcodeproj/*.pbxuser Index: build-aux/m4/buildsys.m4 ================================================================== --- build-aux/m4/buildsys.m4 +++ build-aux/m4/buildsys.m4 @@ -1,8 +1,8 @@ dnl dnl Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2016, 2017, -dnl 2018, 2020 +dnl 2018, 2020, 2021 dnl Jonathan Schleifer dnl dnl https://fossil.nil.im/buildsys dnl dnl Permission to use, copy, modify, and/or distribute this software for any @@ -165,12 +165,12 @@ AC_DEFUN([BUILDSYS_SHARED_LIB], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([BUILDSYS_CHECK_IOS]) AC_MSG_CHECKING(for shared library system) - case "$host_os" in - darwin*) + case "$host" in + *-*-darwin*) AC_MSG_RESULT(Darwin) LIB_CFLAGS='-fPIC -DPIC' LIB_LDFLAGS='-dynamiclib -current_version ${LIB_MAJOR}.${LIB_MINOR} -compatibility_version ${LIB_MAJOR}' LIB_LDFLAGS_INSTALL_NAME='-Wl,-install_name,${libdir}/$${out%.dylib}.${LIB_MAJOR}.dylib' LIB_PREFIX='lib' @@ -188,14 +188,14 @@ UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.dylib ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib' INSTALL_PLUGIN='&& rm -fr ${DESTDIR}${plugindir}/$$i && cp -R $$i ${DESTDIR}${plugindir}/' UNINSTALL_PLUGIN='&& rm -fr ${DESTDIR}${plugindir}/$$i' CLEAN_LIB='' ;; - mingw* | cygwin*) + *-*-mingw* | *-*-cygwin*) AC_MSG_RESULT(MinGW / Cygwin) LIB_CFLAGS='' - LIB_LDFLAGS='-shared -Wl,--export-all-symbols,--out-implib,lib${SHARED_LIB}.a' + LIB_LDFLAGS='-shared -Wl,--export-all-symbols,--out-implib,lib$$out.a' LIB_LDFLAGS_INSTALL_NAME='' LIB_PREFIX='' LIB_SUFFIX='.dll' LDFLAGS_RPATH='-Wl,-rpath,${libdir}' PLUGIN_CFLAGS='' @@ -204,13 +204,13 @@ LINK_PLUGIN='${LD} -o $$out ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS}' INSTALL_LIB='&& ${MKDIR_P} ${DESTDIR}${bindir} && ${INSTALL} -m 755 $$i ${DESTDIR}${bindir}/$$i && ${INSTALL} -m 755 lib$$i.a ${DESTDIR}${libdir}/lib$$i.a' UNINSTALL_LIB='&& rm -f ${DESTDIR}${bindir}/$$i ${DESTDIR}${libdir}/lib$$i.a' INSTALL_PLUGIN='&& ${INSTALL} -m 755 $$i ${DESTDIR}${plugindir}/$$i' UNINSTALL_PLUGIN='&& rm -f ${DESTDIR}${plugindir}/$$i' - CLEAN_LIB='${SHARED_LIB}.a' + CLEAN_LIB='${SHARED_LIB}.a ${SHARED_LIB_NOINST}.a' ;; - openbsd* | mirbsd*) + *-*-openbsd* | *-*-mirbsd*) AC_MSG_RESULT(OpenBSD) LIB_CFLAGS='-fPIC -DPIC' LIB_LDFLAGS='-shared' LIB_LDFLAGS_INSTALL_NAME='' LIB_PREFIX='lib' @@ -224,14 +224,14 @@ UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i' INSTALL_PLUGIN='&& ${INSTALL} -m 755 $$i ${DESTDIR}${plugindir}/$$i' UNINSTALL_PLUGIN='&& rm -f ${DESTDIR}${plugindir}/$$i' CLEAN_LIB='' ;; - solaris*) + *-*-solaris*) AC_MSG_RESULT(Solaris) LIB_CFLAGS='-fPIC -DPIC' - LIB_LDFLAGS='-shared -Wl,-soname=${SHARED_LIB}.${LIB_MAJOR}.${LIB_MINOR}' + LIB_LDFLAGS='-shared -Wl,-soname=$$out.${LIB_MAJOR}.${LIB_MINOR}' LIB_LDFLAGS_INSTALL_NAME='' LIB_PREFIX='lib' LIB_SUFFIX='.so' LDFLAGS_RPATH='-Wl,-rpath,${libdir}' PLUGIN_CFLAGS='-fPIC -DPIC' @@ -242,14 +242,14 @@ UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}' INSTALL_PLUGIN='&& ${INSTALL} -m 755 $$i ${DESTDIR}${plugindir}/$$i' UNINSTALL_PLUGIN='&& rm -f ${DESTDIR}${plugindir}/$$i' CLEAN_LIB='' ;; - *-android*) + *-*-android*) AC_MSG_RESULT(Android) LIB_CFLAGS='-fPIC -DPIC' - LIB_LDFLAGS='-shared -Wl,-soname=${SHARED_LIB}.${LIB_MAJOR}' + LIB_LDFLAGS='-shared -Wl,-soname=$$out.${LIB_MAJOR}' LIB_LDFLAGS_INSTALL_NAME='' LIB_PREFIX='lib' LIB_SUFFIX='.so' LDFLAGS_RPATH='' PLUGIN_CFLAGS='-fPIC -DPIC' @@ -260,14 +260,33 @@ UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.0' INSTALL_PLUGIN='&& ${INSTALL} -m 755 $$i ${DESTDIR}${plugindir}/$$i' UNINSTALL_PLUGIN='&& rm -f ${DESTDIR}${plugindir}/$$i' CLEAN_LIB='' ;; + hppa*-*-hpux*) + AC_MSG_RESULT([HP-UX (PA-RISC)]) + LIB_CFLAGS='-fPIC -DPIC' + LIB_LDFLAGS='-shared -Wl,+h,$$out' + LIB_LDFLAGS_INSTALL_NAME='' + LIB_PREFIX='lib' + LIB_SUFFIX='.${LIB_MAJOR}' + LINK_LIB='&& rm -f $${out%%.*}.sl && ${LN_S} $$out $${out%%.*}.sl' + LDFLAGS_RPATH='-Wl,+b,${libdir}' + PLUGIN_CFLAGS='-fPIC -DPIC' + PLUGIN_LDFLAGS='-shared' + PLUGIN_SUFFIX='.sl' + LINK_PLUGIN='${LD} -o $$out ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS}' + INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i && ${LN_S} -f $$i ${DESTDIR}${libdir}/$${i%%.*}.sl' + UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$${i%%.*}.sl' + INSTALL_PLUGIN='&& ${INSTALL} -m 755 $$i ${DESTDIR}${plugindir}/$$i' + UNINSTALL_PLUGIN='&& rm -f ${DESTDIR}${plugindir}/$$i' + CLEAN_LIB='' + ;; *) AC_MSG_RESULT(ELF) LIB_CFLAGS='-fPIC -DPIC' - LIB_LDFLAGS='-shared -Wl,-soname=${SHARED_LIB}.${LIB_MAJOR}' + LIB_LDFLAGS='-shared -Wl,-soname=$$out.${LIB_MAJOR}' LIB_LDFLAGS_INSTALL_NAME='' LIB_PREFIX='lib' LIB_SUFFIX='.so' LDFLAGS_RPATH='-Wl,-rpath,${libdir}' PLUGIN_CFLAGS='-fPIC -DPIC' @@ -285,10 +304,11 @@ AC_SUBST(LIB_CFLAGS) AC_SUBST(LIB_LDFLAGS) AC_SUBST(LIB_LDFLAGS_INSTALL_NAME) AC_SUBST(LIB_PREFIX) AC_SUBST(LIB_SUFFIX) + AC_SUBST(LINK_LIB) AC_SUBST(LDFLAGS_RPATH) AC_SUBST(PLUGIN_CFLAGS) AC_SUBST(PLUGIN_LDFLAGS) AC_SUBST(PLUGIN_SUFFIX) AC_SUBST(LINK_PLUGIN) Index: buildsys.mk.in ================================================================== --- buildsys.mk.in +++ buildsys.mk.in @@ -1,8 +1,8 @@ # # Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, -# 2017, 2018, 2020 +# 2017, 2018, 2020, 2021 # Jonathan Schleifer # # https://fossil.nil.im/buildsys # # Permission to use, copy, modify, and/or distribute this software for any @@ -54,10 +54,11 @@ LIB_CFLAGS = @LIB_CFLAGS@ LIB_LDFLAGS = @LIB_LDFLAGS@ LIB_LDFLAGS_INSTALL_NAME = @LIB_LDFLAGS_INSTALL_NAME@ LIB_PREFIX = @LIB_PREFIX@ LIB_SUFFIX = @LIB_SUFFIX@ +LINK_LIB = @LINK_LIB@ AMIGA_LIB_CFLAGS = @AMIGA_LIB_CFLAGS@ AMIGA_LIB_LDFLAGS = @AMIGA_LIB_LDFLAGS@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PLUGIN_SUFFIX = @PLUGIN_SUFFIX@ @@ -147,11 +148,12 @@ ${DIR_LEAVE}; \ done depend: pre-depend : >.deps - for i in ${DEPS}; do \ + for i in "" ${DEPS}; do \ + test x"$$i" = x"" && continue; \ echo "-include \$${.CURDIR}/$$i" >>.deps; \ done pre-depend: @@ -181,11 +183,11 @@ fi ${SHARED_LIB} ${SHARED_LIB_NOINST}: ${EXT_DEPS} ${LIB_OBJS} ${LIB_OBJS_EXTRA} ${LINK_STATUS} out="$@"; \ - if ${LD} -o $@ ${LIB_OBJS} ${LIB_OBJS_EXTRA} ${LIB_LDFLAGS} ${LIB_LDFLAGS_INSTALL_NAME} ${LDFLAGS} ${LIBS}; then \ + if ${LD} -o $@ ${LIB_OBJS} ${LIB_OBJS_EXTRA} ${LIB_LDFLAGS} ${LIB_LDFLAGS_INSTALL_NAME} ${LDFLAGS} ${LIBS} ${LINK_LIB}; then \ ${LINK_OK}; \ else \ ${LINK_FAILED}; \ fi Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -122,10 +122,24 @@ enable_sockets="no" # TODO check_pedantic="no" AC_SUBST(MAP_LDFLAGS, ['-Wl,-Map,$@.map']) ;; +hppa*-*-hpux*) + dnl Don't default to -g: It creates errors from the assembler and breaks + dnl exceptions. + AS_IF([test x"$OBJCFLAGS" = x""], [OBJCFLAGS="-O2"]) + dnl HP-UX 11.11's inttypes.h defines UINTPTR_MAX etc. to nothing. GCC's + dnl stdint.h defines those correctly, but if inttypes.h gets included + dnl after something included stdint.h, it gets broken again. Therefore, + dnl always include inttypes.h as the very first thing. + dnl We need to put this into OBJCFLAGS and not CPPFLAGS as CPPFLAGS are + dnl also used for .S files. + OBJCFLAGS="$OBJCFLAGS -include inttypes.h" + dnl We need -latomic for GCC's atomics to work. + LIBS="$LIBS -latomic" + ;; esac AS_IF([test x"$host_os" = x"msdosdjgpp" -a x"$build_os" = x"msdosdjgpp"], [ dnl Hack to make configure find these on DOS. : ${AR:=ar.exe} @@ -840,10 +854,12 @@ esac AC_CHECK_LIB(m, fmod, LIBS="$LIBS -lm") AC_CHECK_LIB(complex, creal, TESTS_LIBS="$TESTS_LIBS -lcomplex") +AC_CHECK_FUNCS(strtof truncf) + AC_CHECK_FUNC(asprintf, [ case "$host" in *-*-mingw*) dnl asprintf from MinGW is broken on older Windows versions have_asprintf="no" @@ -1244,20 +1260,22 @@ ]) OBJCFLAGS="$old_OBJCFLAGS" ]) AC_CHECK_HEADERS(dirent.h) -AC_CHECK_FUNCS([sysconf gmtime_r localtime_r nanosleep]) +AC_CHECK_FUNCS([sysconf gmtime_r localtime_r]) case "$host_os" in amigaos* | morphos*) - dnl There is a symbol, but we cannot use fcntl() for sockets on - dnl AmigaOS / MorphOS. + dnl We don't want fcntl() or nanosleep() on AmigaOS / MorphOS, despite + dnl a symbol existing. The reason is that we cannot use fcntl() for + dnl sockets and that nanosleep() is yet another function that uses + dnl errno, so would need to be passed from the linklib. ;; *) AC_CHECK_HEADERS(fcntl.h) - AC_CHECK_FUNCS(fcntl) + AC_CHECK_FUNCS([fcntl nanosleep]) ;; esac AC_CHECK_HEADERS(xlocale.h) AC_CHECK_FUNCS([strtod_l strtof_l asprintf_l]) Index: src/OFKqueueKernelEventObserver.m ================================================================== --- src/OFKqueueKernelEventObserver.m +++ src/OFKqueueKernelEventObserver.m @@ -85,15 +85,15 @@ memset(&event, 0, sizeof(event)); event.ident = object.fileDescriptorForReading; event.filter = EVFILT_READ; event.flags = EV_ADD; -#ifndef OF_NETBSD - event.udata = object; -#else - event.udata = (intptr_t)object; -#endif + /* + * Ugly hack required for NetBSD: NetBSD used `intptr_t` for udata, but + * switched this to `void *` in NetBSD 10. + */ + event.udata = (__typeof__(event.udata))object; if (kevent(_kernelQueue, &event, 1, NULL, 0, NULL) != 0) @throw [OFObserveFailedException exceptionWithObserver: self errNo: errno]; @@ -106,15 +106,15 @@ memset(&event, 0, sizeof(event)); event.ident = object.fileDescriptorForWriting; event.filter = EVFILT_WRITE; event.flags = EV_ADD; -#ifndef OF_NETBSD - event.udata = object; -#else - event.udata = (intptr_t)object; -#endif + /* + * Ugly hack required for NetBSD: NetBSD used `intptr_t` for udata, but + * switched this to `void *` in NetBSD 10. + */ + event.udata = (__typeof__(event.udata))object; if (kevent(_kernelQueue, &event, 1, NULL, 0, NULL) != 0) @throw [OFObserveFailedException exceptionWithObserver: self errNo: errno]; Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -68,12 +68,11 @@ */ #ifdef __MINGW32__ # define strtod __strtod #endif -#ifdef OF_AMIGAOS_M68K -/* libnix has strtod, but not strtof */ +#ifndef HAVE_STRTOF # define strtof strtod #endif #ifndef INFINITY # define INFINITY __builtin_inf() @@ -2500,10 +2499,14 @@ [stripped caseInsensitiveCompare: @"INFINITY"] == OF_ORDERED_SAME) return INFINITY; if ([stripped caseInsensitiveCompare: @"-INF"] == OF_ORDERED_SAME || [stripped caseInsensitiveCompare: @"-INFINITY"] == OF_ORDERED_SAME) return -INFINITY; + if ([stripped caseInsensitiveCompare: @"NAN"] == OF_ORDERED_SAME) + return NAN; + if ([stripped caseInsensitiveCompare: @"-NAN"] == OF_ORDERED_SAME) + return -NAN; #ifdef HAVE_STRTOF_L const char *UTF8String = self.UTF8String; #else /* @@ -2549,10 +2552,14 @@ [stripped caseInsensitiveCompare: @"INFINITY"] == OF_ORDERED_SAME) return INFINITY; if ([stripped caseInsensitiveCompare: @"-INF"] == OF_ORDERED_SAME || [stripped caseInsensitiveCompare: @"-INFINITY"] == OF_ORDERED_SAME) return -INFINITY; + if ([stripped caseInsensitiveCompare: @"NAN"] == OF_ORDERED_SAME) + return NAN; + if ([stripped caseInsensitiveCompare: @"-NAN"] == OF_ORDERED_SAME) + return -NAN; #ifdef HAVE_STRTOD_L const char *UTF8String = self.UTF8String; #else /* Index: src/OFTCPSocket.m ================================================================== --- src/OFTCPSocket.m +++ src/OFTCPSocket.m @@ -338,11 +338,11 @@ #endif setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&one, (socklen_t)sizeof(one)); -#if defined(OF_WII) || defined(OF_NINTENDO_3DS) +#if defined(OF_HPUX) || defined(OF_WII) || defined(OF_NINTENDO_3DS) if (port != 0) { #endif if (bind(_socket, &address.sockaddr.sockaddr, address.length) != 0) { int errNo = of_socket_errno(); @@ -353,11 +353,11 @@ @throw [OFBindFailedException exceptionWithHost: host port: port socket: self errNo: errNo]; } -#if defined(OF_WII) || defined(OF_NINTENDO_3DS) +#if defined(OF_HPUX) || defined(OF_WII) || defined(OF_NINTENDO_3DS) } else { for (;;) { uint16_t rnd = 0; int ret; @@ -391,11 +391,11 @@ objc_autoreleasePoolPop(pool); if (port > 0) return port; -#if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) +#if !defined(OF_HPUX) && !defined(OF_WII) && !defined(OF_NINTENDO_3DS) memset(&address, 0, sizeof(address)); address.length = (socklen_t)sizeof(address.sockaddr); if (of_getsockname(_socket, &address.sockaddr.sockaddr, &address.length) != 0) { Index: src/OFUDPSocket.m ================================================================== --- src/OFUDPSocket.m +++ src/OFUDPSocket.m @@ -63,11 +63,11 @@ if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) { fcntl(_socket, F_SETFD, flags | FD_CLOEXEC); } #endif -#if defined(OF_WII) || defined(OF_NINTENDO_3DS) +#if defined(OF_HPUX) || defined(OF_WII) || defined(OF_NINTENDO_3DS) if (of_socket_address_get_port(address) != 0) { #endif if (bind(_socket, &address->sockaddr.sockaddr, address->length) != 0) { int errNo = of_socket_errno(); @@ -79,11 +79,11 @@ @throw [OFBindFailedException exceptionWithHost: host port: port socket: self errNo: errNo]; } -#if defined(OF_WII) || defined(OF_NINTENDO_3DS) +#if defined(OF_HPUX) || defined(OF_WII) || defined(OF_NINTENDO_3DS) } else { for (;;) { uint16_t rnd = 0; int ret; @@ -119,11 +119,11 @@ objc_autoreleasePoolPop(pool); if ((port = of_socket_address_get_port(address)) > 0) return port; -#if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) +#if !defined(OF_HPUX) && !defined(OF_WII) && !defined(OF_NINTENDO_3DS) memset(address, 0, sizeof(*address)); address->length = (socklen_t)sizeof(address->sockaddr); if (of_getsockname(_socket, &address->sockaddr.sockaddr, &address->length) != 0) { Index: src/of_asprintf.m ================================================================== --- src/of_asprintf.m +++ src/of_asprintf.m @@ -95,43 +95,39 @@ #ifndef HAVE_ASPRINTF static int vasprintf(char **string, const char *format, va_list arguments) { - int expectedLength, length; - va_list argumentsCopy; - - va_copy(argumentsCopy, arguments); - - expectedLength = vsnprintf(NULL, 0, format, argumentsCopy); - if (expectedLength == -1) - /* - * We have no way to know how large it is. Let's try 64 KB and - * hope. - */ - expectedLength = 65535; - - if ((*string = malloc((size_t)expectedLength + 1)) == NULL) - return -1; - - length = vsnprintf(*string, (size_t)expectedLength + 1, - format, arguments); - - if (length == -1 || length > expectedLength) { + size_t length, bufferLength = 128; + + *string = NULL; + + for (;;) { free(*string); - *string = NULL; - return -1; + + if ((*string = malloc(bufferLength)) == NULL) + return -1; + + length = vsnprintf(*string, bufferLength - 1, format, + arguments); + + if (length > 0 && (size_t)length < bufferLength - 1) + break; + + if (bufferLength > INT_MAX / 2) { + free(*string); + return -1; + } + + bufferLength <<= 1; } - /* - * In case we could not determine the size, resize to the actual size - * needed, but ignore any failure to do so. - */ - if (length < expectedLength) { - char *resized; - - if ((resized = realloc(*string, length + 1)) != NULL) + if (length != bufferLength - 1) { + char *resized = realloc(*string, length + 1); + + /* Ignore if making it smaller failed. */ + if (resized != NULL) *string = resized; } return length; } @@ -289,11 +285,11 @@ break; case 'j': #if defined(OF_WINDOWS) if (!appendSubformat(ctx, "I64", 3)) return false; -#elif defined(_NEWLIB_VERSION) +#elif defined(_NEWLIB_VERSION) || defined(OF_HPUX) if (!appendSubformat(ctx, "ll", 2)) return false; #else if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; @@ -305,11 +301,11 @@ case 'z': #if defined(OF_WINDOWS) if (sizeof(size_t) == 8) if (!appendSubformat(ctx, "I64", 3)) return false; -#elif defined(_NEWLIB_VERSION) +#elif defined(_NEWLIB_VERSION) || defined(OF_HPUX) if (!appendSubformat(ctx, "l", 1)) return false; #else if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; @@ -321,11 +317,11 @@ case 't': #if defined(OF_WINDOWS) if (sizeof(ptrdiff_t) == 8) if (!appendSubformat(ctx, "I64", 3)) return false; -#elif defined(_NEWLIB_VERSION) +#elif defined(_NEWLIB_VERSION) || defined(OF_HPUX) if (!appendSubformat(ctx, "l", 1)) return false; #else if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; Index: src/platform.h ================================================================== --- src/platform.h +++ src/platform.h @@ -137,10 +137,12 @@ # define OF_AMIGAOS #elif defined(__sun__) # define OF_SOLARIS #elif defined(__QNX__) # define OF_QNX +#elif defined(__hpux__) +# define OF_HPUX #elif defined(_PSP) # define OF_PSP #elif defined(__DJGPP__) # define OF_DJGPP # define OF_MSDOS Index: src/platform/posix/thread.m ================================================================== --- src/platform/posix/thread.m +++ src/platform/posix/thread.m @@ -40,34 +40,34 @@ * This is done here to make sure this is done as early as possible in the main * thread. */ OF_CONSTRUCTOR() { - pthread_attr_t pattr; + pthread_attr_t attr; - if (pthread_attr_init(&pattr) == 0) { + if (pthread_attr_init(&attr) == 0) { #ifdef HAVE_PTHREAD_ATTR_GETSCHEDPOLICY int policy; #endif struct sched_param param; #ifdef HAVE_PTHREAD_ATTR_GETSCHEDPOLICY - if (pthread_attr_getschedpolicy(&pattr, &policy) == 0) { + if (pthread_attr_getschedpolicy(&attr, &policy) == 0) { minPrio = sched_get_priority_min(policy); maxPrio = sched_get_priority_max(policy); if (minPrio == -1 || maxPrio == -1) minPrio = maxPrio = 0; } #endif - if (pthread_attr_getschedparam(&pattr, ¶m) != 0) + if (pthread_attr_getschedparam(&attr, ¶m) != 0) normalPrio = param.sched_priority; else minPrio = maxPrio = 0; - pthread_attr_destroy(&pattr); + pthread_attr_destroy(&attr); } } static void * functionWrapper(void *data) @@ -87,44 +87,55 @@ int of_thread_attr_init(of_thread_attr_t *attr) { int error; - pthread_attr_t pattr; - - if ((error = pthread_attr_init(&pattr)) != 0) - return error; + pthread_attr_t POSIXAttr; attr->priority = 0; - error = pthread_attr_getstacksize(&pattr, &attr->stackSize); + attr->stackSize = 0; + + if ((error = pthread_attr_init(&POSIXAttr)) != 0) { + if (error == ENOSYS) + return 0; + + return error; + } + + error = pthread_attr_getstacksize(&POSIXAttr, &attr->stackSize); - pthread_attr_destroy(&pattr); + pthread_attr_destroy(&POSIXAttr); return error; } int of_thread_new(of_thread_t *thread, const char *name, void (*function)(id), id object, const of_thread_attr_t *attr) { int error = 0; - pthread_attr_t pattr; + pthread_attr_t POSIXAttr; + bool POSIXAttrAvailable = true; - if ((error = pthread_attr_init(&pattr)) != 0) - return error; + if ((error = pthread_attr_init(&POSIXAttr)) != 0) { + if (error == ENOSYS) + POSIXAttrAvailable = false; + else + return error; + } @try { struct thread_ctx *ctx; - if (attr != NULL) { + if (attr != NULL && POSIXAttrAvailable) { struct sched_param param; if (attr->priority < -1 || attr->priority > 1) return EINVAL; #ifdef HAVE_PTHREAD_ATTR_SETINHERITSCHED - if ((error = pthread_attr_setinheritsched(&pattr, + if ((error = pthread_attr_setinheritsched(&POSIXAttr, PTHREAD_EXPLICIT_SCHED)) != 0) return error; #endif if (attr->priority < 0) { @@ -133,17 +144,17 @@ (normalPrio - minPrio); } else param.sched_priority = normalPrio + attr->priority * (maxPrio - normalPrio); - if ((error = pthread_attr_setschedparam(&pattr, + if ((error = pthread_attr_setschedparam(&POSIXAttr, ¶m)) != 0) return error; if (attr->stackSize > 0) { - if ((error = pthread_attr_setstacksize(&pattr, - attr->stackSize)) != 0) + if ((error = pthread_attr_setstacksize( + &POSIXAttr, attr->stackSize)) != 0) return error; } } if ((ctx = malloc(sizeof(*ctx))) == NULL) @@ -151,13 +162,15 @@ ctx->function = function; ctx->object = object; ctx->name = name; - error = pthread_create(thread, &pattr, functionWrapper, ctx); + error = pthread_create(thread, &POSIXAttr, functionWrapper, + ctx); } @finally { - pthread_attr_destroy(&pattr); + if (POSIXAttrAvailable) + pthread_attr_destroy(&POSIXAttr); } return error; } Index: src/runtime/exception.m ================================================================== --- src/runtime/exception.m +++ src/runtime/exception.m @@ -334,12 +334,18 @@ static uint64_t readValue(uint8_t enc, const uint8_t **ptr) { uint64_t value; - if (enc == DW_EH_PE_aligned) - OBJC_ERROR("DW_EH_PE_aligned is not implemented!"); + if (enc == DW_EH_PE_aligned) { + const uintptr_t *aligned = (const uintptr_t *) + OF_ROUND_UP_POW2(sizeof(void *), (uintptr_t)*ptr); + + *ptr = (const uint8_t *)(aligned + 1); + + return *aligned; + } #define READ(type) \ { \ type tmp; \ memcpy(&tmp, *ptr, sizeof(type)); \ @@ -378,12 +384,12 @@ #ifndef HAVE_ARM_EHABI_EXCEPTIONS static uint64_t resolveValue(uint64_t value, uint8_t enc, const uint8_t *start, uint64_t base) { - if (value == 0) - return 0; + if (value == 0 || enc == DW_EH_PE_aligned) + return value; value += ((enc & 0x70) == DW_EH_PE_pcrel ? (uintptr_t)start : base); if (enc & DW_EH_PE_indirect) value = *(uintptr_t *)(uintptr_t)value; Index: tests/OFDataTests.m ================================================================== --- tests/OFDataTests.m +++ tests/OFDataTests.m @@ -89,11 +89,11 @@ memcmp(mutable.items, "abcde", 5) == 0) immutable = [OFData dataWithItems: "aaabaccdacaabb" count: 7 itemSize: 2]; - TEST(@"-[rangeOfString:options:range:]", + TEST(@"-[rangeOfData:options:range:]", R(range = [immutable rangeOfData: [OFData dataWithItems: "aa" count: 1 itemSize: 2] options: 0 range: of_range(0, 7)]) && @@ -128,11 +128,11 @@ options: OF_DATA_SEARCH_BACKWARDS range: of_range(0, 5)]) && range.location == 0 && range.length == 1) EXPECT_EXCEPTION( - @"-[rangeOfString:options:range:] failing on different itemSize", + @"-[rangeOfData:options:range:] failing on different itemSize", OFInvalidArgumentException, [immutable rangeOfData: [OFData dataWithItems: "aaa" count: 1 itemSize: 3] options: 0 Index: tests/OFStringTests.m ================================================================== --- tests/OFStringTests.m +++ tests/OFStringTests.m @@ -1106,18 +1106,19 @@ */ TEST(@"-[floatValue]", C(@"\t-0.25 ").floatValue == -0.25 && C(@"\r\n\tINF\t\n").floatValue == INFINITY && C(@"\r -INFINITY\n").floatValue == -INFINITY && - isnan(C(@" NAN\t\t").floatValue)) + isnan(C(@" NAN\t\t").floatValue) && + isnan(C(@" -NaN\t\t").floatValue)) -#if !defined(OF_ANDROID) && !defined(OF_SOLARIS) && !defined(OF_DJGPP) && \ - !defined(OF_AMIGAOS_M68K) +#if !defined(OF_ANDROID) && !defined(OF_SOLARIS) && !defined(OF_HPUX) && \ + !defined(OF_DJGPP) && !defined(OF_AMIGAOS_M68K) # define INPUT @"\t-0x1.FFFFFFFFFFFFFP-1020 " # define EXPECTED -0x1.FFFFFFFFFFFFFP-1020 #else -/* Android, Solaris, DJGPP and AmigaOS3 do not accept 0x for strtod() */ +/* Android, Solaris, HP-UX, DJGPP and AmigaOS 3 do not accept 0x for strtod() */ # if (!defined(OF_SOLARIS) || !defined(OF_X86)) && !defined(OF_AMIGAOS_M68K) # define INPUT @"\t-0.123456789 " # define EXPECTED -0.123456789 # else /* Index: utils/ofhttp/ProgressBar.m ================================================================== --- utils/ofhttp/ProgressBar.m +++ utils/ofhttp/ProgressBar.m @@ -27,10 +27,14 @@ #define GIBIBYTE (1024 * 1024 * 1024) #define MEBIBYTE (1024 * 1024) #define KIBIBYTE (1024) #define UPDATE_INTERVAL 0.1 + +#ifndef HAVE_TRUNCF +# define truncf(x) trunc(x) +#endif @implementation ProgressBar - (instancetype)initWithLength: (unsigned long long)length resumedFrom: (unsigned long long)resumedFrom useUnicode: (bool)useUnicode