Index: .fossil-settings/clean-glob
==================================================================
--- .fossil-settings/clean-glob
+++ .fossil-settings/clean-glob
@@ -37,10 +37,11 @@
tests/EBOOT.PBP
tests/Info.plist
tests/PARAM.SFO
tests/objc_sync/objc_sync
tests/plugin/Info.plist
+tests/subprocess/subprocess
tests/terminal/terminal_tests
tests/testfile_bin.m
tests/testfile_ini.m
tests/tests
tests/tests.3dsx
Index: .fossil-settings/ignore-glob
==================================================================
--- .fossil-settings/ignore-glob
+++ .fossil-settings/ignore-glob
@@ -42,10 +42,11 @@
tests/iOS.xcodeproj/*.pbxuser
tests/iOS.xcodeproj/project.xcworkspace
tests/iOS.xcodeproj/xcuserdata
tests/objc_sync/objc_sync
tests/plugin/Info.plist
+tests/subprocess/subprocess
tests/terminal/terminal_tests
tests/testfile_bin.m
tests/testfile_ini.m
tests/tests
tests/tests.3dsx
Index: .github/workflows/dragonflybsd.yml
==================================================================
--- .github/workflows/dragonflybsd.yml
+++ .github/workflows/dragonflybsd.yml
@@ -1,19 +1,19 @@
name: dragonflybsd
on: [push, pull_request]
jobs:
tests:
- runs-on: macos-12
+ runs-on: ubuntu-latest
strategy:
matrix:
configure_flags:
-
- --disable-shared
- --with-tls=gnutls
steps:
- - uses: actions/checkout@v3
- - uses: vmactions/dragonflybsd-vm@v0
+ - uses: actions/checkout@v4
+ - uses: vmactions/dragonflybsd-vm@v1
with:
usesh: true
copyback: false
prepare: |
pkg install -y autoconf automake gnutls llvm pkgconf
Index: .github/workflows/freebsd.yml
==================================================================
--- .github/workflows/freebsd.yml
+++ .github/workflows/freebsd.yml
@@ -1,19 +1,19 @@
name: freebsd
on: [push, pull_request]
jobs:
tests:
- runs-on: macos-12
+ runs-on: ubuntu-latest
strategy:
matrix:
configure_flags:
-
- --disable-shared
- --with-tls=gnutls
steps:
- - uses: actions/checkout@v3
- - uses: vmactions/freebsd-vm@v0
+ - uses: actions/checkout@v4
+ - uses: vmactions/freebsd-vm@v1
with:
usesh: true
copyback: false
prepare: |
pkg install -y autoconf automake gnutls pkgconf
Index: .github/workflows/netbsd-gcc.yml
==================================================================
--- .github/workflows/netbsd-gcc.yml
+++ .github/workflows/netbsd-gcc.yml
@@ -1,24 +1,24 @@
name: netbsd-gcc
on: [push, pull_request]
jobs:
tests:
- runs-on: macos-12
+ runs-on: ubuntu-latest
strategy:
matrix:
configure_flags:
-
- --disable-shared
- --with-tls=gnutls
steps:
- - uses: actions/checkout@v3
- - uses: vmactions/netbsd-vm@v0
+ - uses: actions/checkout@v4
+ - uses: vmactions/netbsd-vm@v1
with:
usesh: true
copyback: false
prepare: |
- pkg_add autoconf automake gnutls pkgconf
+ /usr/sbin/pkg_add autoconf automake gnutls pkgconf
run: |
./autogen.sh
./configure OBJC=gcc ${{ matrix.configure_flags }}
make -j4
make check
Index: .github/workflows/netbsd.yml
==================================================================
--- .github/workflows/netbsd.yml
+++ .github/workflows/netbsd.yml
@@ -1,24 +1,24 @@
name: netbsd
on: [push, pull_request]
jobs:
tests:
- runs-on: macos-12
+ runs-on: ubuntu-latest
strategy:
matrix:
configure_flags:
-
- --disable-shared
- --with-tls=gnutls
steps:
- - uses: actions/checkout@v3
- - uses: vmactions/netbsd-vm@v0
+ - uses: actions/checkout@v4
+ - uses: vmactions/netbsd-vm@v1
with:
usesh: true
copyback: false
prepare: |
- pkg_add autoconf automake clang gnutls pkgconf
+ /usr/sbin/pkg_add autoconf automake clang gnutls pkgconf
run: |
./autogen.sh
./configure OBJC=clang ${{ matrix.configure_flags }}
make -j4
make check
Index: .github/workflows/openbsd.yml
==================================================================
--- .github/workflows/openbsd.yml
+++ .github/workflows/openbsd.yml
@@ -1,19 +1,19 @@
name: openbsd
on: [push, pull_request]
jobs:
tests:
- runs-on: macos-12
+ runs-on: ubuntu-latest
strategy:
matrix:
configure_flags:
-
- --disable-shared
- --with-tls=gnutls
steps:
- - uses: actions/checkout@v3
- - uses: vmactions/openbsd-vm@v0
+ - uses: actions/checkout@v4
+ - uses: vmactions/openbsd-vm@v1
with:
usesh: true
copyback: false
prepare: |
pkg_add autoconf-2.71 automake-1.16.5 gnutls pkgconf
Index: .gitignore
==================================================================
--- .gitignore
+++ .gitignore
@@ -42,10 +42,11 @@
tests/iOS.xcodeproj/*.pbxuser
tests/iOS.xcodeproj/project.xcworkspace
tests/iOS.xcodeproj/xcuserdata
tests/objc_sync/objc_sync
tests/plugin/Info.plist
+tests/subprocess/subprocess
tests/terminal/terminal_tests
tests/testfile_bin.m
tests/testfile_ini.m
tests/tests
tests/tests.3dsx
Index: ChangeLog
==================================================================
--- ChangeLog
+++ ChangeLog
@@ -2,10 +2,35 @@
* Changes of existing features or bugfixes
+ New features
This file only contains the most significant changes.
+ObjFW 1.0.7 -> ObjFW 1.0.8, 2024-01-21
+ * Fixes compilation on NetBSD, OpenBSD, OpenIndiana etc. which was broken by
+ 1.0.7.
+
+ObjFW 1.0.6 -> ObjFW 1.0.7, 2024-01-21
+ * Fixes inheriting the environment in OFSubprocess.
+ * Fixes dealloc in OFSubprocess when -[closeForWriting] was called.
+ + Adds tests for OFSubprocess.
+ * Changes the key for +[OFSystemInfo networkInterfaces] to the adapter name
+ on Windows XP and newer to avoid a possible collission on the adapter index.
+ * Fixes compilation with old MinGW versions.
+ * Fixes the documentation for OFSRVDNSResourceRecord.
+
+ObjFW 1.0.5 -> ObjFW 1.0.6, 2024-01-15
+ * Fixes compatibility with autoconf 2.72.
+ * Fixes OFDNSResolver's handling of types, classes and lengths > 255.
+
+ObjFW 1.0.4 -> ObjFW 1.0.5, 2023-11-05
+ * Fixes the calculation of the extra alignment in OFAllocObject()
+ * Fixes +[OFSystemInfo networkInterfaces] on OpenBSD and Windows 98
+ * Fixes OFSocketAddressString() for AppleTalk addresses
+ * Uses GetModuleHandle() instead of LoadLibrary() where possible on Windows
+ * Disables tests for global blocks on Win64 due to broken compilers
+ * Adds PGP keys to verify tarballs and commits in the code repository
+
ObjFW 1.0.3 -> ObjFW 1.0.4, 2023-10-08
* Fixes OFFile closing fd 0 when initialization fails
* Fixes -[stringByAppendingPathComponent:] on empty strings
* Fixes +[OFSystemInfo operatingSystemName] and
+[OFSystemInfo operatingSystemVersion] returning nil on some systems
Index: README.md
==================================================================
--- README.md
+++ README.md
@@ -53,11 +53,11 @@
* GNUstep already provides a reimplementation of Foundation, which is only
compatible to a certain degree. This means that a developer still needs to
care about differences between frameworks if they want to be portable. The
idea behind ObjFW is that a developer does not need to concern themselves
- with portablility and making sure their code works with multiple
+ with portability and making sure their code works with multiple
frameworks: Instead, if it works it ObjFW on one platform, they can
reasonably expect it to also work with ObjFW on another platform. ObjFW
behaving differently on different operating systems (unless inevitable
because it is a platform-specific part, like the Windows Registry) is
considered a bug and will be fixed.
@@ -79,23 +79,26 @@
Installation
ObjFW packages are available for various operating systems and can be
installed as following:
- Operating System | Command
- -----------------|---------------------------------------------
- Alpine Linux | `doas apk add objfw`
- CRUX | `sudo prt-get depinst objfw`
- Fedora | `sudo dnf install objfw`
- FreeBSD | `sudo pkg install objfw`
- Haiku | `pkgman install objfw`
- Haiku (gcc2h) | `pkgman install objfw_x86`
- macOS (Homebrew) | `brew install objfw`
- macOS (pkgsrc) | `cd $PKGSRCDIR/devel/objfw && make install`
- NetBSD | `cd /usr/pkgsrc/devel/objfw && make install`
- OpenBSD | `doas pkg_add objfw`
- OpenIndiana | `sudo pkg install developer/objfw`
+ Operating System | Command
+ ---------------------------|---------------------------------------------
+ Alpine Linux | `doas apk add objfw`
+ CRUX | `sudo prt-get depinst objfw`
+ Fedora | `sudo dnf install objfw`
+ FreeBSD | `sudo pkg install objfw`
+ Haiku | `pkgman install objfw`
+ Haiku (gcc2h) | `pkgman install objfw_x86`
+ macOS (Homebrew) | `brew install objfw`
+ macOS (pkgsrc) | `cd $PKGSRCDIR/devel/objfw && make install`
+ NetBSD | `cd /usr/pkgsrc/devel/objfw && make install`
+ OpenBSD | `doas pkg_add objfw`
+ OpenIndiana | `sudo pkg install developer/objfw`
+ Windows (MSYS2/MINGW32) | `pacman -S mingw-w64-i686-objfw`
+ Windows (MSYS2/CLANG64) | `pacman -S mingw-w64-clang-x86_64-objfw`
+ Windows (MSYS2/CLANGARM64) | `pacman -S mingw-w64-clang-aarch64-objfw`
If your operating system is not listed, you can
build ObjFW from source.
@@ -385,20 +388,18 @@
If you have any questions about ObjFW or would like to talk to other ObjFW
users, the following venues are available:
* The [forum](https://objfw.nil.im/forum)
* A [Matrix room](https://matrix.to/#/%23objfw:nil.im)
+ * A [Discord room](https://objfw.nil.im/discord), bridged to the Matrix
+ room above
+ * A [Telegram room](https://t.me/objfw), bridged to the Matrix room above
+ * A [Slack room](https://objfw.nil.im/slack), bridged to the Matrix room
+ above
* An IRC channel named `#objfw` on `irc.oftc.net`
([Web chat](https://webchat.oftc.net/?channels=%23objfw)), bridged to the
Matrix room above
- * A [Slack channel](https://objfw.nil.im/slack), bridged to the Matrix room
- above
- * A [Discord channel](https://objfw.nil.im/discord), bridged to the Matrix
- room above
- * A [Telegram room](https://t.me/objfw), bridged to the Matrix room above
- * A [Gitter room](https://gitter.im/ObjFW/ObjFW), bridged to the Matrix room
- above
Please don't hesitate to join any or all of those!
Donating
Index: configure.ac
==================================================================
--- configure.ac
+++ configure.ac
@@ -1,14 +1,13 @@
-AC_INIT(ObjFW, 1.1dev, js@nil.im, objfw, https://objfw.nil.im/)
+AC_INIT(ObjFW, 1.0.8, js@nil.im, objfw, https://objfw.nil.im/)
AC_CONFIG_SRCDIR(src)
AC_CONFIG_AUX_DIR(build-aux)
AC_CONFIG_MACRO_DIR(build-aux/m4)
AC_DEFINE(OBJFW_VERSION_MAJOR, 1, [The major version of ObjFW])
-AC_DEFINE(OBJFW_VERSION_MINOR, 1, [The minor version of ObjFW])
-dnl This may only be set to 1.1 once 1.1 is released
-AC_SUBST(BUNDLE_VERSION, 1.0.0)
+AC_DEFINE(OBJFW_VERSION_MINOR, 0, [The minor version of ObjFW])
+AC_SUBST(BUNDLE_VERSION, 1.0.8)
AC_SUBST(BUNDLE_SHORT_VERSION, 1.0)
for i in configure.ac build-aux/m4/*; do
AS_IF([test $i -nt configure], [
AC_MSG_ERROR([$i is newer than configure! Run ./autogen.sh!])
@@ -150,10 +149,11 @@
potential_compilers="clang egcc gcc"
;;
esac
AC_PROG_OBJC($potential_compilers)
AC_PROG_OBJCPP
+AC_PROG_EGREP
AC_PROG_LN_S
BUILDSYS_CHECK_IOS
AC_ARG_WITH(wii,
@@ -476,29 +476,25 @@
esac
objc_runtime="ObjFW runtime"
AC_CHECK_HEADER(objc/objc.h)
AC_MSG_CHECKING(which Objective C runtime to use)
-AC_ARG_ENABLE(runtime,
- AS_HELP_STRING([--enable-runtime], [use the included runtime]))
AC_ARG_ENABLE(seluid24,
AS_HELP_STRING([--enable-seluid24],
[use 24 bit instead of 16 bit for selector UIDs]))
-AS_IF([test x"$enable_runtime" != x"yes"], [
- AS_IF([test x"$ac_cv_header_objc_objc_h" = x"yes"], [
- AC_EGREP_CPP(egrep_cpp_yes, [
- #import
-
- #ifdef OBJC_BOOL_DEFINED
- egrep_cpp_yes
- #endif
- ], [
- objc_runtime="Apple runtime"
- ], [
- dnl We don't want the GNU runtime
- :
- ])
+AS_IF([test x"$ac_cv_header_objc_objc_h" = x"yes"], [
+ AC_EGREP_CPP(egrep_cpp_yes, [
+ #import
+
+ #ifdef OBJC_BOOL_DEFINED
+ egrep_cpp_yes
+ #endif
+ ], [
+ objc_runtime="Apple runtime"
+ ], [
+ dnl We don't want the GNU runtime
+ :
])
])
AC_MSG_RESULT($objc_runtime)
case "$objc_runtime" in
@@ -1380,10 +1376,21 @@
esac
AC_CHECK_HEADER(sys/socket.h, [
AC_DEFINE(OF_HAVE_SYS_SOCKET_H, 1,
[Whether we have sys/socket.h])
+ ])
+ AC_CHECK_MEMBERS([struct sockaddr.sa_len], [], [], [
+ #ifdef OF_HAVE_SYS_TYPES_H
+ # include
+ #endif
+ #ifdef OF_HAVE_SYS_SOCKET_H
+ # include
+ #endif
+ #ifdef _WIN32
+ # include
+ #endif
])
AC_CHECK_TYPE([struct sockaddr_storage], [
AC_DEFINE(OF_HAVE_SOCKADDR_STORAGE, 1,
[Whether we have struct sockaddr_storage])
], [], [
@@ -1459,12 +1466,10 @@
#ifdef AF_INET6
egrep_cpp_yes
#endif
], [
AC_DEFINE(OF_HAVE_IPV6, 1, [Whether we have IPv6])
-
- AC_CHECK_FUNCS(inet6_getscopeid)
])
], [
dnl Work around a bug in autoconf 2.61 that creates a broken
dnl configure if this branch is empty.
:
@@ -1949,11 +1954,12 @@
break
])
])
])
AS_IF([test x"$have_subprocesses" = x"yes"], [
- AC_SUBST(OF_SUBPROCESS_M, "OFSubprocess.m")
+ AC_SUBST(USE_SRCS_SUBPROCESS, '${SRCS_SUBPROCESS}')
+ AC_SUBST(SUBPROCESS, "subprocess")
AC_DEFINE(OF_HAVE_SUBPROCESSES, 1, [Whether we have subprocesses])
])
AC_CHECK_HEADERS_ONCE([complex.h sys/ioctl.h sys/ttycom.h])
AC_CHECK_FUNCS(ioctl isatty)
@@ -2005,11 +2011,11 @@
AS_IF([test x"$GOBJC" = x"yes"], [
OBJCFLAGS="$OBJCFLAGS -Wwrite-strings -Wpointer-arith"
AC_ARG_ENABLE(werror,
AS_HELP_STRING([--disable-werror], [do not build with -Werror]))
- AS_IF([test x"$enable_werror" != x"no"], [
+ AS_IF([test x"$enable_werror" = x"yes"], [
OBJCFLAGS="$OBJCFLAGS -Werror"
])
old_OBJCFLAGS="$OBJCFLAGS"
OBJCFLAGS="$OBJCFLAGS -Werror"
Index: extra.mk.in
==================================================================
--- extra.mk.in
+++ extra.mk.in
@@ -1,11 +1,11 @@
OBJFW_SHARED_LIB = @OBJFW_SHARED_LIB@
OBJFW_STATIC_LIB = @OBJFW_STATIC_LIB@
OBJFW_FRAMEWORK = @OBJFW_FRAMEWORK@
OBJFW_LIB_MAJOR = 1
OBJFW_LIB_MINOR = 0
-OBJFW_LIB_PATCH = 2
+OBJFW_LIB_PATCH = 5
OBJFW_LIB_MAJOR_MINOR = ${OBJFW_LIB_MAJOR}.${OBJFW_LIB_MINOR}
OBJFWRT_SHARED_LIB = @OBJFWRT_SHARED_LIB@
OBJFWRT_STATIC_LIB = @OBJFWRT_STATIC_LIB@
OBJFWRT_FRAMEWORK = @OBJFWRT_FRAMEWORK@
@@ -60,11 +60,10 @@
OF_KQUEUE_KERNEL_EVENT_OBSERVER_M = @OF_KQUEUE_KERNEL_EVENT_OBSERVER_M@
OF_OPENSSL_TLS_STREAM_M = @OF_OPENSSL_TLS_STREAM_M@
OF_POLL_KERNEL_EVENT_OBSERVER_M = @OF_POLL_KERNEL_EVENT_OBSERVER_M@
OF_SECURE_TRANSPORT_TLS_STREAM_M = @OF_SECURE_TRANSPORT_TLS_STREAM_M@
OF_SELECT_KERNEL_EVENT_OBSERVER_M = @OF_SELECT_KERNEL_EVENT_OBSERVER_M@
-OF_SUBPROCESS_M = @OF_SUBPROCESS_M@
REEXPORT_RUNTIME = @REEXPORT_RUNTIME@
REEXPORT_RUNTIME_FRAMEWORK = @REEXPORT_RUNTIME_FRAMEWORK@
RUNTIME = @RUNTIME@
RUNTIME_ARC_TESTS_M = @RUNTIME_ARC_TESTS_M@
RUNTIME_AUTORELEASE_M = @RUNTIME_AUTORELEASE_M@
@@ -72,10 +71,11 @@
RUNTIME_INSTANCE_M = @RUNTIME_INSTANCE_M@
RUNTIME_LIBS = @RUNTIME_LIBS@
SFDC_INLINE_H = @SFDC_INLINE_H@
SFDC_TARGET = @SFDC_TARGET@
SFD_FILE = @SFD_FILE@
+SUBPROCESS = @SUBPROCESS@
TESTPLUGIN = @TESTPLUGIN@
TESTPLUGIN_LIBS = @TESTPLUGIN_LIBS@
TESTS_LIBS = @TESTS_LIBS@
TESTS_STATIC_LIB = @TESTS_STATIC_LIB@
TLS = @TLS@
@@ -86,10 +86,11 @@
USE_SRCS_APPLETALK = @USE_SRCS_APPLETALK@
USE_SRCS_FILES = @USE_SRCS_FILES@
USE_SRCS_IPX = @USE_SRCS_IPX@
USE_SRCS_PLUGINS = @USE_SRCS_PLUGINS@
USE_SRCS_SOCKETS = @USE_SRCS_SOCKETS@
+USE_SRCS_SUBPROCESS = @USE_SRCS_SUBPROCESS@
USE_SRCS_TAGGED_POINTERS = @USE_SRCS_TAGGED_POINTERS@
USE_SRCS_THREADS = @USE_SRCS_THREADS@
USE_SRCS_UNIX_SOCKETS = @USE_SRCS_UNIX_SOCKETS@
USE_SRCS_WINDOWS = @USE_SRCS_WINDOWS@
WRAPPER = @WRAPPER@
ADDED misc/keys.asc
Index: misc/keys.asc
==================================================================
--- /dev/null
+++ misc/keys.asc
@@ -0,0 +1,196 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mDMEWtyz7hYJKwYBBAHaRw8BAQdAsw2r74WiB54Nr73sY2sxBLu0RUges2iPeBor
+1Wc6Cre0O0pvbmF0aGFuIFNjaGxlaWZlciAoQ29tbWl0IFNpZ25pbmcgS2V5IDIw
+MTgpIDxqc0BoZWFwLnpvbmU+iJkEExYKAEECGwMHCwoNDAgLBwYVCgkICwMFFgMC
+AQACHgECF4AWIQTGxY7C74kJHg4TzVjYOna/43Y0XgUCXESzpAUJAWlRNgAKCRDY
+Ona/43Y0XhA1AP4nIiBUL2nMtkDJSbSb0/kbyIoTNhRXtlI4crYIqfs07gD+NMdH
+HzMnGtHkpaX7GAqVTeTiThZUnTGNMwnV9aerQQe0OkpvbmF0aGFuIFNjaGxlaWZl
+ciAoT2JqRlcgU2lnbmluZyBLZXkgMjAxOCkgPGpzQGhlYXAuem9uZT6ImQQTFgoA
+QQIbAwcLCg0MCAsHBhUKCQgLAwUWAwIBAAIeAQIXgBYhBMbFjsLviQkeDhPNWNg6
+dr/jdjReBQJcRLOoBQkBaVE2AAoJENg6dr/jdjReDVoBANvkIYUTLemog3UhjZYh
+Zdvq9Axd63L2lnpzm+For3tNAP9GmJwbq/oi8E0mAwesbvQYY/R4NOOKIdV7rkVj
+JzoeCJgzBFxA+ccWCSsGAQQB2kcPAQEHQIe0NK4nnagyINx6Z2DJt4lUzv7a7e6x
+PLifEvo1iQVptDpKb25hdGhhbiBTY2hsZWlmZXIgKE9iakZXIFNpZ25pbmcgS2V5
+IDIwMTkpIDxqc0BoZWFwLnpvbmU+iJkEExYKAEEWIQQtKx7sQXauZ6pvl2B50hGJ
+otRwjQUCXED55wIbAwUJAeEzgAcLCg0MCAsHBhUKCQgLAwUWAwIBAAIeAQIXgAAK
+CRB50hGJotRwjeuIAP9wQ8r+13S0ZHPmOkeVQNqpVdvszisfszQKNRrkKrS7fgEA
+AF4eI4IXb13x5hHvzYn2DMMe2ugx6LoCdzYcVlvFFQ60O0pvbmF0aGFuIFNjaGxl
+aWZlciAoQ29tbWl0IFNpZ25pbmcgS2V5IDIwMTkpIDxqc0BoZWFwLnpvbmU+iJkE
+ExYKAEEWIQQtKx7sQXauZ6pvl2B50hGJotRwjQUCXED5xwIbAwUJAeEzgAcLCg0M
+CAsHBhUKCQgLAwUWAwIBAAIeAQIXgAAKCRB50hGJotRwjXTdAP4oYHIg5+LBhfO+
+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
+WBymwZqetu7HBg==
+=mVJw
+-----END PGP PUBLIC KEY BLOCK-----
Index: src/Makefile
==================================================================
--- src/Makefile
+++ src/Makefile
@@ -87,11 +87,10 @@
OFString+JSONParsing.m \
OFString+PercentEncoding.m \
OFString+PropertyListParsing.m \
OFString+XMLEscaping.m \
OFString+XMLUnescaping.m \
- ${OF_SUBPROCESS_M} \
OFSystemInfo.m \
OFTarArchive.m \
OFTarArchiveEntry.m \
OFThread.m \
OFTimer.m \
@@ -110,10 +109,11 @@
OFZIPArchive.m \
OFZIPArchiveEntry.m \
${USE_SRCS_FILES} \
${USE_SRCS_PLUGINS} \
${USE_SRCS_SOCKETS} \
+ ${USE_SRCS_SUBPROCESS} \
${USE_SRCS_THREADS} \
${USE_SRCS_WINDOWS}
SRCS_FILES = OFFile.m \
OFString+PathAdditions.m
SRCS_PLUGINS = OFPlugin.m
@@ -142,10 +142,11 @@
SRCS_IPX = OFIPXSocket.m \
OFSPXSocket.m \
OFSPXStreamSocket.m
SRCS_UNIX_SOCKETS = OFUNIXDatagramSocket.m \
OFUNIXStreamSocket.m
+SRCS_SUBPROCESS = OFSubprocess.m
SRCS_THREADS = OFCondition.m \
OFMutex.m \
OFPlainCondition.m \
OFPlainMutex.m \
OFPlainThread.m \
Index: src/OFDNSResolver.m
==================================================================
--- src/OFDNSResolver.m
+++ src/OFDNSResolver.m
@@ -431,15 +431,15 @@
OFDNSResourceRecord *record;
if (*i + 10 > length)
@throw [OFTruncatedDataException exception];
- recordType = (buffer[*i] << 16) | buffer[*i + 1];
- DNSClass = (buffer[*i + 2] << 16) | buffer[*i + 3];
+ recordType = (buffer[*i] << 8) | buffer[*i + 1];
+ DNSClass = (buffer[*i + 2] << 8) | buffer[*i + 3];
TTL = (buffer[*i + 4] << 24) | (buffer[*i + 5] << 16) |
(buffer[*i + 6] << 8) | buffer[*i + 7];
- dataLength = (buffer[*i + 8] << 16) | buffer[*i + 9];
+ dataLength = (buffer[*i + 8] << 8) | buffer[*i + 9];
*i += 10;
if (*i + dataLength > length)
@throw [OFTruncatedDataException exception];
Index: src/OFDNSResourceRecord.h
==================================================================
--- src/OFDNSResourceRecord.h
+++ src/OFDNSResourceRecord.h
@@ -152,11 +152,11 @@
/**
* @class OFAAAADNSResourceRecord \
* OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h
*
- * @brief A class represenging a DNS resource record.
+ * @brief A class representing a DNS resource record.
*/
OF_SUBCLASSING_RESTRICTED
@interface OFAAAADNSResourceRecord: OFDNSResourceRecord
{
OFSocketAddress _address;
@@ -390,11 +390,11 @@
domainName: (OFString *)domainName
TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER;
@end
/**
- * @class OFRPNSResourceRecord \
+ * @class OFRPDNSResourceRecord \
* OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h
*
* @brief A class representing an RP DNS resource record.
*/
OF_SUBCLASSING_RESTRICTED
@@ -559,11 +559,11 @@
recordType: (OFDNSRecordType)recordType
TTL: (uint32_t)TTL OF_UNAVAILABLE;
/**
* @brief Initializes an already allocated OFSRVDNSResourceRecord with the
- * specified name, class, preference, mail exchange and time to live.
+ * specified name, priority, weight, target, port and time to live.
*
* @param name The name for the resource record
* @param priority The priority for the resource record
* @param weight The weight for the resource record
* @param target The target for the resource record
Index: src/OFData.h
==================================================================
--- src/OFData.h
+++ src/OFData.h
@@ -123,11 +123,11 @@
/**
* @brief Creates a new OFData with the specified `count` items of size 1 by
* taking over ownership of the specified items pointer.
*
* If initialization fails for whatever reason, the passed memory is *not*
- * free'd if `freeWhenDone` is true.
+ * freed if `freeWhenDone` is true.
*
* @param items The items to store in the OFData
* @param count The number of items
* @param freeWhenDone Whether to free the pointer when it is no longer needed
* by the OFData
@@ -140,11 +140,11 @@
/**
* @brief Creates a new OFData with the specified `count` items of the
* specified size by taking ownership of the specified items pointer.
*
* If initialization fails for whatever reason, the passed memory is *not*
- * free'd if `freeWhenDone` is true.
+ * freed if `freeWhenDone` is true.
*
* @param items The items to store in the OFData
* @param count The number of items
* @param itemSize The item size of a single item in bytes
* @param freeWhenDone Whether to free the pointer when it is no longer needed
@@ -242,11 +242,11 @@
* @brief Initializes an already allocated OFData with the specified `count`
* items of size 1 by taking over ownership of the specified items
* pointer.
*
* If initialization fails for whatever reason, the passed memory is *not*
- * free'd if `freeWhenDone` is true.
+ * freed if `freeWhenDone` is true.
*
* @param items The items to store in the OFData
* @param count The number of items
* @param freeWhenDone Whether to free the pointer when it is no longer needed
* by the OFData
@@ -260,11 +260,11 @@
* @brief Initializes an already allocated OFData with the specified `count`
* items of the specified size by taking ownership of the specified
* items pointer.
*
* If initialization fails for whatever reason, the passed memory is *not*
- * free'd if `freeWhenDone` is true.
+ * freed if `freeWhenDone` is true.
*
* @param items The items to store in the OFData
* @param count The number of items
* @param itemSize The item size of a single item in bytes
* @param freeWhenDone Whether to free the pointer when it is no longer needed
Index: src/OFDatagramSocket.h
==================================================================
--- src/OFDatagramSocket.h
+++ src/OFDatagramSocket.h
@@ -185,11 +185,12 @@
*
* If the buffer is too small, the datagram is truncated.
*
* @param buffer The buffer to write the datagram to
* @param length The length of the buffer
- * @param runLoopMode The run loop mode in which to perform the async receive
+ * @param runLoopMode The run loop mode in which to perform the asynchronous
+ * receive
*/
- (void)asyncReceiveIntoBuffer: (void *)buffer
length: (size_t)length
runLoopMode: (OFRunLoopMode)runLoopMode;
@@ -219,11 +220,12 @@
*
* If the buffer is too small, the datagram is truncated.
*
* @param buffer The buffer to write the datagram to
* @param length The length of the buffer
- * @param runLoopMode The run loop mode in which to perform the async receive
+ * @param runLoopMode The run loop mode in which to perform the asynchronous
+ * receive
* @param block The block to call when the datagram has been received. If the
* block returns true, it will be called again with the same
* buffer and maximum length when more datagrams have been
* received. If you want the next method in the queue to handle
* the datagram received next, you need to return false from the
@@ -261,13 +263,14 @@
/**
* @brief Asynchronously sends the specified datagram to the specified address.
*
* @param data The data to send as a datagram
- * @param receiver A pointer to an @ref OFSocketAddress to which the datgram
+ * @param receiver A pointer to an @ref OFSocketAddress to which the datagram
* should be sent. The receiver is copied.
- * @param runLoopMode The run loop mode in which to perform the async send
+ * @param runLoopMode The run loop mode in which to perform the asynchronous
+ * send
*/
- (void)asyncSendData: (OFData *)data
receiver: (const OFSocketAddress *)receiver
runLoopMode: (OFRunLoopMode)runLoopMode;
@@ -290,11 +293,12 @@
* @brief Asynchronously sends the specified datagram to the specified address.
*
* @param data The data to send as a datagram
* @param receiver A pointer to an @ref OFSocketAddress to which the datagram
* should be sent. The receiver is copied.
- * @param runLoopMode The run loop mode in which to perform the async send
+ * @param runLoopMode The run loop mode in which to perform the asynchronous
+ * send
* @param block The block to call when the packet has been sent. It should
* return the data for the next send with the same callback or nil
* if it should not repeat.
*/
- (void)asyncSendData: (OFData *)data
Index: src/OFDate.h
==================================================================
--- src/OFDate.h
+++ src/OFDate.h
@@ -187,20 +187,20 @@
format: (OFString *)format;
/**
* @brief Returns a date in the distant future.
*
- * The date is system-dependant.
+ * The date is system-dependent.
*
* @return A date in the distant future
*/
+ (instancetype)distantFuture;
/**
* @brief Returns a date in the distant past.
*
- * The date is system-dependant.
+ * The date is system-dependent.
*
* @return A date in the distant past
*/
+ (instancetype)distantPast;
Index: src/OFDate.m
==================================================================
--- src/OFDate.m
+++ src/OFDate.m
@@ -316,11 +316,11 @@
mutex = [[OFMutex alloc] init];
atexit(releaseMutex);
#endif
#ifdef OF_WINDOWS
- if ((module = LoadLibrary("msvcrt.dll")) != NULL)
+ if ((module = GetModuleHandle("msvcrt.dll")) != NULL)
_mktime64FuncPtr = (__time64_t (*)(struct tm *))
GetProcAddress(module, "_mktime64");
#endif
}
Index: src/OFFileIRIHandler.m
==================================================================
--- src/OFFileIRIHandler.m
+++ src/OFFileIRIHandler.m
@@ -642,15 +642,15 @@
readdirMutex = [[OFMutex alloc] init];
atexit(releaseReaddirMutex);
#endif
#ifdef OF_WINDOWS
- if ((module = LoadLibrary("msvcrt.dll")) != NULL)
+ if ((module = GetModuleHandle("msvcrt.dll")) != NULL)
_wutime64FuncPtr = (int (*)(const wchar_t *,
struct __utimbuf64 *))GetProcAddress(module, "_wutime64");
- if ((module = LoadLibrary("kernel32.dll")) != NULL) {
+ if ((module = GetModuleHandleA("kernel32.dll")) != NULL) {
createSymbolicLinkWFuncPtr =
(WINAPI BOOLEAN (*)(LPCWSTR, LPCWSTR, DWORD))
GetProcAddress(module, "CreateSymbolicLinkW");
createHardLinkWFuncPtr =
(WINAPI BOOLEAN (*)(LPCWSTR, LPCWSTR,
Index: src/OFFileManager.h
==================================================================
--- src/OFFileManager.h
+++ src/OFFileManager.h
@@ -762,11 +762,11 @@
forName: (OFString *)name
ofItemAtIRI: (OFIRI *)IRI;
#ifdef OF_FILE_MANAGER_SUPPORTS_EXTENDED_ATTRIBUTES
/**
- * @brief Removes the extended attribute for the specified name wof the item at
+ * @brief Removes the extended attribute for the specified name of the item at
* the specified path.
*
* This method is not available on some systems.
*
* @param name The name of the extended attribute to remove
@@ -779,11 +779,11 @@
- (void)removeExtendedAttributeForName: (OFString *)name
ofItemAtPath: (OFString *)path;
#endif
/**
- * @brief Removes the extended attribute for the specified name wof the item at
+ * @brief Removes the extended attribute for the specified name of the item at
* the specified IRI.
*
* This method is not available for all IRIs.
*
* @param name The name of the extended attribute to remove
Index: src/OFGZIPStream.m
==================================================================
--- src/OFGZIPStream.m
+++ src/OFGZIPStream.m
@@ -248,12 +248,13 @@
_inflateStream = nil;
_state++;
break;
case OFGZIPStreamStateCRC32:
- _bytesRead += [_stream readIntoBuffer: _buffer
- length: 4 - _bytesRead];
+ _bytesRead += [_stream
+ readIntoBuffer: _buffer + _bytesRead
+ length: 4 - _bytesRead];
if (_bytesRead < 4)
return 0;
CRC32 = ((uint32_t)_buffer[3] << 24) |
@@ -272,14 +273,18 @@
_bytesRead = 0;
_CRC32 = ~0;
_state++;
break;
case OFGZIPStreamStateUncompressedSize:
- _bytesRead += [_stream readIntoBuffer: _buffer
- length: 4 - _bytesRead];
+ _bytesRead += [_stream
+ readIntoBuffer: _buffer + _bytesRead
+ length: 4 - _bytesRead];
+
+ if (_bytesRead < 4)
+ return 0;
- uncompressedSize = ((uint32_t)_buffer[3] << 24) |
+ uncompressedSize = (_buffer[3] << 24) |
(_buffer[2] << 16) | (_buffer[1] << 8) | _buffer[0];
if (_uncompressedSize != uncompressedSize) {
OFString *actual = [OFString stringWithFormat:
@"%" PRIu32, _uncompressedSize];
OFString *expected = [OFString stringWithFormat:
Index: src/OFHTTPResponse.h
==================================================================
--- src/OFHTTPResponse.h
+++ src/OFHTTPResponse.h
@@ -72,11 +72,11 @@
* @return The response as a string
*/
- (OFString *)readString;
/**
- * @brief Rread the response as a string, trying to detect the encoding and
+ * @brief Read the response as a string, trying to detect the encoding and
* falling back to the specified encoding if not detectable.
*
* @return The response as a string
*/
- (OFString *)readStringWithEncoding: (OFStringEncoding)encoding;
Index: src/OFHTTPServer.h
==================================================================
--- src/OFHTTPServer.h
+++ src/OFHTTPServer.h
@@ -56,11 +56,11 @@
* @param server The HTTP server which encountered an exception
* @param exception The exception which occurred on the HTTP server's listening
* socket
* @return Whether to continue listening. If you return false, existing
* connections will still be handled and you can start accepting new
- * connections again by calling @ref OFHTTPServer::start again.
+ * connections again by calling @ref OFHTTPServer#start again.
*/
- (bool)server: (OFHTTPServer *)server
didReceiveExceptionOnListeningSocket: (id)exception;
/**
Index: src/OFIRI.h
==================================================================
--- src/OFIRI.h
+++ src/OFIRI.h
@@ -216,11 +216,11 @@
/**
* @brief Creates a new IRI with the specified local file path.
*
* @param path The local file path
* @param isDirectory Whether the path is a directory, in which case a slash is
- * appened if there is no slash yet
+ * appended if there is no slash yet
* @return An initialized OFIRI
*/
+ (instancetype)fileIRIWithPath: (OFString *)path
isDirectory: (bool)isDirectory;
#endif
@@ -265,11 +265,11 @@
* @brief Initializes an already allocated OFIRI with the specified local file
* path.
*
* @param path The local file path
* @param isDirectory Whether the path is a directory, in which case a slash is
- * appened if there is no slash yet
+ * appended if there is no slash yet
* @return An initialized OFIRI
*/
- (instancetype)initFileIRIWithPath: (OFString *)path
isDirectory: (bool)isDirectory;
#endif
Index: src/OFIRIHandler.h
==================================================================
--- src/OFIRIHandler.h
+++ src/OFIRIHandler.h
@@ -330,11 +330,11 @@
- (void)setExtendedAttributeData: (OFData *)data
forName: (OFString *)name
ofItemAtIRI: (OFIRI *)IRI;
/**
- * @brief Removes the extended attribute for the specified name wof the item at
+ * @brief Removes the extended attribute for the specified name of the item at
* the specified IRI.
*
* This method is not available for all IRIs.
*
* @param name The name of the extended attribute to remove
Index: src/OFKernelEventObserver.h
==================================================================
--- src/OFKernelEventObserver.h
+++ src/OFKernelEventObserver.h
@@ -43,11 +43,11 @@
@optional
/**
* @brief This callback is called when an object did get ready for reading.
*
* @note If the object is a subclass of @ref OFStream and
- * @ref OFStream::tryReadLine or @ref OFStream::tryReadUntilDelimiter:
+ * @ref OFStream#tryReadLine or @ref OFStream#tryReadUntilDelimiter:
* has been called on the stream, this callback will not be called again
* until new data has been received, even though there is still data in
* the cache. The reason for this is to prevent spinning in a loop when
* there is an incomplete string in the cache. Once the string has been
* completed, the callback will be called again as long there is data in
Index: src/OFList.h
==================================================================
--- src/OFList.h
+++ src/OFList.h
@@ -20,12 +20,12 @@
OF_ASSUME_NONNULL_BEGIN
/** @file */
/*
- * Make clang's -Wdocumentation shut about about using @struct on someting it
- * thinks is not a struct. Doxygen requires it this way.
+ * Make clang's -Wdocumentation shut up about about using @struct on something
+ * it thinks is not a struct. Doxygen requires it this way.
*/
#ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdocumentation"
#endif
Index: src/OFMatrix4x4.h
==================================================================
--- src/OFMatrix4x4.h
+++ src/OFMatrix4x4.h
@@ -60,11 +60,11 @@
*/
- (instancetype)initWithValues: (const float [_Nonnull 4][4])values
OF_DESIGNATED_INITIALIZER;
/**
- * @brief Mulitplies the receiver with the specified matrix on the left side
+ * @brief Multiplies the receiver with the specified matrix on the left side
* and the receiver on the right side.
*
* @param matrix The matrix to multiply the receiver with
*/
- (void)multiplyWithMatrix: (OFMatrix4x4 *)matrix;
Index: src/OFMutableIRI.h
==================================================================
--- src/OFMutableIRI.h
+++ src/OFMutableIRI.h
@@ -201,11 +201,11 @@
/**
* @brief Appends the specified path component.
*
* @param component The component to append
* @param isDirectory Whether the path is a directory, in which case a slash is
- * appened if there is no slash yet
+ * appended if there is no slash yet
*/
- (void)appendPathComponent: (OFString *)component
isDirectory: (bool)isDirectory;
/**
Index: src/OFMutableString.h
==================================================================
--- src/OFMutableString.h
+++ src/OFMutableString.h
@@ -175,11 +175,11 @@
* @brief Replaces all occurrences of a string in the specified range with
* another string.
*
* @param string The string to replace
* @param replacement The string with which it should be replaced
- * @param options Options modifying search behaviour
+ * @param options Options modifying search behavior
* Possible values: None yet
* @param range The range in which the string should be replaced
*/
- (void)replaceOccurrencesOfString: (OFString *)string
withString: (OFString *)replacement
Index: src/OFObject.h
==================================================================
--- src/OFObject.h
+++ src/OFObject.h
@@ -81,11 +81,11 @@
*/
typedef OFComparisonResult (^OFComparator)(id _Nonnull left, id _Nonnull right);
#endif
/**
- * @brief An enum for representing endianess.
+ * @brief An enum for representing endianness.
*/
typedef enum {
/** Most significant byte first (big endian) */
OFByteOrderBigEndian,
/** Least significant byte first (little endian) */
@@ -113,11 +113,11 @@
/**
* @brief Creates a new OFRange.
*
* @param start The starting index of the range
* @param length The length of the range
- * @return An OFRangeith the specified start and length
+ * @return An OFRange with the specified start and length
*/
static OF_INLINE OFRange OF_CONST_FUNC
OFMakeRange(size_t start, size_t length)
{
OFRange range = { start, length };
@@ -1375,11 +1375,12 @@
/**
* @protocol OFComparing OFObject.h ObjFW/OFObject.h
*
* @brief A protocol for comparing objects.
*
- * This protocol is implemented by objects that can be compared. Its only method, @ref compare:, should be overridden with a stronger type.
+ * This protocol is implemented by objects that can be compared. Its only
+ * method, @ref compare:, should be overridden with a stronger type.
*/
@protocol OFComparing
/**
* @brief Compares the object to another object.
*
@@ -1448,11 +1449,11 @@
/**
* @brief Frees memory allocated by @ref OFAllocMemory, @ref OFAllocZeroedMemory
* or @ref OFResizeMemory.
*
- * @param pointer A pointer to the memory to free or nil (passing nil ooes
+ * @param pointer A pointer to the memory to free or nil (passing nil does
* nothing)
*/
extern void OFFreeMemory(void *_Nullable pointer);
#ifdef OF_APPLE_RUNTIME
Index: src/OFObject.m
==================================================================
--- src/OFObject.m
+++ src/OFObject.m
@@ -334,12 +334,13 @@
size_t instanceSize;
instanceSize = class_getInstanceSize(class);
if OF_UNLIKELY (extraAlignment > 1)
- extraAlignment = ((instanceSize + extraAlignment - 1) &
- ~(extraAlignment - 1)) - extraAlignment;
+ extraAlignment = OFRoundUpToPowerOf2(extraAlignment,
+ PRE_IVARS_ALIGN + instanceSize) -
+ PRE_IVARS_ALIGN - instanceSize;
instance = calloc(1, PRE_IVARS_ALIGN + instanceSize +
extraAlignment + extraSize);
if OF_UNLIKELY (instance == nil) {
Index: src/OFPBKDF2.h
==================================================================
--- src/OFPBKDF2.h
+++ src/OFPBKDF2.h
@@ -60,11 +60,11 @@
extern "C" {
#endif
/**
* @brief Derives a key from a password and a salt using PBKDF2.
*
- * @note This will call @ref OFHMAC::reset on the `HMAC` first, making it
+ * @note This will call @ref OFHMAC#reset on the `HMAC` first, making it
* possible to reuse the `HMAC`, but also meaning all previous results
* from the `HMAC` get invalidated if they have not been copied.
*
* @param parameters The parameters to use
*/
Index: src/OFPlugin.h
==================================================================
--- src/OFPlugin.h
+++ src/OFPlugin.h
@@ -73,11 +73,11 @@
/**
* @brief Returns the address for the specified symbol, or `nil` if not found.
*
* @param symbol The symbol to return the address for
- * @return The address for the speccified symbol, or `nil` if not found
+ * @return The address for the specified symbol, or `nil` if not found
*/
- (nullable void *)addressForSymbol: (OFString *)symbol;
@end
OF_ASSUME_NONNULL_END
Index: src/OFSPXSocket.h
==================================================================
--- src/OFSPXSocket.h
+++ src/OFSPXSocket.h
@@ -113,11 +113,12 @@
*
* @param network The network on which the node to connect to is
* @param node The node to connect to
* @param port The port (sometimes also called socket number) on the node to
* connect to
- * @param runLoopMode The run loop mode in which to perform the async connect
+ * @param runLoopMode The run loop mode in which to perform the asynchronous
+ * connect
*/
- (void)asyncConnectToNetwork: (uint32_t)network
node: (const unsigned char [_Nonnull IPX_NODE_LEN])node
port: (uint16_t)port
runLoopMode: (OFRunLoopMode)runLoopMode;
@@ -142,11 +143,12 @@
*
* @param node The node to connect to
* @param network The network on which the node to connect to is
* @param port The port (sometimes also called socket number) on the node to
* connect to
- * @param runLoopMode The run loop mode in which to perform the async connect
+ * @param runLoopMode The run loop mode in which to perform the asynchronous
+ * connect
* @param block The block to execute once the connection has been established
*/
- (void)asyncConnectToNetwork: (uint32_t)network
node: (const unsigned char [_Nonnull IPX_NODE_LEN])node
port: (uint16_t)port
Index: src/OFSPXStreamSocket.h
==================================================================
--- src/OFSPXStreamSocket.h
+++ src/OFSPXStreamSocket.h
@@ -116,11 +116,12 @@
*
* @param network The network on which the node to connect to is
* @param node The node to connect to
* @param port The port (sometimes also called socket number) on the node to
* connect to
- * @param runLoopMode The run loop mode in which to perform the async connect
+ * @param runLoopMode The run loop mode in which to perform the asynchronous
+ * connect
*/
- (void)asyncConnectToNetwork: (uint32_t)network
node: (const unsigned char [_Nonnull IPX_NODE_LEN])node
port: (uint16_t)port
runLoopMode: (OFRunLoopMode)runLoopMode;
@@ -147,11 +148,12 @@
*
* @param network The network on which the node to connect to is
* @param node The node to connect to
* @param port The port (sometimes also called socket number) on the node to
* connect to
- * @param runLoopMode The run loop mode in which to perform the async connect
+ * @param runLoopMode The run loop mode in which to perform the asynchronous
+ * connect
* @param block The block to execute once the connection has been established
*/
- (void)asyncConnectToNetwork: (uint32_t)network
node: (const unsigned char [_Nonnull IPX_NODE_LEN])node
port: (uint16_t)port
Index: src/OFSequencedPacketSocket.h
==================================================================
--- src/OFSequencedPacketSocket.h
+++ src/OFSequencedPacketSocket.h
@@ -207,11 +207,12 @@
*
* If the buffer is too small, the receive operation fails.
*
* @param buffer The buffer to write the packet to
* @param length The length of the buffer
- * @param runLoopMode The run loop mode in which to perform the async receive
+ * @param runLoopMode The run loop mode in which to perform the asynchronous
+ * receive
*/
- (void)asyncReceiveIntoBuffer: (void *)buffer
length: (size_t)length
runLoopMode: (OFRunLoopMode)runLoopMode;
@@ -240,11 +241,12 @@
*
* If the buffer is too small, the receive operation fails.
*
* @param buffer The buffer to write the packet to
* @param length The length of the buffer
- * @param runLoopMode The run loop mode in which to perform the async receive
+ * @param runLoopMode The run loop mode in which to perform the asynchronous
+ * receive
* @param block The block to call when the packet has been received. If the
* block returns true, it will be called again with the same
* buffer and maximum length when more packets have been received.
* If you want the next method in the queue to handle the packet
* received next, you need to return false from the method.
@@ -274,11 +276,12 @@
/**
* @brief Asynchronously sends the specified packet.
*
* @param data The data to send as a packet
- * @param runLoopMode The run loop mode in which to perform the async send
+ * @param runLoopMode The run loop mode in which to perform the asynchronous
+ * send
*/
- (void)asyncSendData: (OFData *)data runLoopMode: (OFRunLoopMode)runLoopMode;
#ifdef OF_HAVE_BLOCKS
/**
@@ -294,11 +297,12 @@
/**
* @brief Asynchronously sends the specified packet.
*
* @param data The data to send as a packet
- * @param runLoopMode The run loop mode in which to perform the async send
+ * @param runLoopMode The run loop mode in which to perform the asynchronous
+ * send
* @param block The block to call when the packet has been sent. It should
* return the data for the next send with the same callback or nil
* if it should not repeat.
*/
- (void)asyncSendData: (OFData *)data
@@ -338,11 +342,12 @@
- (void)asyncAccept;
/**
* @brief Asynchronously accept an incoming connection.
*
- * @param runLoopMode The run loop mode in which to perform the async accept
+ * @param runLoopMode The run loop mode in which to perform the asynchronous
+ * accept
*/
- (void)asyncAcceptWithRunLoopMode: (OFRunLoopMode)runLoopMode;
#ifdef OF_HAVE_BLOCKS
/**
@@ -355,11 +360,12 @@
- (void)asyncAcceptWithBlock: (OFSequencedPacketSocketAsyncAcceptBlock)block;
/**
* @brief Asynchronously accept an incoming connection.
*
- * @param runLoopMode The run loop mode in which to perform the async accept
+ * @param runLoopMode The run loop mode in which to perform the asynchronous
+ * accept
* @param block The block to execute when a new connection has been accepted.
* Returns whether the next incoming connection should be accepted
* by the specified block as well.
*/
- (void)
Index: src/OFSettings.h
==================================================================
--- src/OFSettings.h
+++ src/OFSettings.h
@@ -23,11 +23,11 @@
/**
* @class OFSettings OFSettings.h ObjFW/OFSettings.h
*
* Paths are delimited by dots, for example `category.subcategory.key`.
*
- * @note The behaviour when accessing a path with a different type than it has
+ * @note The behavior when accessing a path with a different type than it has
* been accessed with before is undefined! If you want to change the type
* for a path, remove it and then set it with the new type.
*
* @brief A class for storing and retrieving settings
*/
Index: src/OFSocket.h
==================================================================
--- src/OFSocket.h
+++ src/OFSocket.h
@@ -288,11 +288,11 @@
/**
* @brief Converts the specified @ref OFSocketAddress to a string.
*
* @param address The address to convert to a string
- * @return The address as an IP string, without the port
+ * @return The address as a string, without the port
*/
extern OFString *_Nonnull OFSocketAddressString(
const OFSocketAddress *_Nonnull address);
/**
Index: src/OFSocket.m
==================================================================
--- src/OFSocket.m
+++ src/OFSocket.m
@@ -965,11 +965,11 @@
static OFString *
appleTalkString(const OFSocketAddress *address)
{
const struct sockaddr_at *addrAT = &address->sockaddr.at;
- return [OFString stringWithFormat: @"%d.%d",
+ return [OFString stringWithFormat: @"%" PRIu8 ".%" PRIu8,
OFFromBigEndian16(addrAT->sat_net), addrAT->sat_node];
}
OFString *
OFSocketAddressString(const OFSocketAddress *address)
Index: src/OFStream.h
==================================================================
--- src/OFStream.h
+++ src/OFStream.h
@@ -493,11 +493,11 @@
* @brief Reads a uint16_t from the stream which is encoded in big endian.
*
* @warning Only call this when you know that enough data is available!
* Otherwise you will get an exception!
*
- * @return A uint16_t from the stream in native endianess
+ * @return A uint16_t from the stream in big endian
* @throw OFReadFailedException Reading failed
* @throw OFTruncatedDataException The end of the stream was reached before
* reading enough bytes
* @throw OFNotOpenException The stream is not open
*/
@@ -507,11 +507,11 @@
* @brief Reads a uint32_t from the stream which is encoded in big endian.
*
* @warning Only call this when you know that enough data is available!
* Otherwise you will get an exception!
*
- * @return A uint32_t from the stream in the native endianess
+ * @return A uint32_t from the stream in big endian
* @throw OFReadFailedException Reading failed
* @throw OFTruncatedDataException The end of the stream was reached before
* reading enough bytes
* @throw OFNotOpenException The stream is not open
*/
@@ -521,11 +521,11 @@
* @brief Reads a uint64_t from the stream which is encoded in big endian.
*
* @warning Only call this when you know that enough data is available!
* Otherwise you will get an exception!
*
- * @return A uint64_t from the stream in the native endianess
+ * @return A uint64_t from the stream in big endian
* @throw OFReadFailedException Reading failed
* @throw OFTruncatedDataException The end of the stream was reached before
* reading enough bytes
* @throw OFNotOpenException The stream is not open
*/
@@ -535,11 +535,11 @@
* @brief Reads a float from the stream which is encoded in big endian.
*
* @warning Only call this when you know that enough data is available!
* Otherwise you will get an exception!
*
- * @return A float from the stream in the native endianess
+ * @return A float from the stream in big endian
* @throw OFReadFailedException Reading failed
* @throw OFTruncatedDataException The end of the stream was reached before
* reading enough bytes
* @throw OFNotOpenException The stream is not open
*/
@@ -549,11 +549,11 @@
* @brief Reads a double from the stream which is encoded in big endian.
*
* @warning Only call this when you know that enough data is available!
* Otherwise you will get an exception!
*
- * @return A double from the stream in the native endianess
+ * @return A double from the stream in big endian
* @throw OFReadFailedException Reading failed
* @throw OFTruncatedDataException The end of the stream was reached before
* reading enough bytes
* @throw OFNotOpenException The stream is not open
*/
@@ -563,11 +563,11 @@
* @brief Reads a uint16_t from the stream which is encoded in little endian.
*
* @warning Only call this when you know that enough data is available!
* Otherwise you will get an exception!
*
- * @return A uint16_t from the stream in native endianess
+ * @return A uint16_t from the stream in little endian
* @throw OFReadFailedException Reading failed
* @throw OFTruncatedDataException The end of the stream was reached before
* reading enough bytes
* @throw OFNotOpenException The stream is not open
*/
@@ -577,11 +577,11 @@
* @brief Reads a uint32_t from the stream which is encoded in little endian.
*
* @warning Only call this when you know that enough data is available!
* Otherwise you will get an exception!
*
- * @return A uint32_t from the stream in the native endianess
+ * @return A uint32_t from the stream in little endian
* @throw OFReadFailedException Reading failed
* @throw OFTruncatedDataException The end of the stream was reached before
* reading enough bytes
* @throw OFNotOpenException The stream is not open
*/
@@ -591,11 +591,11 @@
* @brief Reads a uint64_t from the stream which is encoded in little endian.
*
* @warning Only call this when you know that enough data is available!
* Otherwise you will get an exception!
*
- * @return A uint64_t from the stream in the native endianess
+ * @return A uint64_t from the stream in little endian
* @throw OFReadFailedException Reading failed
* @throw OFTruncatedDataException The end of the stream was reached before
* reading enough bytes
* @throw OFNotOpenException The stream is not open
*/
@@ -605,11 +605,11 @@
* @brief Reads a float from the stream which is encoded in little endian.
*
* @warning Only call this when you know that enough data is available!
* Otherwise you will get an exception!
*
- * @return A float from the stream in the native endianess
+ * @return A float from the stream in little endian
* @throw OFReadFailedException Reading failed
* @throw OFTruncatedDataException The end of the stream was reached before
* reading enough bytes
* @throw OFNotOpenException The stream is not open
*/
@@ -619,11 +619,11 @@
* @brief Reads a double from the stream which is encoded in little endian.
*
* @warning Only call this when you know that enough data is available!
* Otherwise you will get an exception!
*
- * @return A double from the stream in the native endianess
+ * @return A double from the stream in little endian
* @throw OFReadFailedException Reading failed
* @throw OFTruncatedDataException The end of the stream was reached before
* reading enough bytes
* @throw OFNotOpenException The stream is not open
*/
Index: src/OFString.h
==================================================================
--- src/OFString.h
+++ src/OFString.h
@@ -77,15 +77,15 @@
OFStringEncodingISO8859_15,
/** Windows-1251 */
OFStringEncodingWindows1251,
/** Windows-1252 */
OFStringEncodingWindows1252,
- /** Codepage 437 */
+ /** Code page 437 */
OFStringEncodingCodepage437,
- /** Codepage 850 */
+ /** Code page 850 */
OFStringEncodingCodepage850,
- /** Codepage 858 */
+ /** Code page 858 */
OFStringEncodingCodepage858,
/** Mac OS Roman */
OFStringEncodingMacRoman,
/** KOI8-R */
OFStringEncodingKOI8R,
@@ -132,11 +132,11 @@
* @brief A class for handling strings.
*/
@interface OFString: OFObject
/**
- * @brief The length of the string in Unicode codepoints.
+ * @brief The length of the string in Unicode code points.
*/
@property (readonly, nonatomic) size_t length;
/**
* @brief The OFString as a UTF-8 encoded C string.
@@ -305,11 +305,11 @@
/**
* @brief Creates a new OFString from a UTF-8 encoded C string without copying
* the string, if possible.
*
* If initialization fails for whatever reason, the passed C string is *not*
- * free'd if `freeWhenDone` is true.
+ * freed if `freeWhenDone` is true.
*
* @note OFMutableString always creates a copy!
*
* @param UTF8String A UTF-8 encoded C string to initialize the OFString with
* @param freeWhenDone Whether to free the C string when the OFString gets
@@ -323,11 +323,11 @@
/**
* @brief Creates a new OFString from a UTF-8 encoded C string with the
* specified length without copying the string, if possible.
*
* If initialization fails for whatever reason, the passed C string is *not*
- * free'd if `freeWhenDone` is true.
+ * freed if `freeWhenDone` is true.
*
* @note OFMutableString always creates a copy!
*
* @param UTF8String A UTF-8 encoded C string to initialize the OFString with
* @param UTF8StringLength The length of the UTF-8 encoded C string
@@ -529,13 +529,13 @@
/**
* @brief Creates a new OFString with the contents of the specified IRI.
*
* If the IRI's scheme is file, it tries UTF-8 encoding.
*
- * If the IRI's scheme is http(s), it tries to detect the encoding from the HTTP
- * headers. If it could not detect the encoding using the HTTP headers, it tries
- * UTF-8.
+ * If the IRI's scheme is `http` or `https`, it tries to detect the encoding
+ * from the HTTP headers. If it could not detect the encoding using the HTTP
+ * headers, it tries UTF-8.
*
* @param IRI The IRI to the contents for the string
* @return A new autoreleased OFString
* @throw OFInvalidEncodingException The string is not in the expected encoding
*/
@@ -585,11 +585,11 @@
/**
* @brief Initializes an already allocated OFString from an UTF-8 encoded C
* string without copying the string, if possible.
*
* If initialization fails for whatever reason, the passed C string is *not*
- * free'd if `freeWhenDone` is true.
+ * freed if `freeWhenDone` is true.
*
* @note OFMutableString always creates a copy!
*
* @param UTF8String A UTF-8 encoded C string to initialize the OFString with
* @param freeWhenDone Whether to free the C string when it is not needed
@@ -604,11 +604,11 @@
* @brief Initializes an already allocated OFString from an UTF-8 encoded C
* string with the specified length without copying the string, if
* possible.
*
* If initialization fails for whatever reason, the passed C string is *not*
- * free'd if `freeWhenDone` is true.
+ * freed if `freeWhenDone` is true.
*
* @note OFMutableString always creates a copy!
*
* @param UTF8String A UTF-8 encoded C string to initialize the OFString with
* @param UTF8StringLength The length of the UTF-8 encoded C string
@@ -830,13 +830,13 @@
* @brief Initializes an already allocated OFString with the contents of the
* specified IRI.
*
* If the IRI's scheme is file, it tries UTF-8 encoding.
*
- * If the IRI's scheme is http(s), it tries to detect the encoding from the HTTP
- * headers. If it could not detect the encoding using the HTTP headers, it tries
- * UTF-8.
+ * If the IRI's scheme is `http` or `https`, it tries to detect the encoding
+ * from the HTTP headers. If it could not detect the encoding using the HTTP
+ * headers, it tries UTF-8.
*
* @param IRI The IRI to the contents for the string
* @return An initialized OFString
* @throw OFInvalidEncodingException The string is not in the expected encoding
*/
@@ -1003,11 +1003,11 @@
/**
* @brief Returns the index of the first character from the set.
*
* @param characterSet The set of characters to search for
- * @param options Options modifying search behaviour
+ * @param options Options modifying search behavior
* @return The index of the first occurrence of a character from the set or
* `OFNotFound` if it was not found
*/
- (size_t)indexOfCharacterFromSet: (OFCharacterSet *)characterSet
options: (OFStringSearchOptions)options;
@@ -1014,11 +1014,11 @@
/**
* @brief Returns the index of the first character from the set.
*
* @param characterSet The set of characters to search for
- * @param options Options modifying search behaviour
+ * @param options Options modifying search behavior
* @param range The range in which to search
* @return The index of the first occurrence of a character from the set or
* `OFNotFound` if it was not found
*/
- (size_t)indexOfCharacterFromSet: (OFCharacterSet *)characterSet
@@ -1043,11 +1043,11 @@
/**
* @brief Creates a substring from the beginning to the specified index.
*
* @param idx The index at which the substring should end, exclusive
- * @return The subtring from the beginning to the specified index
+ * @return The substring from the beginning to the specified index
*/
- (OFString *)substringToIndex: (size_t)idx;
/**
* @brief Creates a substring with the specified range.
@@ -1149,11 +1149,11 @@
* @brief Creates a new string by replacing the occurrences of the specified
* string in the specified range with the specified replacement.
*
* @param string The string to replace
* @param replacement The string with which it should be replaced
- * @param options Options modifying search behaviour.
+ * @param options Options modifying search behavior.
* Possible values are:
* * None yet, pass 0
* @param range The range in which to replace the string
* @return A new string with the occurrences of the specified string replaced
*/
Index: src/OFTCPSocket.h
==================================================================
--- src/OFTCPSocket.h
+++ src/OFTCPSocket.h
@@ -78,11 +78,11 @@
@property (class, nonatomic) uint16_t SOCKS5Port;
#endif
#if !defined(OF_WII) && !defined(OF_NINTENDO_3DS)
/**
- * @brief Whether the socket sends keep alives for the connection.
+ * @brief Whether the socket sends keep-alives for the connection.
*
* @warning This is not available on the Wii or Nintendo 3DS!
*
* @throw OFGetOptionFailedException The option could not be retrieved
* @throw OFSetOptionFailedException The option could not be set
@@ -172,11 +172,12 @@
/**
* @brief Asynchronously connects the OFTCPSocket to the specified destination.
*
* @param host The host to connect to
* @param port The port on the host to connect to
- * @param runLoopMode The run loop mode in which to perform the async connect
+ * @param runLoopMode The run loop mode in which to perform the asynchronous
+ * connect
*/
- (void)asyncConnectToHost: (OFString *)host
port: (uint16_t)port
runLoopMode: (OFRunLoopMode)runLoopMode;
@@ -195,11 +196,12 @@
/**
* @brief Asynchronously connects the OFTCPSocket to the specified destination.
*
* @param host The host to connect to
* @param port The port on the host to connect to
- * @param runLoopMode The run loop mode in which to perform the async connect
+ * @param runLoopMode The run loop mode in which to perform the asynchronous
+ * connect
* @param block The block to execute once the connection has been established
*/
- (void)asyncConnectToHost: (OFString *)host
port: (uint16_t)port
runLoopMode: (OFRunLoopMode)runLoopMode
Index: src/OFThread.h
==================================================================
--- src/OFThread.h
+++ src/OFThread.h
@@ -293,11 +293,11 @@
/**
* @brief This routine is executed when the thread's main method has finished
* executing or terminate has been called.
*
- * @note Be sure to call [super handleTermination]!
+ * @note Be sure to call `[super handleTermination]`!
*/
- (void)handleTermination OF_REQUIRES_SUPER;
/**
* @brief Starts the thread.
Index: src/OFXMLElement.h
==================================================================
--- src/OFXMLElement.h
+++ src/OFXMLElement.h
@@ -60,11 +60,11 @@
*/
@property OF_NULLABLE_PROPERTY (readonly, nonatomic)
OFArray OF_GENERIC(OFXMLAttribute *) *attributes;
/**
- * @brief An array of OFXMLNodes with all children of the element.
+ * @brief An array of @ref OFXMLNode with all children of the element.
*/
@property OF_NULLABLE_PROPERTY (nonatomic, copy)
OFArray OF_GENERIC(OFXMLNode *) *children;
/**
@@ -319,11 +319,11 @@
- (void)insertChild: (OFXMLNode *)child atIndex: (size_t)index;
/**
* @brief Inserts the specified children at the specified index.
*
- * @param children An array of OFXMLNodes which are added as children
+ * @param children An array of @ref OFXMLNode which are added as children
* @param index The index where the child is added
*/
- (void)insertChildren: (OFArray OF_GENERIC(OFXMLNode *) *)children
atIndex: (size_t)index;
Index: src/OFZIPArchiveEntry.h
==================================================================
--- src/OFZIPArchiveEntry.h
+++ src/OFZIPArchiveEntry.h
@@ -196,11 +196,11 @@
* @return The ZIP entry version as a string
*/
extern OFString *OFZIPArchiveEntryVersionToString(uint16_t version);
/**
- * @brief Convers the ZIP entry compression method to a string.
+ * @brief Converts the ZIP entry compression method to a string.
*
* @param compressionMethod The ZIP entry compression method to convert to a
* string
* @return The ZIP entry compression method as a string
*/
Index: src/exceptions/OFCreateSymbolicLinkFailedException.h
==================================================================
--- src/exceptions/OFCreateSymbolicLinkFailedException.h
+++ src/exceptions/OFCreateSymbolicLinkFailedException.h
@@ -33,16 +33,16 @@
int _errNo;
OF_RESERVE_IVARS(OFCreateSymbolicLinkFailedException, 4)
}
/**
- * @brief The IRI at which the symlink should have been created.
+ * @brief The IRI at which the symbolic link should have been created.
*/
@property (readonly, nonatomic) OFIRI *IRI;
/**
- * @brief The target for the symlink.
+ * @brief The target for the symbolic link.
*/
@property (readonly, nonatomic) OFString *target;
/**
* @brief The errno of the error that occurred.
@@ -50,11 +50,11 @@
@property (readonly, nonatomic) int errNo;
/**
* @brief Creates a new, autoreleased create symbolic link failed exception.
*
- * @param IRI The IRI where the symlink should have been created
+ * @param IRI The IRI where the symbolic link should have been created
* @param target The target for the symbolic link
* @param errNo The errno of the error that occurred
* @return A new, autoreleased create symbolic link failed exception
*/
+ (instancetype)exceptionWithIRI: (OFIRI *)IRI
@@ -65,11 +65,11 @@
/**
* @brief Initializes an already allocated create symbolic link failed
* exception.
*
- * @param IRI The IRI where the symlink should have been created
+ * @param IRI The IRI where the symbolic link should have been created
* @param target The target for the symbolic link
* @param errNo The errno of the error that occurred
* @return An initialized create symbolic link failed exception
*/
- (instancetype)initWithIRI: (OFIRI *)IRI
Index: src/platform/POSIX/OFSubprocess.m
==================================================================
--- src/platform/POSIX/OFSubprocess.m
+++ src/platform/POSIX/OFSubprocess.m
@@ -39,12 +39,15 @@
#import "OFNotOpenException.h"
#import "OFOutOfRangeException.h"
#import "OFReadFailedException.h"
#import "OFWriteFailedException.h"
-#if !defined(HAVE_POSIX_SPAWNP) || !defined(HAVE_SPAWN_H)
+#ifndef OF_MACOS
extern char **environ;
+#else
+# include
+# define environ (*_NSGetEnviron())
#endif
@interface OFSubprocess ()
- (void)of_getArgv: (char ***)argv
forProgramName: (OFString *)programName
@@ -176,20 +179,21 @@
@throw [OFInitializationFailedException
exceptionWithClass: self.class];
# endif
if (posix_spawnp(&_pid, path, &actions, &attr,
- argv, env) != 0)
+ argv, (env != NULL ? env : environ)) != 0)
@throw [OFInitializationFailedException
exceptionWithClass: self.class];
} @finally {
posix_spawn_file_actions_destroy(&actions);
posix_spawnattr_destroy(&attr);
}
#else
if ((_pid = vfork()) == 0) {
- environ = env;
+ if (env != NULL)
+ environ = env;
close(_readPipe[0]);
close(_writePipe[1]);
dup2(_writePipe[0], 0);
dup2(_readPipe[1], 1);
@@ -374,11 +378,13 @@
- (void)close
{
if (_readPipe[0] == -1)
@throw [OFNotOpenException exceptionWithObject: self];
- [self closeForWriting];
+ if (_writePipe[1] != -1)
+ [self closeForWriting];
+
close(_readPipe[0]);
if (_pid != -1) {
kill(_pid, SIGTERM);
waitpid(_pid, &_status, WNOHANG);
Index: src/platform/POSIX/OFSystemInfo+NetworkInterfaces.m
==================================================================
--- src/platform/POSIX/OFSystemInfo+NetworkInterfaces.m
+++ src/platform/POSIX/OFSystemInfo+NetworkInterfaces.m
@@ -225,13 +225,16 @@
# if defined(OF_HAVE_IPV6) && defined(HAVE_IF_NAMETOINDEX)
if (address.sockaddr.in6.sin6_family == AF_INET6 &&
address.sockaddr.in6.sin6_addr.s6_addr[0] == 0xFE &&
(address.sockaddr.in6.sin6_addr.s6_addr[1] & 0xC0)
== 0x80) {
-# if defined(HAVE_INET6_GETSCOPEID)
- inet6_getscopeid(&address.sockaddr.in6,
- INET6_IS_ADDR_LINKLOCAL);
+# if defined(__KAME__)
+# define addr6 address.sockaddr.in6.sin6_addr.s6_addr
+ address.sockaddr.in6.sin6_scope_id =
+ (addr6[2] << 8) | addr6[3];
+ addr6[2] = addr6[3] = 0;
+# undef addr6
# elif defined(HAVE_IF_NAMETOINDEX)
address.sockaddr.in6.sin6_scope_id =
if_nametoindex(
[name cStringWithEncoding: encoding]);
# endif
@@ -239,15 +242,18 @@
# endif
[addresses addItem: &address];
next:
-# ifdef _SIZEOF_ADDR_IFREQ
- buffer += _SIZEOF_ADDR_IFREQ(*current);
-# else
- buffer += sizeof(struct ifreq);
-# endif
+# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+ if (current->ifr_addr.sa_len > sizeof(struct sockaddr))
+ buffer += sizeof(struct ifreq) -
+ sizeof(struct sockaddr) +
+ current->ifr_addr.sa_len;
+ else
+# endif
+ buffer += sizeof(struct ifreq);
}
} @finally {
free(ifrs);
closesocket(sock);
}
Index: src/platform/Windows/OFSubprocess.m
==================================================================
--- src/platform/Windows/OFSubprocess.m
+++ src/platform/Windows/OFSubprocess.m
@@ -381,11 +381,13 @@
- (void)close
{
if (_readPipe[0] == NULL)
@throw [OFNotOpenException exceptionWithObject: self];
- [self closeForWriting];
+ if (_writePipe[1] != NULL)
+ [self closeForWriting];
+
CloseHandle(_readPipe[0]);
if (_handle != INVALID_HANDLE_VALUE) {
TerminateProcess(_handle, 0);
CloseHandle(_handle);
Index: src/platform/Windows/OFSystemInfo+NetworkInterfaces.m
==================================================================
--- src/platform/Windows/OFSystemInfo+NetworkInterfaces.m
+++ src/platform/Windows/OFSystemInfo+NetworkInterfaces.m
@@ -36,29 +36,28 @@
static void
init(void)
{
HMODULE module;
- if ((module = LoadLibrary("iphlpapi.dll")) != NULL)
+ if ((module = GetModuleHandle("iphlpapi.dll")) != NULL)
GetAdaptersAddressesFuncPtr = (WINAPI ULONG (*)(ULONG, ULONG,
PVOID, PIP_ADAPTER_ADDRESSES, PULONG))
GetProcAddress(module, "GetAdaptersAddresses");
-
}
static OFMutableDictionary OF_GENERIC(OFString *, OFNetworkInterface) *
networkInterfacesFromGetAdaptersAddresses(void)
{
OFMutableDictionary *ret = [OFMutableDictionary dictionary];
- OFStringEncoding encoding = [OFLocale encoding];
ULONG adapterAddressesSize = sizeof(IP_ADAPTER_ADDRESSES);
PIP_ADAPTER_ADDRESSES adapterAddresses;
if ((adapterAddresses = malloc(adapterAddressesSize)) == NULL)
return nil;
@try {
+ OFStringEncoding encoding = [OFLocale encoding];
ULONG error = GetAdaptersAddressesFuncPtr(AF_UNSPEC, 0, NULL,
adapterAddresses, &adapterAddressesSize);
if (error == ERROR_BUFFER_OVERFLOW) {
PIP_ADAPTER_ADDRESSES newAdapterAddresses =
@@ -100,11 +99,11 @@
dataWithItems: iter->PhysicalAddress
count: iter->PhysicalAddressLength];
[interface setObject: address forKey: key];
}
- for (PIP_ADAPTER_UNICAST_ADDRESS_LH addrIter =
+ for (__typeof__(iter->FirstUnicastAddress) addrIter =
iter->FirstUnicastAddress; addrIter != NULL;
addrIter = addrIter->Next) {
OFSocketAddress address;
int length;
OFNetworkInterfaceKey key;
@@ -193,12 +192,11 @@
OFString *name, *IPString;
OFNumber *index;
OFSocketAddress IPv4Address;
OFData *addresses;
- name = [OFString stringWithCString: iter->AdapterName
- encoding: encoding];
+ name = [OFString stringWithFormat: @"%u", iter->Index];
if ((interface = [ret objectForKey: name]) == nil) {
interface = [OFMutableDictionary dictionary];
[ret setObject: interface forKey: name];
}
Index: src/runtime/ObjFWRT.h
==================================================================
--- src/runtime/ObjFWRT.h
+++ src/runtime/ObjFWRT.h
@@ -132,11 +132,11 @@
*/
typedef bool BOOL;
#endif
/**
- * @brief A method implemenation.
+ * @brief A method implementation.
*
* @param object The messaged object
* @param selector The selector sent
*/
typedef id _Nullable (*IMP)(id _Nonnull object, SEL _Nonnull selector, ...);
@@ -310,11 +310,11 @@
* ABI, small structs might not use the struct return ABI.
*
* @param class_ The class whose method implementation should be returned
* @param selector The selector for the method whose implementation should be
* returned
- * @return The class's metod implementation for the specified selector
+ * @return The class's method implementation for the specified selector
*/
extern IMP _Nullable class_getMethodImplementation(Class _Nullable class_,
SEL _Nonnull selector);
/**
@@ -325,11 +325,11 @@
* ABI, small structs might not use the struct return ABI.
*
* @param class_ The class whose method implementation should be returned
* @param selector The selector for the method whose implementation should be
* returned
- * @return The class's metod implementation for the specified selector
+ * @return The class's method implementation for the specified selector
*/
extern IMP _Nullable class_getMethodImplementation_stret(Class _Nullable class_,
SEL _Nonnull selector);
/**
DELETED src/runtime/lookup-asm/lookup-asm-amd64-macho.S
Index: src/runtime/lookup-asm/lookup-asm-amd64-macho.S
==================================================================
--- src/runtime/lookup-asm/lookup-asm-amd64-macho.S
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2008-2023 Jonathan Schleifer
- *
- * All rights reserved.
- *
- * This file is part of ObjFW. It may be distributed under the terms of the
- * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
- * the packaging of this file.
- *
- * Alternatively, it may be distributed under the terms of the GNU General
- * Public License, either version 2 or 3, which can be found in the file
- * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
- * file.
- */
-
-#include "config.h"
-
-.globl _objc_msg_lookup
-.globl _objc_msg_lookup_stret
-.globl _objc_msg_lookup_super
-.globl _objc_msg_lookup_super_stret
-
-.section __TEXT, __text, regular, pure_instructions
-.macro GENERATE_LOOKUP
-$0:
- testq %rdi, %rdi
- jz returnNilMethod
-
- testb $$1, %dil
- jnz LtaggedPointer_$0
-
- movq (%rdi), %r8
- movq 64(%r8), %r8
-
-Lmain_$0:
- movq (%rsi), %rax
- movzbl %ah, %ecx
- movzbl %al, %edx
-#ifdef OF_SELUID24
- shrl $$16, %eax
-
- movq (%r8,%rax,8), %r8
-#endif
- movq (%r8,%rcx,8), %r8
- movq (%r8,%rdx,8), %rax
-
- testq %rax, %rax
- jz $1
-
- ret
-
-LtaggedPointer_$0:
- movq _objc_taggedPointerSecret@GOTPCREL(%rip), %rax
- xorq (%rax), %rdi
- andb $$0xE, %dil
- movzbl %dil, %r8d
-
- movq _objc_taggedPointerClasses@GOTPCREL(%rip), %rax
- movq (%rax,%r8,4), %r8
- movq 64(%r8), %r8
-
- jmp Lmain_$0
-.endmacro
-
-.macro GENERATE_LOOKUP_SUPER
-$0:
- movq %rdi, %r8
- movq (%rdi), %rdi
- testq %rdi, %rdi
- jz returnNilMethod
-
- movq 8(%r8), %r8
- movq 64(%r8), %r8
- jmp Lmain_$1
-.endmacro
-
-GENERATE_LOOKUP _objc_msg_lookup, _objc_methodNotFound
-GENERATE_LOOKUP _objc_msg_lookup_stret, _objc_methodNotFound_stret
-GENERATE_LOOKUP_SUPER _objc_msg_lookup_super, _objc_msg_lookup
-GENERATE_LOOKUP_SUPER _objc_msg_lookup_super_stret, _objc_msg_lookup_stret
-
-returnNilMethod:
- leaq nilMethod(%rip), %rax
- ret
-
-nilMethod:
- xorq %rax, %rax
- ret
Index: src/runtime/lookup-asm/lookup-asm.S
==================================================================
--- src/runtime/lookup-asm/lookup-asm.S
+++ src/runtime/lookup-asm/lookup-asm.S
@@ -37,14 +37,10 @@
# elif defined(OF_SPARC64)
# include "lookup-asm-sparc64-elf.S"
# elif defined(OF_SPARC)
# include "lookup-asm-sparc-elf.S"
# endif
-#elif defined(OF_MACH_O)
-# if defined(OF_AMD64)
-# include "lookup-asm-amd64-macho.S"
-# endif
#elif defined(OF_WINDOWS)
# if defined(OF_AMD64)
# include "lookup-asm-amd64-win64.S"
# elif defined(OF_X86)
# include "lookup-asm-x86-win32.S"
Index: src/runtime/private.h
==================================================================
--- src/runtime/private.h
+++ src/runtime/private.h
@@ -295,14 +295,10 @@
# if defined(OF_AMD64) || defined(OF_X86) || \
defined(OF_POWERPC64) || defined(OF_POWERPC) || \
defined(OF_ARM64) || defined(OF_ARM) || \
defined(OF_MIPS64_N64) || defined(OF_MIPS) || \
defined(OF_SPARC64) || defined(OF_SPARC)
-# define OF_ASM_LOOKUP
-# endif
-#elif defined(OF_MACH_O)
-# if defined(OF_AMD64)
# define OF_ASM_LOOKUP
# endif
#elif defined(OF_WINDOWS)
# if defined(OF_AMD64) || defined(OF_X86)
# define OF_ASM_LOOKUP
Index: tests/Makefile
==================================================================
--- tests/Makefile
+++ tests/Makefile
@@ -1,9 +1,10 @@
include ../extra.mk
SUBDIRS = ${TESTPLUGIN} \
${OBJC_SYNC} \
+ ${SUBPROCESS} \
terminal
CLEAN = EBOOT.PBP \
boot.dol \
${PROG_NOINST}.arm9 \
@@ -59,10 +60,11 @@
${RUNTIME_ARC_TESTS_M} \
TestsAppDelegate.m \
${USE_SRCS_FILES} \
${USE_SRCS_PLUGINS} \
${USE_SRCS_SOCKETS} \
+ ${USE_SRCS_SUBPROCESS} \
${USE_SRCS_THREADS} \
${USE_SRCS_WINDOWS} \
testfile_bin.m \
testfile_ini.m
SRCS_PLUGINS = OFPluginTests.m
@@ -81,10 +83,11 @@
SRCS_IPX = OFIPXSocketTests.m \
OFSPXSocketTests.m \
OFSPXStreamSocketTests.m
SRCS_UNIX_SOCKETS = OFUNIXDatagramSocketTests.m \
OFUNIXStreamSocketTests.m
+SRCS_SUBPROCESS = OFSubprocessTests.m
SRCS_THREADS = OFThreadTests.m
SRCS_WINDOWS = OFWindowsRegistryKeyTests.m
IOS_USER ?= mobile
IOS_TMP ?= /tmp/objfw-test
@@ -224,10 +227,15 @@
rm -fr romfs tests.nacp
${PROG_NOINST}.rpx: ${PROG_NOINST}
elf2rpl $< $@
-CPPFLAGS += -I../src -I../src/exceptions -I../src/runtime -I.. -DSTDOUT
+CPPFLAGS += -I../src \
+ -I../src/exceptions \
+ -I../src/runtime \
+ -I.. \
+ -DSTDOUT \
+ -DPROG_SUFFIX=\"${PROG_SUFFIX}\"
OBJCFLAGS_RuntimeARCTests.m = -fobjc-arc -fobjc-arc-exceptions
LIBS := ${TESTS_LIBS} ${LIBS}
LDFLAGS += ${MAP_LDFLAGS}
LD = ${OBJC}
Index: tests/OFBlockTests.m
==================================================================
--- tests/OFBlockTests.m
+++ tests/OFBlockTests.m
@@ -28,11 +28,11 @@
extern void *_NSConcreteGlobalBlock;
extern void *_NSConcreteMallocBlock;
#endif
/* Clang on Win32 generates broken code that crashes for global blocks. */
-#if !defined(OF_WINDOWS) || !defined(OF_X86) || !defined(__clang__)
+#if !defined(OF_WINDOWS) || !defined(__clang__)
static void (^globalBlock)(void) = ^ {};
#endif
static int
(^returnStackBlock(void))(void)
@@ -70,11 +70,11 @@
TEST(@"Class of stack block",
(Class)&_NSConcreteStackBlock == objc_getClass("OFStackBlock") &&
[stackBlock isKindOfClass: [OFBlock class]])
-#if !defined(OF_WINDOWS) || !defined(OF_X86) || !defined(__clang__)
+#if !defined(OF_WINDOWS) || !defined(__clang__)
TEST(@"Class of global block",
(Class)&_NSConcreteGlobalBlock == objc_getClass("OFGlobalBlock") &&
[globalBlock isKindOfClass: [OFBlock class]])
#endif
@@ -91,11 +91,11 @@
TEST(@"Copying a stack block and using its copied variable",
(voidBlock = returnStackBlock()) && voidBlock() == 43 &&
voidBlock() == 44 && voidBlock() == 45)
-#if !defined(OF_WINDOWS) || !defined(OF_X86) || !defined(__clang__)
+#if !defined(OF_WINDOWS) || !defined(__clang__)
TEST(@"Copying a global block",
(id)globalBlock == [[globalBlock copy] autorelease])
#endif
#ifndef __clang_analyzer__
@@ -104,11 +104,11 @@
[mallocBlock retainCount] == 2)
#endif
TEST(@"Autorelease a stack block", R([stackBlock autorelease]))
-#if !defined(OF_WINDOWS) || !defined(OF_X86) || !defined(__clang__)
+#if !defined(OF_WINDOWS) || !defined(__clang__)
TEST(@"Autorelease a global block", R([globalBlock autorelease]))
#endif
#ifndef __clang_analyzer__
TEST(@"Autorelease a malloc block", R([mallocBlock autorelease]))
ADDED tests/OFSubprocessTests.m
Index: tests/OFSubprocessTests.m
==================================================================
--- /dev/null
+++ tests/OFSubprocessTests.m
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#include "config.h"
+
+#import "TestsAppDelegate.h"
+
+static OFString *const module = @"OFSubprocess";
+
+@implementation TestsAppDelegate (OFSubprocessTests)
+- (void)subprocessTests
+{
+ void *pool = objc_autoreleasePoolPush();
+#ifdef OF_HAVE_FILES
+ OFString *program = [@"subprocess" stringByAppendingPathComponent:
+ @"subprocess" @PROG_SUFFIX];
+#else
+ OFString *program = @"subprocess/subprocess" @PROG_SUFFIX;
+#endif
+ OFArray *arguments = [OFArray arrayWithObjects: @"tést", @"123", nil];
+ OFMutableDictionary *environment =
+ [[[OFApplication environment] mutableCopy] autorelease];
+ OFSubprocess *subprocess;
+
+ [environment setObject: @"yés" forKey: @"tëst"];
+
+ TEST(@"+[subprocessWithProgram:programName:arguments:environment]",
+ (subprocess =
+ [OFSubprocess subprocessWithProgram: program
+ programName: program
+ arguments: arguments
+ environment: environment]))
+
+ TEST(@"Standard input", R([subprocess writeLine: @"Hellö world!"]))
+
+ TEST(@"Standard output",
+ [[subprocess readLine] isEqual: @"HELLÖ WORLD!"])
+
+ TEST(@"-[closeForWriting]", R([subprocess closeForWriting]))
+
+ TEST(@"-[waitForTermination]", [subprocess waitForTermination] == 0)
+
+ objc_autoreleasePoolPop(pool);
+}
+@end
Index: tests/TestsAppDelegate.h
==================================================================
--- tests/TestsAppDelegate.h
+++ tests/TestsAppDelegate.h
@@ -248,10 +248,14 @@
@end
@interface TestsAppDelegate (OFStringTests)
- (void)stringTests;
@end
+
+@interface TestsAppDelegate (OFSubprocessTests)
+- (void)subprocessTests;
+@end
@interface TestsAppDelegate (OFTCPSocketTests)
- (void)TCPSocketTests;
@end
Index: tests/TestsAppDelegate.m
==================================================================
--- tests/TestsAppDelegate.m
+++ tests/TestsAppDelegate.m
@@ -442,12 +442,15 @@
[self XMLElementBuilderTests];
[self JSONTests];
[self propertyListTests];
[self matrix4x4Tests];
-#if defined(OF_HAVE_PLUGINS)
+#ifdef OF_HAVE_PLUGINS
[self pluginTests];
+#endif
+#ifdef OF_HAVE_SUBPROCESSES
+ [self subprocessTests];
#endif
#ifdef OF_WINDOWS
[self windowsRegistryKeyTests];
#endif
ADDED tests/subprocess/Makefile
Index: tests/subprocess/Makefile
==================================================================
--- /dev/null
+++ tests/subprocess/Makefile
@@ -0,0 +1,9 @@
+PROG_NOINST = subprocess${PROG_SUFFIX}
+SRCS = Subprocess.m
+
+include ../../buildsys.mk
+include ../../extra.mk
+
+CPPFLAGS += -I../../src -I../../src/exceptions -I../../src/runtime -I../..
+LIBS := -L../../src -lobjfw -L../../src/runtime ${RUNTIME_LIBS} ${LIBS}
+LD = ${OBJC}
ADDED tests/subprocess/Subprocess.m
Index: tests/subprocess/Subprocess.m
==================================================================
--- /dev/null
+++ tests/subprocess/Subprocess.m
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#include "config.h"
+
+#import "ObjFW.h"
+
+@interface Subprocess: OFObject
+@end
+
+OF_APPLICATION_DELEGATE(Subprocess)
+
+@implementation Subprocess
+- (void)applicationDidFinishLaunching: (OFNotification *)notification
+{
+ OFString *line;
+
+ if (![[OFApplication arguments] isEqual:
+ [OFArray arrayWithObjects: @"tést", @"123", nil]])
+ [OFApplication terminateWithStatus: 1];
+
+ if (![[[OFApplication environment] objectForKey: @"tëst"]
+ isEqual: @"yés"])
+ [OFApplication terminateWithStatus: 2];
+
+ while ((line = [OFStdIn readLine]) != nil)
+ [OFStdOut writeLine: line.uppercaseString];
+
+ [OFApplication terminate];
+}
+@end