summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Schleifer <js@nil.im>2020-07-06 23:42:22 +0000
committerJonathan Schleifer <js@nil.im>2020-07-06 23:42:22 +0000
commite28e93fa5684631fc4ff87032a4714ecb686d179 (patch)
tree0aa0c46b0cd0ffeaf1cfe3c8aac43e21814fffad
parent5f279937f0756200a963ee2e1001e64ea405730a (diff)
parente8d90ad1fcf3373b738ed50c072989d580af2e94 (diff)
Merge trunk into branch "1.0"1.0
FossilOrigin-Name: 98f0907d36e6738cb7d7280a27b631591130bb7af7bc968388ad6b19ab47cd05
-rw-r--r--.cirrus.yml22
-rw-r--r--.fossil-settings/clean-glob2
-rw-r--r--.fossil-settings/ignore-glob2
-rw-r--r--.gitignore2
-rw-r--r--.travis.yml20
-rw-r--r--Makefile8
-rw-r--r--PLATFORMS.md26
-rw-r--r--README.md150
-rw-r--r--build-aux/m4/buildsys.m42
-rw-r--r--buildsys.mk.in4
-rw-r--r--configure.ac33
-rw-r--r--extra.mk.in1
-rw-r--r--src/Makefile2
-rw-r--r--src/OFAdjacentArray.m2
-rw-r--r--src/OFApplication.m1
-rw-r--r--src/OFArray+Private.h1
-rw-r--r--src/OFDNSResolver.h4
-rw-r--r--src/OFDNSResolver.m42
-rw-r--r--src/OFData+CryptoHashing.m2
-rw-r--r--src/OFDictionary.m5
-rw-r--r--src/OFEnumerator.h2
-rw-r--r--src/OFEpollKernelEventObserver.m4
-rw-r--r--src/OFFileURLHandler.h2
-rw-r--r--src/OFFileURLHandler.m297
-rw-r--r--src/OFGZIPStream.h53
-rw-r--r--src/OFGZIPStream.m9
-rw-r--r--src/OFHTTPClient.m4
-rw-r--r--src/OFHTTPResponse.h6
-rw-r--r--src/OFHTTPServer.m4
-rw-r--r--src/OFINICategory+Private.h1
-rw-r--r--src/OFINICategory.m2
-rw-r--r--src/OFINIFile.m1
-rw-r--r--src/OFINIFileSettings.m2
-rw-r--r--src/OFKernelEventObserver.m2
-rw-r--r--src/OFLHAArchive.m2
-rw-r--r--src/OFLHAArchiveEntry+Private.h1
-rw-r--r--src/OFLHADecompressingStream.h1
-rw-r--r--src/OFList.m1
-rw-r--r--src/OFMD5Hash.m1
-rw-r--r--src/OFMapTable+Private.h1
-rw-r--r--src/OFMapTable.m4
-rw-r--r--src/OFMutableAdjacentArray.m2
-rw-r--r--src/OFMutableString.m3
-rw-r--r--src/OFMutableUTF8String.m2
-rw-r--r--src/OFPollKernelEventObserver.m4
-rw-r--r--src/OFRIPEMD160Hash.m1
-rw-r--r--src/OFRunLoop+Private.h1
-rw-r--r--src/OFRunLoop.h2
-rw-r--r--src/OFRunLoop.m3
-rw-r--r--src/OFSHA1Hash.m1
-rw-r--r--src/OFSPXSocket.m1
-rw-r--r--src/OFSPXStreamSocket.m1
-rw-r--r--src/OFSelectKernelEventObserver.m5
-rw-r--r--src/OFStdIOStream+Private.h1
-rw-r--r--src/OFStdIOStream.m25
-rw-r--r--src/OFStream+Private.h1
-rw-r--r--src/OFString.m12
-rw-r--r--src/OFTarArchive.m2
-rw-r--r--src/OFTarArchiveEntry+Private.h1
-rw-r--r--src/OFThread+Private.h1
-rw-r--r--src/OFTimer+Private.h1
-rw-r--r--src/OFTimer.m3
-rw-r--r--src/OFUDPSocket+Private.h1
-rw-r--r--src/OFUDPSocket.m2
-rw-r--r--src/OFURL.m1
-rw-r--r--src/OFUTF8String+Private.h1
-rw-r--r--src/OFWindowsRegistryKey.m1
-rw-r--r--src/OFXMLElement.m2
-rw-r--r--src/OFXMLParser.h3
-rw-r--r--src/OFXMLParser.m746
-rw-r--r--src/OFZIPArchive.m4
-rw-r--r--src/OFZIPArchiveEntry+Private.h5
-rw-r--r--src/ObjFW.h3
-rw-r--r--src/exceptions/OFDNSQueryFailedException.m2
-rw-r--r--src/forwarding/apple-forwarding-i386.S118
-rw-r--r--src/forwarding/apple-forwarding-x86_64.S200
-rw-r--r--src/forwarding/forwarding-sparc-elf.S175
-rw-r--r--src/forwarding/forwarding-sparc64-elf.S30
-rw-r--r--src/forwarding/forwarding-x86-elf.S262
-rw-r--r--src/forwarding/forwarding-x86-win32.S255
-rw-r--r--src/forwarding/forwarding-x86_64-elf.S250
-rw-r--r--src/forwarding/forwarding-x86_64-macho.S238
-rw-r--r--src/forwarding/forwarding-x86_64-win64.S194
-rw-r--r--src/forwarding/forwarding.S2
-rw-r--r--src/macros.h13
-rw-r--r--src/pbkdf2.h53
-rw-r--r--src/pbkdf2.m70
-rw-r--r--src/platform/amiga/thread.m13
-rw-r--r--src/platform/windows/thread.m66
-rw-r--r--src/runtime/exception.m5
-rw-r--r--src/runtime/lookup-asm/lookup-asm-sparc-elf.S7
-rw-r--r--src/runtime/lookup-asm/lookup-asm-x86-elf.S63
-rw-r--r--src/runtime/lookup-asm/lookup-asm-x86-win32.S61
-rw-r--r--src/runtime/lookup-asm/lookup-asm-x86_64-elf.S48
-rw-r--r--src/runtime/lookup-asm/lookup-asm-x86_64-macho.S38
-rw-r--r--src/runtime/lookup-asm/lookup-asm-x86_64-win64.S56
-rw-r--r--src/scrypt.h41
-rw-r--r--src/scrypt.m81
-rw-r--r--tests/Makefile1
-rw-r--r--tests/OFDNSResolverTests.m4
-rw-r--r--tests/OFLocaleTests.m8
-rwxr-xr-xtests/OFSPXSocketTests.m28
-rwxr-xr-xtests/OFSPXStreamSocketTests.m28
-rw-r--r--tests/PBKDF2Tests.m97
-rw-r--r--tests/ScryptTests.m58
-rw-r--r--tests/TestsAppDelegate.m8
-rw-r--r--tests/plugin/Makefile2
-rw-r--r--utils/ofarc/GZIPArchive.m19
-rw-r--r--utils/ofarc/LHAArchive.m28
-rw-r--r--utils/ofarc/TarArchive.m20
-rw-r--r--utils/ofarc/ZIPArchive.m20
111 files changed, 2541 insertions, 1694 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
new file mode 100644
index 00000000..550d9c6b
--- /dev/null
+++ b/.cirrus.yml
@@ -0,0 +1,22 @@
+task:
+ name: FreeBSD 12.1
+ freebsd_instance:
+ image_family: freebsd-12-1
+ install_script:
+ pkg install -y autoconf automake
+ shared_script:
+ - ./autogen.sh
+ - ./configure
+ - make -j4 install
+ static_script:
+ - ./autogen.sh
+ - ./configure --disable-shared
+ - make -j4 install
+ shared_seluid24_script:
+ - ./autogen.sh
+ - ./configure --enable-seluid24
+ - make -j4 install
+ static_seluid24_script:
+ - ./autogen.sh
+ - ./configure --disable-shared --enable-seluid24
+ - make -j4 install
diff --git a/.fossil-settings/clean-glob b/.fossil-settings/clean-glob
index 43a41c90..5a472925 100644
--- a/.fossil-settings/clean-glob
+++ b/.fossil-settings/clean-glob
@@ -21,7 +21,6 @@ config.h.in
config.log
config.status
configure
-DerivedData
docs
extra.mk
generators/gen_tables
@@ -30,6 +29,7 @@ src/bridge/Info.plist
src/objfw-defs.h
src/runtime/amiga-library-functable.inc
src/runtime/inline.h
+tests/DerivedData
tests/EBOOT.PBP
tests/Info.plist
tests/PARAM.SFO
diff --git a/.fossil-settings/ignore-glob b/.fossil-settings/ignore-glob
index eab02e38..1e0726e8 100644
--- a/.fossil-settings/ignore-glob
+++ b/.fossil-settings/ignore-glob
@@ -23,7 +23,6 @@ config.h.in
config.log
config.status
configure
-DerivedData
docs
extra.mk
generators/gen_tables
@@ -32,6 +31,7 @@ src/bridge/Info.plist
src/objfw-defs.h
src/runtime/amiga-library-functable.inc
src/runtime/inline.h
+tests/DerivedData
tests/EBOOT.PBP
tests/Info.plist
tests/PARAM.SFO
diff --git a/.gitignore b/.gitignore
index bbe9232e..593731d6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,7 +23,6 @@ config.h.in
config.log
config.status
configure
-DerivedData
docs
extra.mk
generators/gen_tables
@@ -32,6 +31,7 @@ src/bridge/Info.plist
src/objfw-defs.h
src/runtime/amiga-library-functable.inc
src/runtime/inline.h
+tests/DerivedData
tests/EBOOT.PBP
tests/Info.plist
tests/PARAM.SFO
diff --git a/.travis.yml b/.travis.yml
index 81b70712..9591637f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -225,19 +225,19 @@ matrix:
# Nintendo 3DS
- os: linux
- dist: trusty
+ dist: bionic
env:
- config=nintendo_3ds
# Nintendo DS
- os: linux
- dist: trusty
+ dist: bionic
env:
- config=nintendo_ds
# Nintendo Wii
- os: linux
- dist: trusty
+ dist: bionic
env:
- config=wii
@@ -268,8 +268,10 @@ before_install:
- if [ "$config" = "nintendo_3ds" -o "$config" = "nintendo_ds"
-o "$config" = "wii" ]; then
- wget https://github.com/devkitPro/pacman/releases/download/devkitpro-pacman-1.0.1/devkitpro-pacman.deb;
- sudo dpkg -i devkitpro-pacman.deb;
+ deb=devkitpro-pacman.amd64.deb;
+ wget https://github.com/devkitPro/pacman/releases/download/v1.0.2/$deb;
+ sudo apt install gdebi;
+ sudo gdebi -n $deb;
fi
- if [ "$config" = "nintendo_3ds" ]; then
@@ -290,14 +292,6 @@ before_install:
fi
script:
- # This needs to use ed on macOS, as it has no GNU sed, and sed on Linux, as
- # some Travis hosts have no ed.
- - if [ "$TRAVIS_OS_NAME" = "osx" ]; then
- echo -e '%s/-DSTDOUT$/&_SIMPLE/\nwq' | ed -s tests/Makefile;
- else
- sed -i 's/-DSTDOUT$/&_SIMPLE/' tests/Makefile;
- fi
-
- build() {
if ! git clean -fxd >/tmp/clean_log 2>&1; then
cat /tmp/clean_log;
diff --git a/Makefile b/Makefile
index 599b3d5e..78d727cd 100644
--- a/Makefile
+++ b/Makefile
@@ -12,9 +12,15 @@ DISTCLEAN = Info.plist \
include buildsys.mk
+.PHONY: docs tarball
+
utils tests: src
-tarball:
+docs:
+ rm -fr docs
+ doxygen >/dev/null
+
+tarball: docs
echo "Generating tarball for version ${PACKAGE_VERSION}..."
rm -fr objfw-${PACKAGE_VERSION} objfw-${PACKAGE_VERSION}.tar \
objfw-${PACKAGE_VERSION}.tar.gz
diff --git a/PLATFORMS.md b/PLATFORMS.md
index 550e8651..7f33da6d 100644
--- a/PLATFORMS.md
+++ b/PLATFORMS.md
@@ -79,9 +79,10 @@ iOS
Linux
-----
- * Architectures: Alpha, ARMv6, ARM64, Itanium, m68k, MIPS (O32), RISC-V 64,
- PowerPC, S390x, SH4, x86, x86_64
- * Compilers: Clang 3.0-9.0, GCC 4.6-8.2
+ * Architectures: Alpha, ARMv6, ARMv7, ARM64, Itanium, m68k, MIPS (O32),
+ MIPS64 (N64), RISC-V 64, PowerPC, S390x, SuperH-4, x86,
+ x86_64
+ * Compilers: Clang 3.0-10.0, GCC 4.6-10.0
* Runtimes: ObjFW
@@ -89,8 +90,8 @@ macOS
-----
* OS Versions: 10.5, 10.7-10.14, Darling
- * Architectures: PowerPC, PowerPC 64, x86, x86_64
- * Compilers: Clang 3.1-7.0, GCC 4.2.1
+ * Architectures: PowerPC, PowerPC64, x86, x86_64
+ * Compilers: Clang 3.1-10.0, GCC 4.2.1
* Runtimes: Apple, ObjFW
@@ -107,8 +108,9 @@ MorphOS
NetBSD
------
- * OS Versions: 5.1-7.99
- * Architectures: ARM, ARM (big endian, BE8 mode), SPARC, SPARC64, x86, x86_64
+ * OS Versions: 5.1-9.0
+ * Architectures: ARM, ARM (big endian, BE8 mode), MIPS (O32), SPARC, SPARC64,
+ x86, x86_64
* Compilers: Clang 3.0-3.2, GCC 4.1.3 & 4.5.3
* Runtimes: ObjFW
@@ -136,7 +138,7 @@ Nintendo DS
OpenBSD
-------
- * OS Versions: 5.2-6.5
+ * OS Versions: 5.2-6.7
* Architectures: MIPS64, PA-RISC, PowerPC, SPARC64, x86_64
* Compilers: GCC 6.3.0, Clang 4.0
* Runtimes: ObjFW
@@ -183,9 +185,12 @@ Wii
Windows
-------
- * OS Versions: XP (x86), 7 (x64), 8 (x64), 8.1 (x64), 10, Wine (x86 & x64)
+ * OS Versions: 98 SE, NT 4.0, XP (x86), 7 (x64), 8 (x64), 8.1 (x64), 10,
+ Wine (x86 & x64)
* Architectures: x86, x86_64
- * Compilers: GCC 6.2.0 from msys2 (x86 and x64), Clang 3.9.0 from msys2 (x86)
+ * Compilers: GCC 5.3.0 & 6.2.0 from msys2 (x86 & x64),
+ Clang 3.9.0 from msys2 (x86),
+ Clang 10.0 from msys2 (x86 & x86_64)
* Runtimes: ObjFW
@@ -213,6 +218,7 @@ resolveInstanceMethod:, which are always available):
* ARM64 (ARM64/ELF, Apple/Mach-O)
* MIPS (O32/ELF, EABI/ELF)
* PowerPC (SysV/ELF, EABI/ELF, Apple/Mach-O)
+ * SPARC (SysV/ELF)
* SPARC64 (SysV/ELF)
* x86 (SysV/ELF, Apple/Mach-O, Win32/PE)
* x86_64 (SysV/ELF, Apple/Mach-O, Mach-O, Win64/PE)
diff --git a/README.md b/README.md
index f397a518..7d43ccb2 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,19 @@
-ObjFW is a portable, lightweight framework for the Objective C language. It
-enables you to write an application in Objective C that will run on any
-platform supported by ObjFW without having to worry about differences between
-operating systems or various frameworks that you would otherwise need if you
-want to be portable.
+There are three ways you are probably reading this right now:
-See https://objfw.nil.im/ for more information.
+ * On [ObjFW](https://objfw.nil.im/)'s homepage, via Fossil
+ * On [GitHub](https://github.com/ObjFW/ObjFW)
+ * Via an editor or pager, by opening `README.md` from a checkout or tarball
+
+ObjFW is developed using Fossil, so if you are reading this on GitHub or any
+other place, you are most likely using a mirror.
<h1 id="table-of-contents">Table of Contents</h1>
+ * [What is ObjFW?](#what)
+ * [License](#license)
+ * [Releases](#releases)
+ * [Cloning the repository](#cloning)
* [Installation](#installation)
* [macOS and iOS](#macos-and-ios)
* [Building as a framework](#building-framework)
@@ -25,10 +30,104 @@ See https://objfw.nil.im/ for more information.
* [Wii](#wii)
* [Amiga](#amiga)
* [Writing your first application with ObjFW](#first-app)
+ * [Documentation](#documentation)
* [Bugs and feature requests](#bugs)
+ * [Support and community](#support)
* [Commercial use](#commercial-use)
+<h1 id="what">What is ObjFW?</h1>
+
+ ObjFW is a portable, lightweight framework for the Objective-C language. It
+ enables you to write an application in Objective-C that will run on any
+ [platform](PLATFORMS.md) supported by ObjFW without having to worry about
+ differences between operating systems or various frameworks you would
+ otherwise need if you want to be portable.
+
+ It supports all modern Objective-C features when using Clang, but is also
+ compatible with GCC ≥ 4.6 to allow maximum portability.
+
+ ObjFW is intentionally incompatible with Foundation. This has two reasons:
+
+ * 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
+ 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.
+ * Foundation predates a lot of modern Objective-C concepts. The most
+ prominent one is exceptions, which are only used in Foundation as a
+ replacement for `abort()`. This results in cumbersome error handling,
+ especially in initializers, which in Foundation only return `nil` on error
+ with no indication of what went wrong. It also means that the return of
+ every `init` call needs to be checked against `nil`. But in the wild,
+ nobody actually checks *each and every* return from `init` against `nil`,
+ leading to bugs. ObjFW fixes this by making exceptions a first class
+ citizen.
+
+ ObjFW also comes with its own lightweight and extremely fast Objective-C
+ runtime, which in real world use cases was found to be significantly faster
+ than both GNU's and Apple's runtime.
+
+
+<h1 id="license">License</h1>
+
+ ObjFW is released under three licenses:
+
+ * [QPL](LICENSE.QPL)
+ * [GPLv2](LICENSE.GPLv2)
+ * [GPLv3](LICENSE.GPLv3)
+
+ The QPL allows you to use ObjFW in any open source project. Because the GPL
+ does not allow using code under any other license, ObjFW is also available
+ under the GPLv2 and GPLv3 to allow GPL-licensed projects to use ObjFW.
+
+ You can pick under which of those three licenses you want to use ObjFW. If
+ none of them work for you, contact me and we can find a solution.
+
+
+<h1 id="releases">Releases</h1>
+
+ Releases of ObjFW, as well as changelogs and the accompanying documentation
+ can be found [here](https://objfw.nil.im/wiki?name=Releases).
+
+
+<h1 id="cloning">Cloning the repository</h1>
+
+ ObjFW is developed in a [Fossil](https://fossil-scm.org) repository, with
+ automatic incremental exports to Git. This means you can either clone the
+ Fossil repository or the Git repository - it does not make a huge difference.
+ The main advantage of cloning the Fossil repository over cloning the Git
+ repository is that you also get all the tickets, wiki pages, etc.
+
+<h2 id="cloning-fossil">Fossil</h2>
+
+ Clone the Fossil repository like this:
+
+ $ fossil clone https://objfw.nil.im objfw.fossil
+ $ mkdir objfw && cd objfw
+ $ fossil open ../objfw.fossil
+
+ You can then use Fossil's web interface to browse the timeline, tickets,
+ wiki pages, etc.:
+
+ $ fossil ui
+
+ It's also possible to open the same local repository multiple times, so that
+ you have multiple working directories all backed by the same local
+ repository.
+
+<h2 id="cloning-git">Git</h2>
+
+ To clone the Git repository, use the following:
+
+ $ git clone https://github.com/ObjFW/ObjFW
+
+
<h1 id="installation">Installation</h1>
To install ObjFW, just run the following commands:
@@ -144,9 +243,9 @@ See https://objfw.nil.im/ for more information.
$ pacman -S mingw-w64-x86_64-clang mingw-w64-x86_64-gcc-objc
There is nothing wrong with installing them both, as MSYS2 has created two
- entries in your start menu: `MinGW-w64 Win32 Shell` and `MinGW-w64 Win64
- Shell`. So if you want to build for 32 or 64 bit, you just start the correct
- shell.
+ entries in your start menu: `MinGW-w64 Win32 Shell` and
+ `MinGW-w64 Win64 Shell`. So if you want to build for 32 or 64 bit, you just
+ start the correct shell.
Finally, install a few more things needed to build ObjFW:
@@ -222,10 +321,39 @@ See https://objfw.nil.im/ for more information.
your own build system, you can get the necessary flags from `objfw-config`.
+<h1 id="documentation">Documentation</h1>
+
+ You can find the documentation for released versions of ObjFW
+ [here](https://objfw.nil.im/docs/).
+
+ In order to build the documentation yourself (necessary to have documentation
+ for trunk / master), you need to have [Doxygen](https://www.doxygen.nl)
+ installed. Once installed, you can build the documentation from the root
+ directory of the repository:
+
+ $ doxygen >/dev/null
+
+
<h1 id="bugs">Bugs and feature requests</h1>
- If you find any bugs or have feature requests, feel free to send a mail to
- js@nil.im!
+ If you find any bugs or have feature requests, please
+ [file a new bug](https://objfw.nil.im/tktnew) in the
+ [bug tracker](https://objfw.nil.im/reportlist).
+
+ Alternatively, feel free to send a mail to js@nil.im!
+
+
+<h1 id="support">Support and community</h1>
+
+ 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](https://matrix.to/#/%23objfw:nil.im) room
+ * An [IRC channel](irc://chat.freenode.net/#objfw) on Freenode (`#objfw`),
+ bridged to the Matrix room above
+
+ Please don't hesitate to join any or all of those!
<h1 id="commercial-use">Commercial use</h1>
diff --git a/build-aux/m4/buildsys.m4 b/build-aux/m4/buildsys.m4
index c78c03c1..3cabdbb6 100644
--- a/build-aux/m4/buildsys.m4
+++ b/build-aux/m4/buildsys.m4
@@ -3,7 +3,7 @@ dnl Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2016, 2017,
dnl 2018, 2020
dnl Jonathan Schleifer <js@nil.im>
dnl
-dnl https://git.nil.im/buildsys.git
+dnl https://fossil.nil.im/buildsys
dnl
dnl Permission to use, copy, modify, and/or distribute this software for any
dnl purpose with or without fee is hereby granted, provided that the above
diff --git a/buildsys.mk.in b/buildsys.mk.in
index b92270bd..6cb1a2cd 100644
--- a/buildsys.mk.in
+++ b/buildsys.mk.in
@@ -3,7 +3,7 @@
# 2017, 2018, 2020
# Jonathan Schleifer <js@nil.im>
#
-# https://git.nil.im/buildsys.git
+# https://fossil.nil.im/buildsys
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -216,7 +216,7 @@ copy-headers-into-framework:
${AMIGA_LIB} ${AMIGA_LIB_NOINST}: ${EXT_DEPS} ${AMIGA_LIB_OBJS_START} ${AMIGA_LIB_OBJS} ${AMIGA_LIB_OBJS_EXTRA}
${LINK_STATUS}
- if ${LD} -o $@ ${AMIGA_LIB_OBJS_START} ${AMIGA_LIB_OBJS} ${AMIGA_LIB_OBJS_EXTRA} ${AMIGA_LIB_LDFLAGS} ${LDFLAGS} ${LIBS}; then \
+ if ${LD} -o $@ ${AMIGA_LIB_OBJS_START} ${AMIGA_LIB_OBJS} ${AMIGA_LIB_OBJS_EXTRA} ${AMIGA_LIB_LDFLAGS} ${AMIGA_LIB_LIBS}; then \
${LINK_OK}; \
else \
${LINK_FAILED}; \
diff --git a/configure.ac b/configure.ac
index d4d72f78..27d8b3f6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -60,10 +60,10 @@ case "$host" in
AC_SUBST(SFDC_INLINE_H, inline.h)
dnl For 68000, GCC emits calls to helper functions that
dnl do not work properly in a library.
- AC_SUBST(AMIGA_LIB_CFLAGS,
- "-mcpu=68020 -fbaserel -ffreestanding")
+ t="-mcpu=68020 -fbaserel -noixemul"
+ AC_SUBST(AMIGA_LIB_CFLAGS, "$t -ffreestanding")
AC_SUBST(AMIGA_LIB_LDFLAGS,
- "-mcpu=68020 -fbaserel -resident -nostartfiles")
+ "$t -resident -nostartfiles")
])
AC_SUBST(LIBBASES_M, libbases.m)
@@ -91,10 +91,10 @@ case "$host" in
AS_IF([test x"$enable_amiga_lib" != x"no"], [
AC_SUBST(OBJFWRT_AMIGA_LIB, objfwrt.library)
AC_SUBST(CVINCLUDE_INLINE_H, inline.h)
- t="-mresident32 -ffreestanding"
+ t="-mresident32 -ffreestanding -noixemul"
AC_SUBST(AMIGA_LIB_CFLAGS, $t)
t="-mresident32 -nostartfiles -nodefaultlibs"
- t="$t -lc"
+ t="$t -noixemul -lc"
AC_SUBST(AMIGA_LIB_LDFLAGS, $t)
])
@@ -252,6 +252,14 @@ case "$OBJC" in
OBJCFLAGS="$OBJCFLAGS $flag"
OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS $flag"
;;
+ dnl Don't use -no-integrated-as on Darwin. It breaks
+ dnl building for the iOS simulator.
+ i?86-*-darwin* | x86_64-*-darwin*)
+ ;;
+ dnl Many older Clang versions don't support jmp short.
+ i?86-*-* | x86_64-*-*)
+ ASFLAGS="$ASFLAGS -no-integrated-as"
+ ;;
dnl Clang's assembler on Windows is not complete yet
dnl and cannot compile all .S files.
*-*-mingw*)
@@ -599,13 +607,14 @@ case "$objc_runtime" in
AC_MSG_ERROR([Exceptions not accepted by compiler!])
])
- AC_CHECK_FUNC($raise_exception, [], [
- AC_CHECK_LIB(c++, $raise_exception, [
- LIBS="-lc++ -lc++abi -lpthread $LIBS"
- ], [
- AC_MSG_ERROR([_Unwind_RaiseException missing!])
- ], [-lc++abi -lpthread])
- ])
+ AC_SEARCH_LIBS($raise_exception, [c++abi gcc_s gcc], [
+ dnl c++abi requires pthread on OpenBSD
+ AS_IF([test x"$ac_lib" = x"c++abi"], [
+ LIBS="$LIBS -lpthread"
+ ])
+ ], [
+ AC_MSG_ERROR([$raise_exception missing!])
+ ], [-lpthread])
AC_CHECK_FUNCS(_Unwind_GetDataRelBase _Unwind_GetTextRelBase)
;;
diff --git a/extra.mk.in b/extra.mk.in
index baa7bdfb..507daa1b 100644
--- a/extra.mk.in
+++ b/extra.mk.in
@@ -1,7 +1,6 @@
OBJFW_SHARED_LIB = @OBJFW_SHARED_LIB@
OBJFW_STATIC_LIB = @OBJFW_STATIC_LIB@
OBJFW_FRAMEWORK = @OBJFW_FRAMEWORK@
-# When changing: Be sure to also change these in the Xcode project!
OBJFW_LIB_MAJOR = 9
OBJFW_LIB_MINOR = 0
OBJFW_LIB_MAJOR_MINOR = ${OBJFW_LIB_MAJOR}.${OBJFW_LIB_MINOR}
diff --git a/src/Makefile b/src/Makefile
index 92c6ade7..2f566f28 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -2,7 +2,7 @@ include ../extra.mk
SUBDIRS = ${RUNTIME} exceptions ${ENCODINGS} forwarding
SUBDIRS_AFTER = ${BRIDGE}
-DISTCLEAN = objfw-defs.h
+DISTCLEAN = Info.plist objfw-defs.h
SHARED_LIB = ${OBJFW_SHARED_LIB}
STATIC_LIB = ${OBJFW_STATIC_LIB}
diff --git a/src/OFAdjacentArray.m b/src/OFAdjacentArray.m
index eb3b8fe7..7c368eed 100644
--- a/src/OFAdjacentArray.m
+++ b/src/OFAdjacentArray.m
@@ -343,7 +343,7 @@
return 0;
state->state = (unsigned long)count;
- state->itemsPtr = _array.items;
+ state->itemsPtr = (id *)_array.items;
state->mutationsPtr = (unsigned long *)self;
return (int)count;
diff --git a/src/OFApplication.m b/src/OFApplication.m
index 78ec2db9..09067dda 100644
--- a/src/OFApplication.m
+++ b/src/OFApplication.m
@@ -72,6 +72,7 @@ extern char **environ;
# undef asm
#endif
+OF_DIRECT_MEMBERS
@interface OFApplication ()
- (instancetype)of_init OF_METHOD_FAMILY(init);
- (void)of_setArgumentCount: (int *)argc
diff --git a/src/OFArray+Private.h b/src/OFArray+Private.h
index 52dd82a7..898820cb 100644
--- a/src/OFArray+Private.h
+++ b/src/OFArray+Private.h
@@ -19,6 +19,7 @@
OF_ASSUME_NONNULL_BEGIN
+OF_DIRECT_MEMBERS
@interface OFArrayEnumerator: OFEnumerator
{
OFArray *_array;
diff --git a/src/OFDNSResolver.h b/src/OFDNSResolver.h
index c33b3215..812ac0e3 100644
--- a/src/OFDNSResolver.h
+++ b/src/OFDNSResolver.h
@@ -65,7 +65,9 @@ typedef enum of_dns_resolver_error_t {
/*! The server does not have support for the requested query */
OF_DNS_RESOLVER_ERROR_SERVER_NOT_IMPLEMENTED,
/*! The server refused the query */
- OF_DNS_RESOLVER_ERROR_SERVER_REFUSED
+ OF_DNS_RESOLVER_ERROR_SERVER_REFUSED,
+ /*! There was no name server to query */
+ OF_DNS_RESOLVER_ERROR_NO_NAME_SERVER
} of_dns_resolver_error_t;
/*!
diff --git a/src/OFDNSResolver.m b/src/OFDNSResolver.m
index b7702d4d..64244e4a 100644
--- a/src/OFDNSResolver.m
+++ b/src/OFDNSResolver.m
@@ -65,6 +65,7 @@
- (void)of_contextTimedOut: (OFDNSResolverContext *)context;
@end
+OF_DIRECT_MEMBERS
@interface OFDNSResolverContext: OFObject
{
@public
@@ -819,6 +820,17 @@ parseSection(const unsigned char *buffer, size_t length, size_t *i,
if (query.domainName.UTF8StringLength > 253)
@throw [OFOutOfRangeException exception];
+ if (_settings->_nameServers.count == 0) {
+ id exception = [OFDNSQueryFailedException
+ exceptionWithQuery: query
+ error: OF_DNS_RESOLVER_ERROR_NO_NAME_SERVER];
+ [delegate resolver: self
+ didPerformQuery: query
+ response: nil
+ exception: exception];
+ return;
+ }
+
context = [[[OFDNSResolverContext alloc]
initWithQuery: query
ID: ID
@@ -880,12 +892,10 @@ parseSection(const unsigned char *buffer, size_t length, size_t *i,
exceptionWithQuery: context->_query
error: OF_DNS_RESOLVER_ERROR_TIMEOUT];
- if ([context->_delegate respondsToSelector:
- @selector(resolver:didPerformQuery:response:exception:)])
- [context->_delegate resolver: self
- didPerformQuery: context->_query
- response: nil
- exception: exception];
+ [context->_delegate resolver: self
+ didPerformQuery: context->_query
+ response: nil
+ exception: exception];
}
- (bool)of_handleResponseBuffer: (unsigned char *)buffer
@@ -1041,12 +1051,10 @@ parseSection(const unsigned char *buffer, size_t length, size_t *i,
if (exception != nil)
response = nil;
- if ([context->_delegate respondsToSelector:
- @selector(resolver:didPerformQuery:response:exception:)])
- [context->_delegate resolver: self
- didPerformQuery: context->_query
- response: response
- exception: exception];
+ [context->_delegate resolver: self
+ didPerformQuery: context->_query
+ response: response
+ exception: exception];
return false;
}
@@ -1275,12 +1283,10 @@ done:
exceptionWithQuery: context->_query
error: OF_DNS_RESOLVER_ERROR_CANCELED];
- if ([context->_delegate respondsToSelector:
- @selector(resolver:didPerformQuery:response:exception:)])
- [context->_delegate resolver: self
- didPerformQuery: context->_query
- response: nil
- exception: exception];
+ [context->_delegate resolver: self
+ didPerformQuery: context->_query
+ response: nil
+ exception: exception];
}
[_queries removeAllObjects];
diff --git a/src/OFData+CryptoHashing.m b/src/OFData+CryptoHashing.m
index 9273799c..1f87ae84 100644
--- a/src/OFData+CryptoHashing.m
+++ b/src/OFData+CryptoHashing.m
@@ -31,7 +31,7 @@
int _OFData_CryptoHashing_reference;
@implementation OFData (CryptoHashing)
-- (OFString *)of_cryptoHashWithClass: (Class <OFCryptoHash>)class
+- (OFString *)of_cryptoHashWithClass: (Class <OFCryptoHash>)class OF_DIRECT
{
void *pool = objc_autoreleasePoolPush();
id <OFCryptoHash> hash =
diff --git a/src/OFDictionary.m b/src/OFDictionary.m
index 5693bb5f..3d788e8c 100644
--- a/src/OFDictionary.m
+++ b/src/OFDictionary.m
@@ -48,6 +48,7 @@ static OFCharacterSet *URLQueryPartAllowedCharacterSet = nil;
@interface OFDictionaryPlaceholder: OFDictionary
@end
+OF_DIRECT_MEMBERS
@interface OFDictionaryObjectEnumerator: OFEnumerator
{
OFDictionary *_dictionary;
@@ -57,6 +58,7 @@ static OFCharacterSet *URLQueryPartAllowedCharacterSet = nil;
- (instancetype)initWithDictionary: (OFDictionary *)dictionary;
@end
+OF_DIRECT_MEMBERS
@interface OFURLQueryPartAllowedCharacterSet: OFCharacterSet
+ (OFCharacterSet *)URLQueryPartAllowedCharacterSet;
@end
@@ -224,7 +226,8 @@ static OFCharacterSet *URLQueryPartAllowedCharacterSet = nil;
+ (instancetype)dictionaryWithDictionary: (OFDictionary *)dictionary
{
- return [[[self alloc] initWithDictionary: dictionary] autorelease];
+ return [[(OFDictionary *)[self alloc]
+ initWithDictionary: dictionary] autorelease];
}
+ (instancetype)dictionaryWithObject: (id)object
diff --git a/src/OFEnumerator.h b/src/OFEnumerator.h
index 31eb7968..355f99f5 100644
--- a/src/OFEnumerator.h
+++ b/src/OFEnumerator.h
@@ -54,7 +54,7 @@ typedef struct {
/*! Arbitrary state information for the enumeration */
unsigned long state;
/*! Pointer to a C array of objects to return */
- id const __unsafe_unretained _Nullable *_Nullable itemsPtr;
+ id __unsafe_unretained _Nullable *_Nullable itemsPtr;
/*! Arbitrary state information to detect mutations */
unsigned long *_Nullable mutationsPtr;
/*! Additional arbitrary state information */
diff --git a/src/OFEpollKernelEventObserver.m b/src/OFEpollKernelEventObserver.m
index ec1c24b4..46881a97 100644
--- a/src/OFEpollKernelEventObserver.m
+++ b/src/OFEpollKernelEventObserver.m
@@ -92,7 +92,7 @@ static const of_map_table_functions_t mapFunctions = { NULL };
- (void)of_addObject: (id)object
fileDescriptor: (int)fd
- events: (int)addEvents
+ events: (int)addEvents OF_DIRECT
{
struct epoll_event event;
intptr_t events;
@@ -115,7 +115,7 @@ static const of_map_table_functions_t mapFunctions = { NULL };
- (void)of_removeObject: (id)object
fileDescriptor: (int)fd
- events: (int)removeEvents
+ events: (int)removeEvents OF_DIRECT
{
intptr_t events;
diff --git a/src/OFFileURLHandler.h b/src/OFFileURLHandler.h
index f433a9cb..bbb3e97e 100644
--- a/src/OFFileURLHandler.h
+++ b/src/OFFileURLHandler.h
@@ -20,7 +20,7 @@
OF_ASSUME_NONNULL_BEGIN
@interface OFFileURLHandler: OFURLHandler
-+ (bool)of_directoryExistsAtPath: (OFString *)path;
++ (bool)of_directoryExistsAtPath: (OFString *)path OF_DIRECT;
@end
OF_ASSUME_NONNULL_END
diff --git a/src/OFFileURLHandler.m b/src/OFFileURLHandler.m
index 476ddfb2..757fae2d 100644
--- a/src/OFFileURLHandler.m
+++ b/src/OFFileURLHandler.m
@@ -18,15 +18,21 @@
#include "config.h"
#include <errno.h>
+#include <math.h>
#ifdef HAVE_DIRENT_H
# include <dirent.h>
#endif
#include "unistd_wrapper.h"
+#import "platform.h"
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
+#include <sys/time.h>
+#ifdef OF_WINDOWS
+# include <utime.h>
+#endif
#ifdef HAVE_PWD_H
# include <pwd.h>
@@ -109,6 +115,7 @@ static OFMutex *readdirMutex;
#endif
#ifdef OF_WINDOWS
+static int (*func__wutime64)(const wchar_t *, struct __utimbuf64 *);
static WINAPI BOOLEAN (*func_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD);
static WINAPI BOOLEAN (*func_CreateHardLinkW)(LPCWSTR, LPCWSTR,
LPSECURITY_ATTRIBUTES);
@@ -146,6 +153,50 @@ setErrno(void)
}
#endif
+#ifdef OF_AMIGAOS
+static void
+setErrno(void)
+{
+ switch (IoErr()) {
+ case ERROR_DELETE_PROTECTED:
+ case ERROR_READ_PROTECTED:
+ case ERROR_WRITE_PROTECTED:
+ errno = EACCES;
+ break;
+ case ERROR_DISK_NOT_VALIDATED:
+ case ERROR_OBJECT_IN_USE:
+ errno = EBUSY;
+ break;
+ case ERROR_OBJECT_EXISTS:
+ errno = EEXIST;
+ break;
+ case ERROR_DIR_NOT_FOUND:
+ case ERROR_NO_MORE_ENTRIES:
+ case ERROR_OBJECT_NOT_FOUND:
+ errno = ENOENT;
+ break;
+ case ERROR_NO_FREE_STORE:
+ errno = ENOMEM;
+ break;
+ case ERROR_DISK_FULL:
+ errno = ENOSPC;
+ break;
+ case ERROR_DIRECTORY_NOT_EMPTY:
+ errno = ENOTEMPTY;
+ break;
+ case ERROR_DISK_WRITE_PROTECTED:
+ errno = EROFS;
+ break;
+ case ERROR_RENAME_ACROSS_DEVICES:
+ errno = EXDEV;
+ break;
+ default:
+ errno = 0;
+ break;
+ }
+}
+#endif
+
static int
of_stat(OFString *path, of_stat_t *buffer)
{
@@ -225,19 +276,7 @@ of_stat(OFString *path, of_stat_t *buffer)
if ((lock = Lock([path cStringWithEncoding: [OFLocale encoding]],
SHARED_LOCK)) == 0) {
- switch (IoErr()) {
- case ERROR_OBJECT_IN_USE:
- case ERROR_DISK_NOT_VALIDATED:
- errno = EBUSY;
- break;
- case ERROR_OBJECT_NOT_FOUND:
- errno = ENOENT;
- break;
- default:
- errno = 0;
- break;
- }
-
+ setErrno();
return -1;
}
@@ -513,6 +552,10 @@ setSymbolicLinkDestinationAttribute(of_mutable_file_attributes_t attributes,
#endif
#ifdef OF_WINDOWS
+ if ((module = LoadLibrary("msvcrt.dll")) != NULL)
+ func__wutime64 = (int (*)(const wchar_t *,
+ struct __utimbuf64 *))GetProcAddress(module, "_wutime64");
+
if ((module = LoadLibrary("kernel32.dll")) != NULL) {
func_CreateSymbolicLinkW =
(WINAPI BOOLEAN (*)(LPCWSTR, LPCWSTR, DWORD))
@@ -598,9 +641,123 @@ setSymbolicLinkDestinationAttribute(of_mutable_file_attributes_t attributes,
return ret;
}
+- (void)of_setLastAccessDate: (OFDate *)lastAccessDate
+ andModificationDate: (OFDate *)modificationDate
+ ofItemAtURL: (OFURL *)URL
+ attributes: (of_file_attributes_t)attributes OF_DIRECT
+{
+ OFString *path = URL.fileSystemRepresentation;
+ of_file_attribute_key_t attributeKey = (modificationDate != nil
+ ? of_file_attribute_key_modification_date
+ : of_file_attribute_key_last_access_date);
+
+ if (lastAccessDate == nil)
+ lastAccessDate = modificationDate;
+ if (modificationDate == nil)
+ modificationDate = lastAccessDate;
+
+#if defined(OF_WINDOWS)
+ if (func__wutime64 != NULL) {
+ struct __utimbuf64 times = {
+ .actime =
+ (__time64_t)lastAccessDate.timeIntervalSince1970,
+ .modtime =
+ (__time64_t)modificationDate.timeIntervalSince1970
+ };
+
+ if (func__wutime64([path UTF16String], &times) != 0)
+ @throw [OFSetItemAttributesFailedException
+ exceptionWithURL: URL
+ attributes: attributes
+ failedAttribute: attributeKey
+ errNo: errno];
+ } else {
+ struct _utimbuf times = {
+ .actime = (time_t)lastAccessDate.timeIntervalSince1970,
+ .modtime =
+ (time_t)modificationDate.timeIntervalSince1970
+ };
+ int status;
+
+ if ([OFSystemInfo isWindowsNT])
+ status = _wutime([path UTF16String], &times);
+ else
+ status = _utime(
+ [path cStringWithEncoding: [OFLocale encoding]],
+ &times);
+
+ if (status != 0)
+ @throw [OFSetItemAttributesFailedException
+ exceptionWithURL: URL
+ attributes: attributes
+ failedAttribute: attributeKey
+ errNo: errno];
+ }
+#elif defined(OF_AMIGAOS)
+ /* AmigaOS does not support access time. */
+ of_time_interval_t modificationTime =
+ modificationDate.timeIntervalSince1970;
+ struct Locale *locale;
+ struct DateStamp date;
+
+ modificationTime -= 252460800; /* 1978-01-01 */
+
+ if (modificationTime < 0)
+ @throw [OFOutOfRangeException exception];
+
+ locale = OpenLocale(NULL);
+ /*
+ * FIXME: This does not take DST into account. But unfortunately, there
+ * is no way to figure out if DST should be in effect for the
+ * timestamp.
+ */
+ modificationTime -= locale->loc_GMTOffset * 60.0;
+ CloseLocale(locale);
+
+ date.ds_Days = modificationTime / 86400;
+ date.ds_Minute = ((LONG)modificationTime % 86400) / 60;
+ date.ds_Tick = fmod(modificationTime, 60) * TICKS_PER_SECOND;
+
+ if (!SetFileDate([path cStringWithEncoding: [OFLocale encoding]],
+ &date) != 0) {
+ setErrno();
+
+ @throw [OFSetItemAttributesFailedException
+ exceptionWithURL: URL
+ attributes: attributes
+ failedAttribute: attributeKey
+ errNo: errno];
+ }
+#else
+ of_time_interval_t lastAccessTime =
+ lastAccessDate.timeIntervalSince1970;
+ of_time_interval_t modificationTime =
+ modificationDate.timeIntervalSince1970;
+ struct timeval times[2] = {
+ {
+ .tv_sec = (time_t)lastAccessTime,
+ .tv_usec =
+ (int)((lastAccessTime - times[0].tv_sec) * 1000)
+ },
+ {
+ .tv_sec = (time_t)modificationTime,
+ .tv_usec =
+ (int)((modificationTime - times[1].tv_sec) * 1000)
+ },
+ };
+
+ if (utimes([path cStringWithEncoding: [OFLocale encoding]], times) != 0)
+ @throw [OFSetItemAttributesFailedException
+ exceptionWithURL: URL
+ attributes: attributes
+ failedAttribute: attributeKey
+ errNo: errno];
+#endif
+}
+
- (void)of_setPOSIXPermissions: (OFNumber *)permissions
ofItemAtURL: (OFURL *)URL
- attributes: (of_file_attributes_t)attributes
+ attributes: (of_file_attributes_t)attributes OF_DIRECT
{
#ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS
uint16_t mode = permissions.uInt16Value & 0777;
@@ -630,7 +787,7 @@ setSymbolicLinkDestinationAttribute(of_mutable_file_attributes_t attributes,
andGroup: (OFString *)group
ofItemAtURL: (OFURL *)URL
attributeKey: (of_file_attribute_key_t)attributeKey
- attributes: (of_file_attributes_t)attributes
+ attributes: (of_file_attributes_t)attributes OF_DIRECT
{
#ifdef OF_FILE_MANAGER_SUPPORTS_OWNER
OFString *path = URL.fileSystemRepresentation;
@@ -699,6 +856,7 @@ setSymbolicLinkDestinationAttribute(of_mutable_file_attributes_t attributes,
OFEnumerator *objectEnumerator;
of_file_attribute_key_t key;
id object;
+ OFDate *lastAccessDate, *modificationDate;
if (URL == nil)
@throw [OFInvalidArgumentException exception];
@@ -711,7 +869,10 @@ setSymbolicLinkDestinationAttribute(of_mutable_file_attributes_t attributes,
while ((key = [keyEnumerator nextObject]) != nil &&
(object = [objectEnumerator nextObject]) != nil) {
- if ([key isEqual: of_file_attribute_key_posix_permissions])
+ if ([key isEqual: of_file_attribute_key_modification_date] ||
+ [key isEqual: of_file_attribute_key_last_access_date])
+ continue;
+ else if ([key isEqual: of_file_attribute_key_posix_permissions])
[self of_setPOSIXPermissions: object
ofItemAtURL: URL
attributes: attributes];
@@ -733,6 +894,17 @@ setSymbolicLinkDestinationAttribute(of_mutable_file_attributes_t attributes,
object: self];
}
+ lastAccessDate = [attributes
+ objectForKey: of_file_attribute_key_last_access_date];
+ modificationDate = [attributes
+ objectForKey: of_file_attribute_key_modification_date];
+
+ if (lastAccessDate != nil || modificationDate != nil)
+ [self of_setLastAccessDate: lastAccessDate
+ andModificationDate: modificationDate
+ ofItemAtURL: URL
+ attributes: attributes];
+
objc_autoreleasePoolPop(pool);
}
@@ -815,34 +987,11 @@ setSymbolicLinkDestinationAttribute(of_mutable_file_attributes_t attributes,
if ((lock = CreateDir(
[path cStringWithEncoding: [OFLocale encoding]])) == 0) {
- int errNo;
-
- switch (IoErr()) {
- case ERROR_NO_FREE_STORE:
- case ERROR_DISK_FULL:
- errNo = ENOSPC;
- break;
- case ERROR_OBJECT_IN_USE:
- case ERROR_DISK_NOT_VALIDATED:
- errNo = EBUSY;
- break;
- case ERROR_OBJECT_EXISTS:
- errNo = EEXIST;
- break;
- case ERROR_OBJECT_NOT_FOUND:
- errNo = ENOENT;
- break;
- case ERROR_DISK_WRITE_PROTECTED:
- errNo = EROFS;
- break;
- default:
- errNo = 0;
- break;
- }
+ setErrno();
@throw [OFCreateDirectoryFailedException
exceptionWithURL: URL
- errNo: errNo];
+ errNo: errno];
}
UnLock(lock);
@@ -967,24 +1116,11 @@ setSymbolicLinkDestinationAttribute(of_mutable_file_attributes_t attributes,
if ((lock = Lock([path cStringWithEncoding: encoding],
SHARED_LOCK)) == 0) {
- int errNo;
-
- switch (IoErr()) {
- case ERROR_OBJECT_IN_USE:
- case ERROR_DISK_NOT_VALIDATED:
- errNo = EBUSY;
- break;
- case ERROR_OBJECT_NOT_FOUND:
- errNo = ENOENT;
- break;
- default:
- errNo = 0;
- break;
- }
+ setErrno();
@throw [OFOpenItemFailedException exceptionWithURL: URL
mode: nil
- errNo: errNo];
+ errNo: errno];
}
@try {
@@ -1203,29 +1339,10 @@ setSymbolicLinkDestinationAttribute(of_mutable_file_attributes_t attributes,
#ifdef OF_AMIGAOS
if (!DeleteFile([path cStringWithEncoding: [OFLocale encoding]])) {
- int errNo;
-
- switch (IoErr()) {
- case ERROR_OBJECT_IN_USE:
- case ERROR_DISK_NOT_VALIDATED:
- errNo = EBUSY;
- break;
- case ERROR_OBJECT_NOT_FOUND:
- errNo = ENOENT;
- break;
- case ERROR_DISK_WRITE_PROTECTED:
- errNo = EROFS;
- break;
- case ERROR_DELETE_PROTECTED:
- errNo = EACCES;
- break;
- default:
- errNo = 0;
- break;
- }
+ setErrno();
@throw [OFRemoveItemFailedException exceptionWithURL: URL
- errNo: errNo];
+ errNo: errno];
}
#endif
@@ -1339,34 +1456,12 @@ setSymbolicLinkDestinationAttribute(of_mutable_file_attributes_t attributes,
cStringWithEncoding: encoding],
[destination.fileSystemRepresentation
cStringWithEncoding: encoding])) {
- int errNo;
-
- switch (IoErr()) {
- case ERROR_RENAME_ACROSS_DEVICES:
- errNo = EXDEV;
- break;
- case ERROR_OBJECT_IN_USE:
- case ERROR_DISK_NOT_VALIDATED:
- errNo = EBUSY;
- break;
- case ERROR_OBJECT_EXISTS:
- errNo = EEXIST;
- break;
- case ERROR_OBJECT_NOT_FOUND:
- errNo = ENOENT;
- break;
- case ERROR_DISK_WRITE_PROTECTED:
- errNo = EROFS;
- break;
- default:
- errNo = 0;
- break;
- }
+ setErrno();
@throw [OFMoveItemFailedException
exceptionWithSourceURL: source
destinationURL: destination
- errNo: errNo];
+ errNo: errno];
}
#else
int status;
diff --git a/src/OFGZIPStream.h b/src/OFGZIPStream.h
index c45c0f45..2cf2d7ff 100644
--- a/src/OFGZIPStream.h
+++ b/src/OFGZIPStream.h
@@ -40,7 +40,7 @@ OF_SUBCLASSING_RESTRICTED
OF_GZIP_STREAM_FLAGS,
OF_GZIP_STREAM_MODIFICATION_TIME,
OF_GZIP_STREAM_EXTRA_FLAGS,
- OF_GZIP_STREAM_OS,
+ OF_GZIP_STREAM_OPERATING_SYSTEM,
OF_GZIP_STREAM_EXTRA_LENGTH,
OF_GZIP_STREAM_EXTRA,
OF_GZIP_STREAM_NAME,
@@ -58,23 +58,23 @@ OF_SUBCLASSING_RESTRICTED
OF_GZIP_STREAM_FLAG_COMMENT = 0x10
} _flags;
uint8_t _extraFlags;
- enum of_gzip_stream_os {
- OF_GZIP_STREAM_OS_FAT = 0,
- OF_GZIP_STREAM_OS_AMIGA = 1,
- OF_GZIP_STREAM_OS_VMS = 2,
- OF_GZIP_STREAM_OS_UNIX = 3,
- OF_GZIP_STREAM_OS_VM_CMS = 4,
- OF_GZIP_STREAM_OS_ATARI_TOS = 5,
- OF_GZIP_STREAM_OS_HPFS = 6,
- OF_GZIP_STREAM_OS_MACINTOSH = 7,
- OF_GZIP_STREAM_OS_Z_SYSTEM = 8,
- OF_GZIP_STREAM_OS_CP_M = 9,
- OF_GZIP_STREAM_OS_TOPS_20 = 10,
- OF_GZIP_STREAM_OS_NTFS = 11,
- OF_GZIP_STREAM_OS_QDO = 12,
- OF_GZIP_STREAM_OS_ACORN_RISC_OS = 13,
- OF_GZIP_STREAM_OS_UNKNOWN = 255
- } _OS;
+ enum of_gzip_stream_operating_system {
+ OF_GZIP_STREAM_OPERATING_SYSTEM_FAT = 0,
+ OF_GZIP_STREAM_OPERATING_SYSTEM_AMIGA = 1,
+ OF_GZIP_STREAM_OPERATING_SYSTEM_VMS = 2,
+ OF_GZIP_STREAM_OPERATING_SYSTEM_UNIX = 3,
+ OF_GZIP_STREAM_OPERATING_SYSTEM_VM_CMS = 4,
+ OF_GZIP_STREAM_OPERATING_SYSTEM_ATARI_TOS = 5,
+ OF_GZIP_STREAM_OPERATING_SYSTEM_HPFS = 6,
+ OF_GZIP_STREAM_OPERATING_SYSTEM_MACINTOSH = 7,
+ OF_GZIP_STREAM_OPERATING_SYSTEM_Z_SYSTEM = 8,
+ OF_GZIP_STREAM_OPERATING_SYSTEM_CP_M = 9,
+ OF_GZIP_STREAM_OPERATING_SYSTEM_TOPS_20 = 10,
+ OF_GZIP_STREAM_OPERATING_SYSTEM_NTFS = 11,
+ OF_GZIP_STREAM_OPERATING_SYSTEM_QDO = 12,
+ OF_GZIP_STREAM_OPERATING_SYSTEM_ACORN_RISC_OS = 13,
+ OF_GZIP_STREAM_OPERATING_SYSTEM_UNKNOWN = 255
+ } _operatingSystemMadeOn;
size_t _bytesRead;
uint8_t _buffer[4];
OFDate *_Nullable _modificationDate;
@@ -83,6 +83,23 @@ OF_SUBCLASSING_RESTRICTED
}
/*!
+ * @brief The operating system on which the data was compressed.
+ *
+ * This property is only guaranteed to be available once @ref atEndOfStream is
+ * true.
+ */
+@property (readonly, nonatomic)
+ enum of_gzip_stream_operating_system operatingSystemMadeOn;
+
+/*!
+ * @brief The modification date of the original file.
+ *
+ * This property is only guaranteed to be available once @ref atEndOfStream is
+ * true.
+ */
+@property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFDate *modificationDate;
+
+/*!
* @brief Creates a new OFGZIPStream with the specified underlying stream.
*
* @param stream The underlying stream for the OFGZIPStream
diff --git a/src/OFGZIPStream.m b/src/OFGZIPStream.m
index 32b1b4cb..10deb26e 100644
--- a/src/OFGZIPStream.m
+++ b/src/OFGZIPStream.m
@@ -30,6 +30,9 @@
#import "OFTruncatedDataException.h"
@implementation OFGZIPStream
+@synthesize operatingSystemMadeOn = _operatingSystemMadeOn;
+@synthesize modificationDate = _modificationDate;
+
+ (instancetype)streamWithStream: (OFStream *)stream
mode: (OFString *)mode
{
@@ -54,6 +57,8 @@
object: nil];
_stream = [stream retain];
+ _operatingSystemMadeOn =
+ OF_GZIP_STREAM_OPERATING_SYSTEM_UNKNOWN;
_CRC32 = ~0;
} @catch (id e) {
[self release];
@@ -142,12 +147,12 @@
_extraFlags = byte;
_state++;
break;
- case OF_GZIP_STREAM_OS:
+ case OF_GZIP_STREAM_OPERATING_SYSTEM:
if ([_stream readIntoBuffer: &byte
length: 1] < 1)
return 0;
- _OS = byte;
+ _operatingSystemMadeOn = byte;
_state++;
break;
case OF_GZIP_STREAM_EXTRA_LENGTH:
diff --git a/src/OFHTTPClient.m b/src/OFHTTPClient.m
index 5261ecd9..cd720322 100644
--- a/src/OFHTTPClient.m
+++ b/src/OFHTTPClient.m
@@ -53,6 +53,7 @@
#define REDIRECTS_DEFAULT 10
+OF_DIRECT_MEMBERS
@interface OFHTTPClientRequestHandler: OFObject <OFTCPSocketDelegate>
{
@public
@@ -72,6 +73,7 @@
- (void)closeAndReconnect;
@end
+OF_DIRECT_MEMBERS
@interface OFHTTPClientRequestBodyStream: OFStream <OFReadyForWritingObserving>
{
OFHTTPClientRequestHandler *_handler;
@@ -85,6 +87,7 @@
socket: (OFTCPSocket *)sock;
@end
+OF_DIRECT_MEMBERS
@interface OFHTTPClientResponse: OFHTTPResponse <OFReadyForReadingObserving>
{
OFTCPSocket *_socket;
@@ -98,6 +101,7 @@
- (instancetype)initWithSocket: (OFTCPSocket *)sock;
@end
+OF_DIRECT_MEMBERS
@interface OFHTTPClientSyncPerformer: OFObject <OFHTTPClientDelegate>
{
OFHTTPClient *_client;
diff --git a/src/OFHTTPResponse.h b/src/OFHTTPResponse.h
index 4f7387be..b3e92fda 100644
--- a/src/OFHTTPResponse.h
+++ b/src/OFHTTPResponse.h
@@ -74,6 +74,12 @@ OF_ASSUME_NONNULL_BEGIN
#ifdef __cplusplus
extern "C" {
#endif
+/*!
+ * @brief Returns a description string for the specified HTTP status code.
+ *
+ * @param code The HTTP status code to return a description string for
+ * @return A description string for the specified HTTP status code
+ */
extern OFString *_Nonnull of_http_status_code_to_string(short code);
#ifdef __cplusplus
}
diff --git a/src/OFHTTPServer.m b/src/OFHTTPServer.m
index 042657a1..3d53d238 100644
--- a/src/OFHTTPServer.m
+++ b/src/OFHTTPServer.m
@@ -57,6 +57,7 @@
@interface OFHTTPServer () <OFTCPSocketDelegate>
@end
+OF_DIRECT_MEMBERS
@interface OFHTTPServerResponse: OFHTTPResponse <OFReadyForWritingObserving>
{
OFStreamSocket *_socket;
@@ -70,6 +71,7 @@
request: (OFHTTPRequest *)request;
@end
+OF_DIRECT_MEMBERS
@interface OFHTTPServerConnection: OFObject <OFTCPSocketDelegate>
{
@public
@@ -98,6 +100,7 @@
- (void)createResponse;
@end
+OF_DIRECT_MEMBERS
@interface OFHTTPServerRequestBodyStream: OFStream <OFReadyForReadingObserving>
{
OFStreamSocket *_socket;
@@ -112,6 +115,7 @@
@end
#ifdef OF_HAVE_THREADS
+OF_DIRECT_MEMBERS
@interface OFHTTPServerThread: OFThread
- (void)stop;
@end
diff --git a/src/OFINICategory+Private.h b/src/OFINICategory+Private.h
index 7aedca48..b9fd8817 100644
--- a/src/OFINICategory+Private.h
+++ b/src/OFINICategory+Private.h
@@ -22,6 +22,7 @@ OF_ASSUME_NONNULL_BEGIN
@class OFStream;
+OF_DIRECT_MEMBERS
@interface OFINICategory ()
- (instancetype)of_initWithName: (OFString *)name OF_METHOD_FAMILY(init);
- (void)of_parseLine: (OFString *)line;
diff --git a/src/OFINICategory.m b/src/OFINICategory.m
index bdf109ab..320fe154 100644
--- a/src/OFINICategory.m
+++ b/src/OFINICategory.m
@@ -122,7 +122,7 @@ unescapeString(OFString *string)
@implementation OFINICategory
@synthesize name = _name;
-- (instancetype)of_initWithName: (OFString *)name
+- (instancetype)of_initWithName: (OFString *)name OF_DIRECT
{
self = [super init];
diff --git a/src/OFINIFile.m b/src/OFINIFile.m
index c3ceb583..662f269e 100644
--- a/src/OFINIFile.m
+++ b/src/OFINIFile.m
@@ -29,6 +29,7 @@
#import "OFInvalidFormatException.h"
#import "OFOpenItemFailedException.h"
+OF_DIRECT_MEMBERS
@interface OFINIFile ()
- (void)of_parseFile: (OFString *)path
encoding: (of_string_encoding_t)encoding;
diff --git a/src/OFINIFileSettings.m b/src/OFINIFileSettings.m
index 48861388..142fde1e 100644
--- a/src/OFINIFileSettings.m
+++ b/src/OFINIFileSettings.m
@@ -56,7 +56,7 @@
- (void)of_getCategory: (OFString **)category
andKey: (OFString **)key
- forPath: (OFString *)path
+ forPath: (OFString *)path OF_DIRECT
{
size_t pos = [path rangeOfString: @"."
options: OF_STRING_SEARCH_BACKWARDS].location;
diff --git a/src/OFKernelEventObserver.m b/src/OFKernelEventObserver.m
index 9ab39ee8..7f9a11b3 100644
--- a/src/OFKernelEventObserver.m
+++ b/src/OFKernelEventObserver.m
@@ -221,7 +221,7 @@ enum {
if ([object isKindOfClass: [OFStream class]] &&
[object hasDataInReadBuffer] &&
- ![object of_isWaitingForDelimiter]) {
+ ![(OFStream *)object of_isWaitingForDelimiter]) {
if ([_delegate respondsToSelector:
@selector(objectIsReadyForReading:)])
[_delegate objectIsReadyForReading: object];
diff --git a/src/OFLHAArchive.m b/src/OFLHAArchive.m
index 6be0f125..33906534 100644
--- a/src/OFLHAArchive.m
+++ b/src/OFLHAArchive.m
@@ -38,6 +38,7 @@
#import "OFTruncatedDataException.h"
#import "OFWriteFailedException.h"
+OF_DIRECT_MEMBERS
@interface OFLHAArchiveFileReadStream: OFStream <OFReadyForReadingObserving>
{
OFStream *_stream, *_decompressedStream;
@@ -52,6 +53,7 @@
- (void)of_skip;
@end
+OF_DIRECT_MEMBERS
@interface OFLHAArchiveFileWriteStream: OFStream <OFReadyForWritingObserving>
{
OFMutableLHAArchiveEntry *_entry;
diff --git a/src/OFLHAArchiveEntry+Private.h b/src/OFLHAArchiveEntry+Private.h
index f7ed5584..ab705daa 100644
--- a/src/OFLHAArchiveEntry+Private.h
+++ b/src/OFLHAArchiveEntry+Private.h
@@ -19,6 +19,7 @@
OF_ASSUME_NONNULL_BEGIN
+OF_DIRECT_MEMBERS
@interface OFLHAArchiveEntry ()
- (instancetype)of_initWithHeader: (char [_Nonnull 21])header
stream: (OFStream *)stream
diff --git a/src/OFLHADecompressingStream.h b/src/OFLHADecompressingStream.h
index a3f626e3..6588ad40 100644
--- a/src/OFLHADecompressingStream.h
+++ b/src/OFLHADecompressingStream.h
@@ -21,6 +21,7 @@ OF_ASSUME_NONNULL_BEGIN
#define OF_LHA_DECOMPRESSING_STREAM_BUFFER_SIZE 4096
+OF_DIRECT_MEMBERS
@interface OFLHADecompressingStream: OFStream
{
OFStream *_stream;
diff --git a/src/OFList.m b/src/OFList.m
index 0ebef382..fe3fa712 100644
--- a/src/OFList.m
+++ b/src/OFList.m
@@ -28,6 +28,7 @@
#import "OFEnumerationMutationException.h"
#import "OFInvalidArgumentException.h"
+OF_DIRECT_MEMBERS
@interface OFListEnumerator: OFEnumerator
{
OFList *_list;
diff --git a/src/OFMD5Hash.m b/src/OFMD5Hash.m
index c775d17b..5b6d08fb 100644
--- a/src/OFMD5Hash.m
+++ b/src/OFMD5Hash.m
@@ -28,6 +28,7 @@
#define DIGEST_SIZE 16
#define BLOCK_SIZE 64
+OF_DIRECT_MEMBERS
@interface OFMD5Hash ()
- (void)of_resetState;
@end
diff --git a/src/OFMapTable+Private.h b/src/OFMapTable+Private.h
index 6b16c5f2..b2f91ced 100644
--- a/src/OFMapTable+Private.h
+++ b/src/OFMapTable+Private.h
@@ -19,6 +19,7 @@
OF_ASSUME_NONNULL_BEGIN
+OF_DIRECT_MEMBERS
@interface OFMapTableEnumeratorWrapper: OFEnumerator
{
OFMapTableEnumerator *_enumerator;
diff --git a/src/OFMapTable.m b/src/OFMapTable.m
index f1468706..c7ddda90 100644
--- a/src/OFMapTable.m
+++ b/src/OFMapTable.m
@@ -61,12 +61,14 @@ defaultEqual(void *object1, void *object2)
return (object1 == object2);
}
+OF_DIRECT_MEMBERS
@interface OFMapTable ()
- (void)of_setObject: (void *)object
forKey: (void *)key
hash: (uint32_t)hash;
@end
+OF_DIRECT_MEMBERS
@interface OFMapTableEnumerator ()
- (instancetype)of_initWithMapTable: (OFMapTable *)mapTable
buckets: (struct of_map_table_bucket **)buckets
@@ -293,7 +295,7 @@ defaultEqual(void *object1, void *object2)
return NULL;
}
-- (void)of_resizeForCount: (uint32_t)count
+- (void)of_resizeForCount: (uint32_t)count OF_DIRECT
{
uint32_t fullness, capacity;
struct of_map_table_bucket **buckets;
diff --git a/src/OFMutableAdjacentArray.m b/src/OFMutableAdjacentArray.m
index 1c901977..9d72e9a1 100644
--- a/src/OFMutableAdjacentArray.m
+++ b/src/OFMutableAdjacentArray.m
@@ -328,7 +328,7 @@
return 0;
state->state = (unsigned long)count;
- state->itemsPtr = _array.items;
+ state->itemsPtr = (id *)_array.items;
state->mutationsPtr = &_mutations;
return (int)count;
diff --git a/src/OFMutableString.m b/src/OFMutableString.m
index ffa2bffd..e7ca6c1d 100644
--- a/src/OFMutableString.m
+++ b/src/OFMutableString.m
@@ -235,7 +235,7 @@ static struct {
- (void)of_convertWithWordStartTable: (const of_unichar_t *const [])startTable
wordMiddleTable: (const of_unichar_t *const [])middleTable
wordStartTableSize: (size_t)startTableSize
- wordMiddleTableSize: (size_t)middleTableSize
+ wordMiddleTableSize: (size_t)middleTableSize OF_DIRECT
{
void *pool = objc_autoreleasePoolPush();
const of_unichar_t *characters = self.characters;
@@ -267,6 +267,7 @@ static struct {
#else
- (void)of_convertWithWordStartFunction: (char (*)(char))startFunction
wordMiddleFunction: (char (*)(char))middleFunction
+ OF_DIRECT
{
void *pool = objc_autoreleasePoolPush();
const of_unichar_t *characters = self.characters;
diff --git a/src/OFMutableUTF8String.m b/src/OFMutableUTF8String.m
index b5f29b90..fa28b9da 100644
--- a/src/OFMutableUTF8String.m
+++ b/src/OFMutableUTF8String.m
@@ -73,7 +73,7 @@
- (void)of_convertWithWordStartTable: (const of_unichar_t *const[])startTable
wordMiddleTable: (const of_unichar_t *const[])middleTable
wordStartTableSize: (size_t)startTableSize
- wordMiddleTableSize: (size_t)middleTableSize
+ wordMiddleTableSize: (size_t)middleTableSize OF_DIRECT
{
of_unichar_t *unicodeString;
size_t unicodeLen, newCStringLength;
diff --git a/src/OFPollKernelEventObserver.m b/src/OFPollKernelEventObserver.m
index 399d94ec..339568ac 100644
--- a/src/OFPollKernelEventObserver.m
+++ b/src/OFPollKernelEventObserver.m
@@ -71,7 +71,7 @@
- (void)of_addObject: (id)object
fileDescriptor: (int)fd
- events: (short)events
+ events: (short)events OF_DIRECT
{
struct pollfd *FDs;
size_t count;
@@ -110,7 +110,7 @@
- (void)of_removeObject: (id)object
fileDescriptor: (int)fd
- events: (short)events
+ events: (short)events OF_DIRECT
{
struct pollfd *FDs;
size_t nFDs;
diff --git a/src/OFRIPEMD160Hash.m b/src/OFRIPEMD160Hash.m
index 43cb8095..cac87bc1 100644
--- a/src/OFRIPEMD160Hash.m
+++ b/src/OFRIPEMD160Hash.m
@@ -28,6 +28,7 @@
#define DIGEST_SIZE 20
#define BLOCK_SIZE 64
+OF_DIRECT_MEMBERS
@interface OFRIPEMD160Hash ()
- (void)of_resetState;
@end
diff --git a/src/OFRunLoop+Private.h b/src/OFRunLoop+Private.h
index 61cb7bf9..87bea03b 100644
--- a/src/OFRunLoop+Private.h
+++ b/src/OFRunLoop+Private.h
@@ -33,6 +33,7 @@ OF_ASSUME_NONNULL_BEGIN
@end
#endif
+OF_DIRECT_MEMBERS
@interface OFRunLoop ()
+ (void)of_setMainRunLoop: (OFRunLoop *)runLoop;
#ifdef OF_HAVE_SOCKETS
diff --git a/src/OFRunLoop.h b/src/OFRunLoop.h
index 96db093c..059f85a0 100644
--- a/src/OFRunLoop.h
+++ b/src/OFRunLoop.h
@@ -49,7 +49,7 @@ extern "C" {
/*!
* @brief The default mode for an OFRunLoop.
*/
-extern of_run_loop_mode_t of_run_loop_mode_default;
+extern const of_run_loop_mode_t of_run_loop_mode_default;
#ifdef __cplusplus
}
#endif
diff --git a/src/OFRunLoop.m b/src/OFRunLoop.m
index 1a982bf1..1067afc1 100644
--- a/src/OFRunLoop.m
+++ b/src/OFRunLoop.m
@@ -45,7 +45,7 @@
#import "OFObserveFailedException.h"
-of_run_loop_mode_t of_run_loop_mode_default = @"of_run_loop_mode_default";
+const of_run_loop_mode_t of_run_loop_mode_default = @"of_run_loop_mode_default";
static OFRunLoop *mainRunLoop = nil;
@interface OFRunLoopState: OFObject
@@ -78,6 +78,7 @@ static OFRunLoop *mainRunLoop = nil;
}
@end
+OF_DIRECT_MEMBERS
@interface OFRunLoop ()
- (OFRunLoopState *)of_stateForMode: (of_run_loop_mode_t)mode
create: (bool)create;
diff --git a/src/OFSHA1Hash.m b/src/OFSHA1Hash.m
index c8e3fc15..5861abfc 100644
--- a/src/OFSHA1Hash.m
+++ b/src/OFSHA1Hash.m
@@ -28,6 +28,7 @@
#define DIGEST_SIZE 20
#define BLOCK_SIZE 64
+OF_DIRECT_MEMBERS
@interface OFSHA1Hash ()
- (void)of_resetState;
@end
diff --git a/src/OFSPXSocket.m b/src/OFSPXSocket.m
index 80721608..c377d6e9 100644
--- a/src/OFSPXSocket.m
+++ b/src/OFSPXSocket.m
@@ -45,6 +45,7 @@
- (void)of_closeSocket;
@end
+OF_DIRECT_MEMBERS
@interface OFSPXSocketAsyncConnectDelegate: OFObject <OFRunLoopConnectDelegate>
{
OFSPXSocket *_socket;
diff --git a/src/OFSPXStreamSocket.m b/src/OFSPXStreamSocket.m
index 1df82113..91c1a9d8 100644
--- a/src/OFSPXStreamSocket.m
+++ b/src/OFSPXStreamSocket.m
@@ -45,6 +45,7 @@
- (void)of_closeSocket;
@end
+OF_DIRECT_MEMBERS
@interface OFSPXStreamSocketAsyncConnectDelegate: OFObject
<OFRunLoopConnectDelegate>
{
diff --git a/src/OFSelectKernelEventObserver.m b/src/OFSelectKernelEventObserver.m
index e8297a2f..a8a96b50 100644
--- a/src/OFSelectKernelEventObserver.m
+++ b/src/OFSelectKernelEventObserver.m
@@ -228,8 +228,9 @@
#endif
if (events < 0)
- @throw [OFObserveFailedException exceptionWithObserver: self
- errNo: errno];
+ @throw [OFObserveFailedException
+ exceptionWithObserver: self
+ errNo: of_socket_errno()];
#ifdef OF_AMIGAOS
if (execSignalMask != 0 &&
diff --git a/src/OFStdIOStream+Private.h b/src/OFStdIOStream+Private.h
index 8c4c7052..c94d29fa 100644
--- a/src/OFStdIOStream+Private.h
+++ b/src/OFStdIOStream+Private.h
@@ -19,6 +19,7 @@
OF_ASSUME_NONNULL_BEGIN
+OF_DIRECT_MEMBERS
@interface OFStdIOStream ()
#ifndef OF_AMIGAOS
- (instancetype)of_initWithFileDescriptor: (int)fd OF_METHOD_FAMILY(init);
diff --git a/src/OFStdIOStream.m b/src/OFStdIOStream.m
index f1a9aee6..e360dec3 100644
--- a/src/OFStdIOStream.m
+++ b/src/OFStdIOStream.m
@@ -44,9 +44,14 @@
#import "OFReadFailedException.h"
#import "OFWriteFailedException.h"
+#ifdef OF_IOS
+# undef HAVE_ISATTY
+#endif
+
#ifdef OF_AMIGAOS
# include <proto/exec.h>
# include <proto/dos.h>
+# undef HAVE_ISATTY
#endif
/* References for static linking */
@@ -98,7 +103,7 @@ of_log(OFConstantString *format, ...)
objc_autoreleasePoolPop(pool);
}
-#if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS)
+#ifdef HAVE_ISATTY
static int
colorToANSI(OFColor *color)
{
@@ -388,7 +393,7 @@ colorToANSI(OFColor *color)
- (bool)hasTerminal
{
-#if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS)
+#ifdef HAVE_ISATTY
return isatty(_fd);
#else
return false;
@@ -425,7 +430,7 @@ colorToANSI(OFColor *color)
- (void)setForegroundColor: (OFColor *)color
{
-#if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS)
+#ifdef HAVE_ISATTY
int code;
if (!isatty(_fd))
@@ -440,7 +445,7 @@ colorToANSI(OFColor *color)
- (void)setBackgroundColor: (OFColor *)color
{
-#if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS)
+#ifdef HAVE_ISATTY
int code;
if (!isatty(_fd))
@@ -455,7 +460,7 @@ colorToANSI(OFColor *color)
- (void)reset
{
-#if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS)
+#ifdef HAVE_ISATTY
if (!isatty(_fd))
return;
@@ -465,7 +470,7 @@ colorToANSI(OFColor *color)
- (void)clear
{
-#if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS)
+#ifdef HAVE_ISATTY
if (!isatty(_fd))
return;
@@ -475,7 +480,7 @@ colorToANSI(OFColor *color)
- (void)eraseLine
{
-#if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS)
+#ifdef HAVE_ISATTY
if (!isatty(_fd))
return;
@@ -485,7 +490,7 @@ colorToANSI(OFColor *color)
- (void)setCursorColumn: (unsigned int)column
{
-#if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS)
+#ifdef HAVE_ISATTY
if (!isatty(_fd))
return;
@@ -498,7 +503,7 @@ colorToANSI(OFColor *color)
if (position.x < 0 || position.y < 0)
@throw [OFInvalidArgumentException exception];
-#if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS)
+#ifdef HAVE_ISATTY
if (!isatty(_fd))
return;
@@ -509,7 +514,7 @@ colorToANSI(OFColor *color)
- (void)setRelativeCursorPosition: (of_point_t)position
{
-#if defined(HAVE_ISATTY) && !defined(OF_AMIGAOS)
+#ifdef HAVE_ISATTY
if (!isatty(_fd))
return;
diff --git a/src/OFStream+Private.h b/src/OFStream+Private.h
index ea788e59..aeb85d22 100644
--- a/src/OFStream+Private.h
+++ b/src/OFStream+Private.h
@@ -19,6 +19,7 @@
OF_ASSUME_NONNULL_BEGIN
+OF_DIRECT_MEMBERS
@interface OFStream ()
@property (readonly, nonatomic, getter=of_isWaitingForDelimiter)
bool of_waitingForDelimiter;
diff --git a/src/OFString.m b/src/OFString.m
index cc8f9921..1e10ccde 100644
--- a/src/OFString.m
+++ b/src/OFString.m
@@ -88,9 +88,9 @@ static locale_t cLocale;
- (size_t)of_getCString: (char *)cString
maxLength: (size_t)maxLength
encoding: (of_string_encoding_t)encoding
- lossy: (bool)lossy;
+ lossy: (bool)lossy OF_DIRECT;
- (const char *)of_cStringWithEncoding: (of_string_encoding_t)encoding
- lossy: (bool)lossy;
+ lossy: (bool)lossy OF_DIRECT;
- (OFString *)of_JSONRepresentationWithOptions: (int)options
depth: (size_t)depth;
@end
@@ -376,7 +376,7 @@ decomposedString(OFString *self, const char *const *const *table, size_t size)
- (instancetype)initWithUTF8String: (const char *)UTF8String
{
- id string;
+ OFUTF8String *string;
size_t length;
void *storage;
@@ -391,7 +391,7 @@ decomposedString(OFString *self, const char *const *const *table, size_t size)
- (instancetype)initWithUTF8String: (const char *)UTF8String
length: (size_t)UTF8StringLength
{
- id string;
+ OFUTF8String *string;
void *storage;
string = of_alloc_object([OFUTF8String class], UTF8StringLength + 1, 1,
@@ -424,7 +424,7 @@ decomposedString(OFString *self, const char *const *const *table, size_t size)
encoding: (of_string_encoding_t)encoding
{
if (encoding == OF_STRING_ENCODING_UTF_8) {
- id string;
+ OFUTF8String *string;
size_t length;
void *storage;
@@ -446,7 +446,7 @@ decomposedString(OFString *self, const char *const *const *table, size_t size)
length: (size_t)cStringLength
{
if (encoding == OF_STRING_ENCODING_UTF_8) {
- id string;
+ OFUTF8String *string;
void *storage;
string = of_alloc_object([OFUTF8String class],
diff --git a/src/OFTarArchive.m b/src/OFTarArchive.m
index 03bd6d66..a88e8920 100644
--- a/src/OFTarArchive.m
+++ b/src/OFTarArchive.m
@@ -34,6 +34,7 @@
#import "OFTruncatedDataException.h"
#import "OFWriteFailedException.h"
+OF_DIRECT_MEMBERS
@interface OFTarArchiveFileReadStream: OFStream <OFReadyForReadingObserving>
{
OFTarArchiveEntry *_entry;
@@ -47,6 +48,7 @@
- (void)of_skip;
@end
+OF_DIRECT_MEMBERS
@interface OFTarArchiveFileWriteStream: OFStream <OFReadyForWritingObserving>
{
OFTarArchiveEntry *_entry;
diff --git a/src/OFTarArchiveEntry+Private.h b/src/OFTarArchiveEntry+Private.h
index 84bdd7fd..1e9738fd 100644
--- a/src/OFTarArchiveEntry+Private.h
+++ b/src/OFTarArchiveEntry+Private.h
@@ -22,6 +22,7 @@ OF_ASSUME_NONNULL_BEGIN
@class OFStream;
+OF_DIRECT_MEMBERS
@interface OFTarArchiveEntry ()
- (instancetype)of_initWithHeader: (unsigned char [_Nonnull 512])header
encoding: (of_string_encoding_t)encoding
diff --git a/src/OFThread+Private.h b/src/OFThread+Private.h
index df6abbec..5631882c 100644
--- a/src/OFThread+Private.h
+++ b/src/OFThread+Private.h
@@ -20,6 +20,7 @@
OF_ASSUME_NONNULL_BEGIN
#ifdef OF_HAVE_THREADS
+OF_DIRECT_MEMBERS
@interface OFThread ()
+ (void)of_createMainThread;
@end
diff --git a/src/OFTimer+Private.h b/src/OFTimer+Private.h
index cf8efff0..6e0ba6ef 100644
--- a/src/OFTimer+Private.h
+++ b/src/OFTimer+Private.h
@@ -19,6 +19,7 @@
OF_ASSUME_NONNULL_BEGIN
+OF_DIRECT_MEMBERS
@interface OFTimer ()
- (void)of_setInRunLoop: (nullable OFRunLoop *)runLoop
mode: (nullable of_run_loop_mode_t)mode;
diff --git a/src/OFTimer.m b/src/OFTimer.m
index 615ba50d..c0c5c464 100644
--- a/src/OFTimer.m
+++ b/src/OFTimer.m
@@ -329,7 +329,8 @@
object: (id)object3
object: (id)object4
arguments: (uint8_t)arguments
- repeats: (bool)repeats OF_METHOD_FAMILY(init)
+ repeats: (bool)repeats
+ OF_METHOD_FAMILY(init) OF_DIRECT
{
self = [super init];
diff --git a/src/OFUDPSocket+Private.h b/src/OFUDPSocket+Private.h
index eab92df6..3d63d7d4 100644
--- a/src/OFUDPSocket+Private.h
+++ b/src/OFUDPSocket+Private.h
@@ -19,6 +19,7 @@
OF_ASSUME_NONNULL_BEGIN
+OF_DIRECT_MEMBERS
@interface OFUDPSocket ()
- (uint16_t)of_bindToAddress: (of_socket_address_t *)address
extraType: (int)extraType;
diff --git a/src/OFUDPSocket.m b/src/OFUDPSocket.m
index 4c171fc0..e4b3851c 100644
--- a/src/OFUDPSocket.m
+++ b/src/OFUDPSocket.m
@@ -39,7 +39,7 @@
@dynamic delegate;
- (uint16_t)of_bindToAddress: (of_socket_address_t *)address
- extraType: (int)extraType
+ extraType: (int)extraType OF_DIRECT
{
void *pool = objc_autoreleasePoolPush();
OFString *host;
diff --git a/src/OFURL.m b/src/OFURL.m
index 10be2606..cc2e57a6 100644
--- a/src/OFURL.m
+++ b/src/OFURL.m
@@ -87,6 +87,7 @@ initURLQueryOrFragmentAllowedCharacterSet(void)
[[OFURLQueryOrFragmentAllowedCharacterSet alloc] init];
}
+OF_DIRECT_MEMBERS
@interface OFInvertedCharacterSetWithoutPercent: OFCharacterSet
{
OFCharacterSet *_characterSet;
diff --git a/src/OFUTF8String+Private.h b/src/OFUTF8String+Private.h
index d95a41ef..0752bb95 100644
--- a/src/OFUTF8String+Private.h
+++ b/src/OFUTF8String+Private.h
@@ -19,6 +19,7 @@
OF_ASSUME_NONNULL_BEGIN
+OF_DIRECT_MEMBERS
@interface OFUTF8String ()
- (instancetype)of_initWithUTF8String: (const char *)UTF8String
length: (size_t)UTF8StringLength
diff --git a/src/OFWindowsRegistryKey.m b/src/OFWindowsRegistryKey.m
index 7c18dd23..9b38995c 100644
--- a/src/OFWindowsRegistryKey.m
+++ b/src/OFWindowsRegistryKey.m
@@ -34,6 +34,7 @@
#import "OFOutOfRangeException.h"
#import "OFSetWindowsRegistryValueFailedException.h"
+OF_DIRECT_MEMBERS
@interface OFWindowsRegistryKey ()
- (instancetype)of_initWithHKey: (HKEY)hKey
close: (bool)close;
diff --git a/src/OFXMLElement.m b/src/OFXMLElement.m
index 491f47de..95d1db3e 100644
--- a/src/OFXMLElement.m
+++ b/src/OFXMLElement.m
@@ -428,7 +428,7 @@ static Class CDATAClass = Nil;
- (OFString *)of_XMLStringWithParent: (OFXMLElement *)parent
namespaces: (OFDictionary *)allNamespaces
indentation: (unsigned int)indentation
- level: (unsigned int)level
+ level: (unsigned int)level OF_DIRECT
{
void *pool;
char *cString;
diff --git a/src/OFXMLParser.h b/src/OFXMLParser.h
index b02021ee..8e3016a1 100644
--- a/src/OFXMLParser.h
+++ b/src/OFXMLParser.h
@@ -153,8 +153,7 @@ OF_SUBCLASSING_RESTRICTED
OF_XMLPARSER_IN_COMMENT_OPENING,
OF_XMLPARSER_IN_COMMENT_1,
OF_XMLPARSER_IN_COMMENT_2,
- OF_XMLPARSER_IN_DOCTYPE,
- OF_XMLPARSER_NUM_STATES
+ OF_XMLPARSER_IN_DOCTYPE
} _state;
size_t _i, _last;
const char *_Nullable _data;
diff --git a/src/OFXMLParser.m b/src/OFXMLParser.m
index 7f4d0c4c..5379a03e 100644
--- a/src/OFXMLParser.m
+++ b/src/OFXMLParser.m
@@ -41,33 +41,56 @@
#import "OFOutOfRangeException.h"
#import "OFUnboundPrefixException.h"
-typedef void (*state_function_t)(id, SEL);
-static SEL selectors[OF_XMLPARSER_NUM_STATES];
-static state_function_t lookupTable[OF_XMLPARSER_NUM_STATES];
-
@interface OFXMLParser () <OFStringXMLUnescapingDelegate>
-- (void)of_inByteOrderMarkState;
-- (void)of_outsideTagState;
-- (void)of_tagOpenedState;
-- (void)of_inProcessingInstructionsState;
-- (void)of_inTagNameState;
-- (void)of_inCloseTagNameState;
-- (void)of_inTagState;
-- (void)of_inAttributeNameState;
-- (void)of_expectAttributeEqualSignState;
-- (void)of_expectAttributeDelimiterState;
-- (void)of_inAttributeValueState;
-- (void)of_expectTagCloseState;
-- (void)of_expectSpaceOrTagCloseState;
-- (void)of_inExclamationMarkState;
-- (void)of_inCDATAOpeningState;
-- (void)of_inCDATAState;
-- (void)of_inCommentOpeningState;
-- (void)of_inCommentState1;
-- (void)of_inCommentState2;
-- (void)of_inDOCTYPEState;
@end
+static void inByteOrderMarkState(OFXMLParser *);
+static void outsideTagState(OFXMLParser *);
+static void tagOpenedState(OFXMLParser *);
+static void inProcessingInstructionsState(OFXMLParser *);
+static void inTagNameState(OFXMLParser *);
+static void inCloseTagNameState(OFXMLParser *);
+static void inTagState(OFXMLParser *);
+static void inAttributeNameState(OFXMLParser *);
+static void expectAttributeEqualSignState(OFXMLParser *);
+static void expectAttributeDelimiterState(OFXMLParser *);
+static void inAttributeValueState(OFXMLParser *);
+static void expectTagCloseState(OFXMLParser *);
+static void expectSpaceOrTagCloseState(OFXMLParser *);
+static void inExclamationMarkState(OFXMLParser *);
+static void inCDATAOpeningState(OFXMLParser *);
+static void inCDATAState(OFXMLParser *);
+static void inCommentOpeningState(OFXMLParser *);
+static void inCommentState1(OFXMLParser *);
+static void inCommentState2(OFXMLParser *);
+static void inDOCTYPEState(OFXMLParser *);
+typedef void (*state_function_t)(OFXMLParser *);
+static state_function_t lookupTable[] = {
+ [OF_XMLPARSER_IN_BYTE_ORDER_MARK] = inByteOrderMarkState,
+ [OF_XMLPARSER_OUTSIDE_TAG] = outsideTagState,
+ [OF_XMLPARSER_TAG_OPENED] = tagOpenedState,
+ [OF_XMLPARSER_IN_PROCESSING_INSTRUCTIONS] =
+ inProcessingInstructionsState,
+ [OF_XMLPARSER_IN_TAG_NAME] = inTagNameState,
+ [OF_XMLPARSER_IN_CLOSE_TAG_NAME] = inCloseTagNameState,
+ [OF_XMLPARSER_IN_TAG] = inTagState,
+ [OF_XMLPARSER_IN_ATTRIBUTE_NAME] = inAttributeNameState,
+ [OF_XMLPARSER_EXPECT_ATTRIBUTE_EQUAL_SIGN] =
+ expectAttributeEqualSignState,
+ [OF_XMLPARSER_EXPECT_ATTRIBUTE_DELIMITER] =
+ expectAttributeDelimiterState,
+ [OF_XMLPARSER_IN_ATTRIBUTE_VALUE] = inAttributeValueState,
+ [OF_XMLPARSER_EXPECT_TAG_CLOSE] = expectTagCloseState,
+ [OF_XMLPARSER_EXPECT_SPACE_OR_TAG_CLOSE] = expectSpaceOrTagCloseState,
+ [OF_XMLPARSER_IN_EXCLAMATION_MARK] = inExclamationMarkState,
+ [OF_XMLPARSER_IN_CDATA_OPENING] = inCDATAOpeningState,
+ [OF_XMLPARSER_IN_CDATA] = inCDATAState,
+ [OF_XMLPARSER_IN_COMMENT_OPENING] = inCommentOpeningState,
+ [OF_XMLPARSER_IN_COMMENT_1] = inCommentState1,
+ [OF_XMLPARSER_IN_COMMENT_2] = inCommentState2,
+ [OF_XMLPARSER_IN_DOCTYPE] = inDOCTYPEState
+};
+
static OF_INLINE void
appendToBuffer(OFMutableData *buffer, const char *string,
of_string_encoding_t encoding, size_t length)
@@ -167,42 +190,6 @@ resolveAttributeNamespace(OFXMLAttribute *attribute, OFArray *namespaces,
@implementation OFXMLParser
@synthesize delegate = _delegate, depthLimit = _depthLimit;
-+ (void)initialize
-{
- const SEL selectors_[OF_XMLPARSER_NUM_STATES] = {
- @selector(of_inByteOrderMarkState),
- @selector(of_outsideTagState),
- @selector(of_tagOpenedState),
- @selector(of_inProcessingInstructionsState),
- @selector(of_inTagNameState),
- @selector(of_inCloseTagNameState),
- @selector(of_inTagState),
- @selector(of_inAttributeNameState),
- @selector(of_expectAttributeEqualSignState),
- @selector(of_expectAttributeDelimiterState),
- @selector(of_inAttributeValueState),
- @selector(of_expectTagCloseState),
- @selector(of_expectSpaceOrTagCloseState),
- @selector(of_inExclamationMarkState),
- @selector(of_inCDATAOpeningState),
- @selector(of_inCDATAState),
- @selector(of_inCommentOpeningState),
- @selector(of_inCommentState1),
- @selector(of_inCommentState2),
- @selector(of_inDOCTYPEState)
- };
- memcpy(selectors, selectors_, sizeof(selectors_));
-
- for (size_t i = 0; i < OF_XMLPARSER_NUM_STATES; i++) {
- if (![self instancesRespondToSelector: selectors[i]])
- @throw [OFInitializationFailedException
- exceptionWithClass: self];
-
- lookupTable[i] = (state_function_t)
- [self instanceMethodForSelector: selectors[i]];
- }
-}
-
+ (instancetype)parser
{
return [[[self alloc] init] autorelease];
@@ -263,7 +250,7 @@ resolveAttributeNamespace(OFXMLAttribute *attribute, OFArray *namespaces,
for (_i = _last = 0; _i < length; _i++) {
size_t j = _i;
- lookupTable[_state](self, selectors[_state]);
+ lookupTable[_state](self);
/* Ensure we don't count this character twice */
if (_i != j)
@@ -319,99 +306,102 @@ resolveAttributeNamespace(OFXMLAttribute *attribute, OFArray *namespaces,
}
#endif
-/*
- * The following methods handle the different states of the parser. They are
- * looked up in +[initialize] and put in a lookup table to speed things up.
- * One dispatch for every character would be way too slow!
- */
-
-- (void)of_inByteOrderMarkState
+static void
+inByteOrderMarkState(OFXMLParser *self)
{
- if (_data[_i] != "\xEF\xBB\xBF"[_level]) {
- if (_level == 0) {
- _state = OF_XMLPARSER_OUTSIDE_TAG;
- _i--;
+ if (self->_data[self->_i] != "\xEF\xBB\xBF"[self->_level]) {
+ if (self->_level == 0) {
+ self->_state = OF_XMLPARSER_OUTSIDE_TAG;
+ self->_i--;
return;
}
@throw [OFMalformedXMLException exceptionWithParser: self];
}
- if (_level++ == 2)
- _state = OF_XMLPARSER_OUTSIDE_TAG;
+ if (self->_level++ == 2)
+ self->_state = OF_XMLPARSER_OUTSIDE_TAG;
- _last = _i + 1;
+ self->_last = self->_i + 1;
}
/* Not in a tag */
-- (void)of_outsideTagState
+static void
+outsideTagState(OFXMLParser *self)
{
size_t length;
- if ((_finishedParsing || _previous.count < 1) && _data[_i] != ' ' &&
- _data[_i] != '\t' && _data[_i] != '\n' && _data[_i] != '\r' &&
- _data[_i] != '<')
+ if ((self->_finishedParsing || self->_previous.count < 1) &&
+ self->_data[self->_i] != ' ' && self->_data[self->_i] != '\t' &&
+ self->_data[self->_i] != '\n' && self->_data[self->_i] != '\r' &&
+ self->_data[self->_i] != '<')
@throw [OFMalformedXMLException exceptionWithParser: self];
- if (_data[_i] != '<')
+ if (self->_data[self->_i] != '<')
return;
- if ((length = _i - _last) > 0)
- appendToBuffer(_buffer, _data + _last, _encoding, length);
+ if ((length = self->_i - self->_last) > 0)
+ appendToBuffer(self->_buffer, self->_data + self->_last,
+ self->_encoding, length);
- if (_buffer.count > 0) {
+ if (self->_buffer.count > 0) {
void *pool = objc_autoreleasePoolPush();
- OFString *characters = transformString(self, _buffer, 0, true);
+ OFString *characters = transformString(self, self->_buffer, 0,
+ true);
- if ([_delegate respondsToSelector:
+ if ([self->_delegate respondsToSelector:
@selector(parser:foundCharacters:)])
- [_delegate parser: self
- foundCharacters: characters];
+ [self->_delegate parser: self
+ foundCharacters: characters];
objc_autoreleasePoolPop(pool);
}
- [_buffer removeAllItems];
+ [self->_buffer removeAllItems];
- _last = _i + 1;
- _state = OF_XMLPARSER_TAG_OPENED;
+ self->_last = self->_i + 1;
+ self->_state = OF_XMLPARSER_TAG_OPENED;
}
/* Tag was just opened */
-- (void)of_tagOpenedState
+static void
+tagOpenedState(OFXMLParser *self)
{
- if (_finishedParsing && _data[_i] != '!' && _data[_i] != '?')
+ if (self->_finishedParsing && self->_data[self->_i] != '!' &&
+ self->_data[self->_i] != '?')
@throw [OFMalformedXMLException exceptionWithParser: self];
- switch (_data[_i]) {
+ switch (self->_data[self->_i]) {
case '?':
- _last = _i + 1;
- _state = OF_XMLPARSER_IN_PROCESSING_INSTRUCTIONS;
- _level = 0;
+ self->_last = self->_i + 1;
+ self->_state = OF_XMLPARSER_IN_PROCESSING_INSTRUCTIONS;
+ self->_level = 0;
break;
case '/':
- _last = _i + 1;
- _state = OF_XMLPARSER_IN_CLOSE_TAG_NAME;
- _acceptProlog = false;
+ self->_last = self->_i + 1;
+ self->_state = OF_XMLPARSER_IN_CLOSE_TAG_NAME;
+ self->_acceptProlog = false;
break;
case '!':
- _last = _i + 1;
- _state = OF_XMLPARSER_IN_EXCLAMATION_MARK;
- _acceptProlog = false;
+ self->_last = self->_i + 1;
+ self->_state = OF_XMLPARSER_IN_EXCLAMATION_MARK;
+ self->_acceptProlog = false;
break;
default:
- if (_depthLimit > 0 && _previous.count >= _depthLimit)
+ if (self->_depthLimit > 0 &&
+ self->_previous.count >= self->_depthLimit)
@throw [OFOutOfRangeException exception];
- _state = OF_XMLPARSER_IN_TAG_NAME;
- _acceptProlog = false;
- _i--;
+ self->_state = OF_XMLPARSER_IN_TAG_NAME;
+ self->_acceptProlog = false;
+ self->_i--;
break;
}
}
/* <?xml […]?> */
-- (bool)of_parseXMLProcessingInstructions: (OFString *)pi
+static bool
+parseXMLProcessingInstructions(OFXMLParser *self, OFString *pi)
{
const char *cString;
size_t length, last;
@@ -421,10 +411,10 @@ resolveAttributeNamespace(OFXMLAttribute *attribute, OFArray *namespaces,
char piDelimiter = 0;
bool hasVersion = false;
- if (!_acceptProlog)
+ if (!self->_acceptProlog)
return false;
- _acceptProlog = false;
+ self->_acceptProlog = false;
pi = [pi substringWithRange: of_range(3, pi.length - 3)];
pi = pi.stringByDeletingEnclosingWhitespaces;
@@ -451,7 +441,7 @@ resolveAttributeNamespace(OFXMLAttribute *attribute, OFArray *namespaces,
attribute = [OFString
stringWithCString: cString + last
- encoding: _encoding
+ encoding: self->_encoding
length: i - last];
last = i + 1;
PIState = 2;
@@ -472,7 +462,7 @@ resolveAttributeNamespace(OFXMLAttribute *attribute, OFArray *namespaces,
value = [OFMutableString
stringWithCString: cString + last
- encoding: _encoding
+ encoding: self->_encoding
length: i - last];
if ([attribute isEqual: @"version"]) {
@@ -484,7 +474,7 @@ resolveAttributeNamespace(OFXMLAttribute *attribute, OFArray *namespaces,
if ([attribute isEqual: @"encoding"]) {
@try {
- _encoding =
+ self->_encoding =
of_string_parse_encoding(value);
} @catch (OFInvalidArgumentException *e) {
@throw [OFInvalidEncodingException
@@ -506,528 +496,564 @@ resolveAttributeNamespace(OFXMLAttribute *attribute, OFArray *namespaces,
}
/* Inside processing instructions */
-- (void)of_inProcessingInstructionsState
+static void
+inProcessingInstructionsState(OFXMLParser *self)
{
- if (_data[_i] == '?')
- _level = 1;
- else if (_level == 1 && _data[_i] == '>') {
+ if (self->_data[self->_i] == '?')
+ self->_level = 1;
+ else if (self->_level == 1 && self->_data[self->_i] == '>') {
void *pool = objc_autoreleasePoolPush();
OFString *PI;
- appendToBuffer(_buffer, _data + _last, _encoding, _i - _last);
- PI = transformString(self, _buffer, 1, false);
+ appendToBuffer(self->_buffer, self->_data + self->_last,
+ self->_encoding, self->_i - self->_last);
+ PI = transformString(self, self->_buffer, 1, false);
if ([PI isEqual: @"xml"] || [PI hasPrefix: @"xml "] ||
[PI hasPrefix: @"xml\t"] || [PI hasPrefix: @"xml\r"] ||
[PI hasPrefix: @"xml\n"])
- if (![self of_parseXMLProcessingInstructions: PI])
+ if (!parseXMLProcessingInstructions(self, PI))
@throw [OFMalformedXMLException
exceptionWithParser: self];
- if ([_delegate respondsToSelector:
+ if ([self->_delegate respondsToSelector:
@selector(parser:foundProcessingInstructions:)])
- [_delegate parser: self
+ [self->_delegate parser: self
foundProcessingInstructions: PI];
objc_autoreleasePoolPop(pool);
- [_buffer removeAllItems];
+ [self->_buffer removeAllItems];
- _last = _i + 1;
- _state = OF_XMLPARSER_OUTSIDE_TAG;
+ self->_last = self->_i + 1;
+ self->_state = OF_XMLPARSER_OUTSIDE_TAG;
} else
- _level = 0;
+ self->_level = 0;
}
/* Inside a tag, no name yet */
-- (void)of_inTagNameState
+static void
+inTagNameState(OFXMLParser *self)
{
void *pool;
const char *bufferCString, *tmp;
size_t length, bufferLength;
OFString *bufferString;
- if (_data[_i] != ' ' && _data[_i] != '\t' && _data[_i] != '\n' &&
- _data[_i] != '\r' && _data[_i] != '>' && _data[_i] != '/')
+ if (self->_data[self->_i] != ' ' && self->_data[self->_i] != '\t' &&
+ self->_data[self->_i] != '\n' && self->_data[self->_i] != '\r' &&
+ self->_data[self->_i] != '>' && self->_data[self->_i] != '/')
return;
- if ((length = _i - _last) > 0)
- appendToBuffer(_buffer, _data + _last, _encoding, length);
+ if ((length = self->_i - self->_last) > 0)
+ appendToBuffer(self->_buffer, self->_data + self->_last,
+ self->_encoding, length);
pool = objc_autoreleasePoolPush();
- bufferCString = _buffer.items;
- bufferLength = _buffer.count;
+ bufferCString = self->_buffer.items;
+ bufferLength = self->_buffer.count;
bufferString = [OFString stringWithUTF8String: bufferCString
length: bufferLength];
if ((tmp = memchr(bufferCString, ':', bufferLength)) != NULL) {
- _name = [[OFString alloc]
+ self->_name = [[OFString alloc]
initWithUTF8String: tmp + 1
length: bufferLength -
(tmp - bufferCString) - 1];
- _prefix = [[OFString alloc]
+ self->_prefix = [[OFString alloc]
initWithUTF8String: bufferCString
length: tmp - bufferCString];
} else {
- _name = [bufferString copy];
- _prefix = nil;
+ self->_name = [bufferString copy];
+ self->_prefix = nil;
}
- if (_data[_i] == '>' || _data[_i] == '/') {
+ if (self->_data[self->_i] == '>' || self->_data[self->_i] == '/') {
OFString *namespace;
- namespace = namespaceForPrefix(_prefix, _namespaces);
+ namespace = namespaceForPrefix(self->_prefix,
+ self->_namespaces);
- if (_prefix != nil && namespace == nil)
+ if (self->_prefix != nil && namespace == nil)
@throw [OFUnboundPrefixException
- exceptionWithPrefix: _prefix
+ exceptionWithPrefix: self->_prefix
parser: self];
- if ([_delegate respondsToSelector: @selector(parser:
+ if ([self->_delegate respondsToSelector: @selector(parser:
didStartElement:prefix:namespace:attributes:)])
- [_delegate parser: self
- didStartElement: _name
- prefix: _prefix
- namespace: namespace
- attributes: nil];
-
- if (_data[_i] == '/') {
- if ([_delegate respondsToSelector:
+ [self->_delegate parser: self
+ didStartElement: self->_name
+ prefix: self->_prefix
+ namespace: namespace
+ attributes: nil];
+
+ if (self->_data[self->_i] == '/') {
+ if ([self->_delegate respondsToSelector:
@selector(parser:didEndElement:prefix:namespace:)])
- [_delegate parser: self
- didEndElement: _name
- prefix: _prefix
- namespace: namespace];
+ [self->_delegate parser: self
+ didEndElement: self->_name
+ prefix: self->_prefix
+ namespace: namespace];
- if (_previous.count == 0)
- _finishedParsing = true;
+ if (self->_previous.count == 0)
+ self->_finishedParsing = true;
} else
- [_previous addObject: bufferString];
+ [self->_previous addObject: bufferString];
- [_name release];
- [_prefix release];
- _name = _prefix = nil;
+ [self->_name release];
+ [self->_prefix release];
+ self->_name = self->_prefix = nil;
- _state = (_data[_i] == '/'
+ self->_state = (self->_data[self->_i] == '/'
? OF_XMLPARSER_EXPECT_TAG_CLOSE
: OF_XMLPARSER_OUTSIDE_TAG);
} else
- _state = OF_XMLPARSER_IN_TAG;
+ self->_state = OF_XMLPARSER_IN_TAG;
- if (_data[_i] != '/')
- [_namespaces addObject: [OFMutableDictionary dictionary]];
+ if (self->_data[self->_i] != '/')
+ [self->_namespaces addObject: [OFMutableDictionary dictionary]];
objc_autoreleasePoolPop(pool);
- [_buffer removeAllItems];
- _last = _i + 1;
+ [self->_buffer removeAllItems];
+ self->_last = self->_i + 1;
}
/* Inside a close tag, no name yet */
-- (void)of_inCloseTagNameState
+static void
+inCloseTagNameState(OFXMLParser *self)
{
void *pool;
const char *bufferCString, *tmp;
size_t length, bufferLength;
OFString *bufferString, *namespace;
- if (_data[_i] != ' ' && _data[_i] != '\t' && _data[_i] != '\n' &&
- _data[_i] != '\r' && _data[_i] != '>')
+ if (self->_data[self->_i] != ' ' && self->_data[self->_i] != '\t' &&
+ self->_data[self->_i] != '\n' && self->_data[self->_i] != '\r' &&
+ self->_data[self->_i] != '>')
return;
- if ((length = _i - _last) > 0)
- appendToBuffer(_buffer, _data + _last, _encoding, length);
+ if ((length = self->_i - self->_last) > 0)
+ appendToBuffer(self->_buffer, self->_data + self->_last,
+ self->_encoding, length);
pool = objc_autoreleasePoolPush();
- bufferCString = _buffer.items;
- bufferLength = _buffer.count;
+ bufferCString = self->_buffer.items;
+ bufferLength = self->_buffer.count;
bufferString = [OFString stringWithUTF8String: bufferCString
length: bufferLength];
if ((tmp = memchr(bufferCString, ':', bufferLength)) != NULL) {
- _name = [[OFString alloc]
+ self->_name = [[OFString alloc]
initWithUTF8String: tmp + 1
length: bufferLength -
(tmp - bufferCString) - 1];
- _prefix = [[OFString alloc]
+ self->_prefix = [[OFString alloc]
initWithUTF8String: bufferCString
length: tmp - bufferCString];
} else {
- _name = [bufferString copy];
- _prefix = nil;
+ self->_name = [bufferString copy];
+ self->_prefix = nil;
}
- if (![_previous.lastObject isEqual: bufferString])
+ if (![self->_previous.lastObject isEqual: bufferString])
@throw [OFMalformedXMLException exceptionWithParser: self];
- [_previous removeLastObject];
+ [self->_previous removeLastObject];
- [_buffer removeAllItems];
+ [self->_buffer removeAllItems];
- namespace = namespaceForPrefix(_prefix, _namespaces);
- if (_prefix != nil && namespace == nil)
- @throw [OFUnboundPrefixException exceptionWithPrefix: _prefix
- parser: self];
+ namespace = namespaceForPrefix(self->_prefix, self->_namespaces);
+ if (self->_prefix != nil && namespace == nil)
+ @throw [OFUnboundPrefixException
+ exceptionWithPrefix: self->_prefix
+ parser: self];
- if ([_delegate respondsToSelector:
+ if ([self->_delegate respondsToSelector:
@selector(parser:didEndElement:prefix:namespace:)])
- [_delegate parser: self
- didEndElement: _name
- prefix: _prefix
- namespace: namespace];
+ [self->_delegate parser: self
+ didEndElement: self->_name
+ prefix: self->_prefix
+ namespace: namespace];
objc_autoreleasePoolPop(pool);
- [_namespaces removeLastObject];
- [_name release];
- [_prefix release];
- _name = _prefix = nil;
+ [self->_namespaces removeLastObject];
+ [self->_name release];
+ [self->_prefix release];
+ self->_name = self->_prefix = nil;
- _last = _i + 1;
- _state = (_data[_i] == '>'
+ self->_last = self->_i + 1;
+ self->_state = (self->_data[self->_i] == '>'
? OF_XMLPARSER_OUTSIDE_TAG
: OF_XMLPARSER_EXPECT_SPACE_OR_TAG_CLOSE);
- if (_previous.count == 0)
- _finishedParsing = true;
+ if (self->_previous.count == 0)
+ self->_finishedParsing = true;
}
/* Inside a tag, name found */
-- (void)of_inTagState
+static void
+inTagState(OFXMLParser *self)
{
void *pool;
OFString *namespace;
OFXMLAttribute *const *attributesObjects;
size_t attributesCount;
- if (_data[_i] != '>' && _data[_i] != '/') {
- if (_data[_i] != ' ' && _data[_i] != '\t' &&
- _data[_i] != '\n' && _data[_i] != '\r') {
- _last = _i;
- _state = OF_XMLPARSER_IN_ATTRIBUTE_NAME;
- _i--;
+ if (self->_data[self->_i] != '>' && self->_data[self->_i] != '/') {
+ if (self->_data[self->_i] != ' ' &&
+ self->_data[self->_i] != '\t' &&
+ self->_data[self->_i] != '\n' &&
+ self->_data[self->_i] != '\r') {
+ self->_last = self->_i;
+ self->_state = OF_XMLPARSER_IN_ATTRIBUTE_NAME;
+ self->_i--;
}
return;
}
- attributesObjects = _attributes.objects;
- attributesCount = _attributes.count;
+ attributesObjects = self->_attributes.objects;
+ attributesCount = self->_attributes.count;
- namespace = namespaceForPrefix(_prefix, _namespaces);
+ namespace = namespaceForPrefix(self->_prefix, self->_namespaces);
- if (_prefix != nil && namespace == nil)
- @throw [OFUnboundPrefixException exceptionWithPrefix: _prefix
- parser: self];
+ if (self->_prefix != nil && namespace == nil)
+ @throw [OFUnboundPrefixException
+ exceptionWithPrefix: self->_prefix
+ parser: self];
for (size_t j = 0; j < attributesCount; j++)
- resolveAttributeNamespace(attributesObjects[j], _namespaces,
- self);
+ resolveAttributeNamespace(attributesObjects[j],
+ self->_namespaces, self);
pool = objc_autoreleasePoolPush();
- if ([_delegate respondsToSelector:
+ if ([self->_delegate respondsToSelector:
@selector(parser:didStartElement:prefix:namespace:attributes:)])
- [_delegate parser: self
- didStartElement: _name
- prefix: _prefix
- namespace: namespace
- attributes: _attributes];
-
- if (_data[_i] == '/') {
- if ([_delegate respondsToSelector:
+ [self->_delegate parser: self
+ didStartElement: self->_name
+ prefix: self->_prefix
+ namespace: namespace
+ attributes: self->_attributes];
+
+ if (self->_data[self->_i] == '/') {
+ if ([self->_delegate respondsToSelector:
@selector(parser:didEndElement:prefix:namespace:)])
- [_delegate parser: self
- didEndElement: _name
- prefix: _prefix
- namespace: namespace];
-
- if (_previous.count == 0)
- _finishedParsing = true;
-
- [_namespaces removeLastObject];
- } else if (_prefix != nil) {
- OFString *str = [OFString stringWithFormat: @"%@:%@",
- _prefix, _name];
- [_previous addObject: str];
+ [self->_delegate parser: self
+ didEndElement: self->_name
+ prefix: self->_prefix
+ namespace: namespace];
+
+ if (self->_previous.count == 0)
+ self->_finishedParsing = true;
+
+ [self->_namespaces removeLastObject];
+ } else if (self->_prefix != nil) {
+ OFString *str = [OFString stringWithFormat:
+ @"%@:%@", self->_prefix, self->_name];
+ [self->_previous addObject: str];
} else
- [_previous addObject: _name];
+ [self->_previous addObject: self->_name];
objc_autoreleasePoolPop(pool);
- [_name release];
- [_prefix release];
- [_attributes removeAllObjects];
- _name = _prefix = nil;
+ [self->_name release];
+ [self->_prefix release];
+ [self->_attributes removeAllObjects];
+ self->_name = self->_prefix = nil;
- _last = _i + 1;
- _state = (_data[_i] == '/'
+ self->_last = self->_i + 1;
+ self->_state = (self->_data[self->_i] == '/'
? OF_XMLPARSER_EXPECT_TAG_CLOSE
: OF_XMLPARSER_OUTSIDE_TAG);
}
/* Looking for attribute name */
-- (void)of_inAttributeNameState
+static void
+inAttributeNameState(OFXMLParser *self)
{
void *pool;
OFString *bufferString;
const char *bufferCString, *tmp;
size_t length, bufferLength;
- if (_data[_i] != '=' && _data[_i] != ' ' && _data[_i] != '\t' &&
- _data[_i] != '\n' && _data[_i] != '\r')
+ if (self->_data[self->_i] != '=' && self->_data[self->_i] != ' ' &&
+ self->_data[self->_i] != '\t' && self->_data[self->_i] != '\n' &&
+ self->_data[self->_i] != '\r')
return;
- if ((length = _i - _last) > 0)
- appendToBuffer(_buffer, _data + _last, _encoding, length);
+ if ((length = self->_i - self->_last) > 0)
+ appendToBuffer(self->_buffer, self->_data + self->_last,
+ self->_encoding, length);
pool = objc_autoreleasePoolPush();
- bufferString = [OFString stringWithUTF8String: _buffer.items
- length: _buffer.count];
+ bufferString = [OFString stringWithUTF8String: self->_buffer.items
+ length: self->_buffer.count];
bufferCString = bufferString.UTF8String;
bufferLength = bufferString.UTF8StringLength;
if ((tmp = memchr(bufferCString, ':', bufferLength)) != NULL) {
- _attributeName = [[OFString alloc]
+ self->_attributeName = [[OFString alloc]
initWithUTF8String: tmp + 1
length: bufferLength -
(tmp - bufferCString) - 1];
- _attributePrefix = [[OFString alloc]
+ self->_attributePrefix = [[OFString alloc]
initWithUTF8String: bufferCString
length: tmp - bufferCString];
} else {
- _attributeName = [bufferString copy];
- _attributePrefix = nil;
+ self->_attributeName = [bufferString copy];
+ self->_attributePrefix = nil;
}
objc_autoreleasePoolPop(pool);
- [_buffer removeAllItems];
+ [self->_buffer removeAllItems];
- _last = _i + 1;
- _state = (_data[_i] == '='
+ self->_last = self->_i + 1;
+ self->_state = (self->_data[self->_i] == '='
? OF_XMLPARSER_EXPECT_ATTRIBUTE_DELIMITER
: OF_XMLPARSER_EXPECT_ATTRIBUTE_EQUAL_SIGN);
}
/* Expecting equal sign of an attribute */
-- (void)of_expectAttributeEqualSignState
+static void
+expectAttributeEqualSignState(OFXMLParser *self)
{
- if (_data[_i] == '=') {
- _last = _i + 1;
- _state = OF_XMLPARSER_EXPECT_ATTRIBUTE_DELIMITER;
+ if (self->_data[self->_i] == '=') {
+ self->_last = self->_i + 1;
+ self->_state = OF_XMLPARSER_EXPECT_ATTRIBUTE_DELIMITER;
return;
}
- if (_data[_i] != ' ' && _data[_i] != '\t' && _data[_i] != '\n' &&
- _data[_i] != '\r')
+ if (self->_data[self->_i] != ' ' && self->_data[self->_i] != '\t' &&
+ self->_data[self->_i] != '\n' && self->_data[self->_i] != '\r')
@throw [OFMalformedXMLException exceptionWithParser: self];
}
/* Expecting name/value delimiter of an attribute */
-- (void)of_expectAttributeDelimiterState
+static void
+expectAttributeDelimiterState(OFXMLParser *self)
{
- _last = _i + 1;
+ self->_last = self->_i + 1;
- if (_data[_i] == ' ' || _data[_i] == '\t' || _data[_i] == '\n' ||
- _data[_i] == '\r')
+ if (self->_data[self->_i] == ' ' || self->_data[self->_i] == '\t' ||
+ self->_data[self->_i] == '\n' || self->_data[self->_i] == '\r')
return;
- if (_data[_i] != '\'' && _data[_i] != '"')
+ if (self->_data[self->_i] != '\'' && self->_data[self->_i] != '"')
@throw [OFMalformedXMLException exceptionWithParser: self];
- _delimiter = _data[_i];
- _state = OF_XMLPARSER_IN_ATTRIBUTE_VALUE;
+ self->_delimiter = self->_data[self->_i];
+ self->_state = OF_XMLPARSER_IN_ATTRIBUTE_VALUE;
}
/* Looking for attribute value */
-- (void)of_inAttributeValueState
+static void
+inAttributeValueState(OFXMLParser *self)
{
void *pool;
OFString *attributeValue;
size_t length;
OFXMLAttribute *attribute;
- if (_data[_i] != _delimiter)
+ if (self->_data[self->_i] != self->_delimiter)
return;
- if ((length = _i - _last) > 0)
- appendToBuffer(_buffer, _data + _last, _encoding, length);
+ if ((length = self->_i - self->_last) > 0)
+ appendToBuffer(self->_buffer, self->_data + self->_last,
+ self->_encoding, length);
pool = objc_autoreleasePoolPush();
- attributeValue = transformString(self, _buffer, 0, true);
-
- if (_attributePrefix == nil && [_attributeName isEqual: @"xmlns"])
- [_namespaces.lastObject setObject: attributeValue
- forKey: @""];
- if ([_attributePrefix isEqual: @"xmlns"])
- [_namespaces.lastObject setObject: attributeValue
- forKey: _attributeName];
-
- attribute = [OFXMLAttribute attributeWithName: _attributeName
- namespace: _attributePrefix
+ attributeValue = transformString(self, self->_buffer, 0, true);
+
+ if (self->_attributePrefix == nil &&
+ [self->_attributeName isEqual: @"xmlns"])
+ [self->_namespaces.lastObject setObject: attributeValue
+ forKey: @""];
+ if ([self->_attributePrefix isEqual: @"xmlns"])
+ [self->_namespaces.lastObject setObject: attributeValue
+ forKey: self->_attributeName];
+
+ attribute = [OFXMLAttribute attributeWithName: self->_attributeName
+ namespace: self->_attributePrefix
stringValue: attributeValue];
- attribute->_useDoubleQuotes = (_delimiter == '"');
- [_attributes addObject: attribute];
+ attribute->_useDoubleQuotes = (self->_delimiter == '"');
+ [self->_attributes addObject: attribute];
objc_autoreleasePoolPop(pool);
- [_buffer removeAllItems];
- [_attributeName release];
- [_attributePrefix release];
- _attributeName = _attributePrefix = nil;
+ [self->_buffer removeAllItems];
+ [self->_attributeName release];
+ [self->_attributePrefix release];
+ self->_attributeName = self->_attributePrefix = nil;
- _last = _i + 1;
- _state = OF_XMLPARSER_IN_TAG;
+ self->_last = self->_i + 1;
+ self->_state = OF_XMLPARSER_IN_TAG;
}
/* Expecting closing '>' */
-- (void)of_expectTagCloseState
+static void
+expectTagCloseState(OFXMLParser *self)
{
- if (_data[_i] == '>') {
- _last = _i + 1;
- _state = OF_XMLPARSER_OUTSIDE_TAG;
+ if (self->_data[self->_i] == '>') {
+ self->_last = self->_i + 1;
+ self->_state = OF_XMLPARSER_OUTSIDE_TAG;
} else
@throw [OFMalformedXMLException exceptionWithParser: self];
}
/* Expecting closing '>' or space */
-- (void)of_expectSpaceOrTagCloseState
+static void
+expectSpaceOrTagCloseState(OFXMLParser *self)
{
- if (_data[_i] == '>') {
- _last = _i + 1;
- _state = OF_XMLPARSER_OUTSIDE_TAG;
- } else if (_data[_i] != ' ' && _data[_i] != '\t' &&
- _data[_i] != '\n' && _data[_i] != '\r')
+ if (self->_data[self->_i] == '>') {
+ self->_last = self->_i + 1;
+ self->_state = OF_XMLPARSER_OUTSIDE_TAG;
+ } else if (self->_data[self->_i] != ' ' &&
+ self->_data[self->_i] != '\t' && self->_data[self->_i] != '\n' &&
+ self->_data[self->_i] != '\r')
@throw [OFMalformedXMLException exceptionWithParser: self];
}
/* In <! */
-- (void)of_inExclamationMarkState
+static void
+inExclamationMarkState(OFXMLParser *self)
{
- if (_finishedParsing && _data[_i] != '-')
+ if (self->_finishedParsing && self->_data[self->_i] != '-')
@throw [OFMalformedXMLException exceptionWithParser: self];
- if (_data[_i] == '-')
- _state = OF_XMLPARSER_IN_COMMENT_OPENING;
- else if (_data[_i] == '[') {
- _state = OF_XMLPARSER_IN_CDATA_OPENING;
- _level = 0;
- } else if (_data[_i] == 'D') {
- _state = OF_XMLPARSER_IN_DOCTYPE;
- _level = 0;
+ if (self->_data[self->_i] == '-')
+ self->_state = OF_XMLPARSER_IN_COMMENT_OPENING;
+ else if (self->_data[self->_i] == '[') {
+ self->_state = OF_XMLPARSER_IN_CDATA_OPENING;
+ self->_level = 0;
+ } else if (self->_data[self->_i] == 'D') {
+ self->_state = OF_XMLPARSER_IN_DOCTYPE;
+ self->_level = 0;
} else
@throw [OFMalformedXMLException exceptionWithParser: self];
- _last = _i + 1;
+ self->_last = self->_i + 1;
}
/* CDATA */
-- (void)of_inCDATAOpeningState
+static void
+inCDATAOpeningState(OFXMLParser *self)
{
- if (_data[_i] != "CDATA["[_level])
+ if (self->_data[self->_i] != "CDATA["[self->_level])
@throw [OFMalformedXMLException exceptionWithParser: self];
- if (++_level == 6) {
- _state = OF_XMLPARSER_IN_CDATA;
- _level = 0;
+ if (++self->_level == 6) {
+ self->_state = OF_XMLPARSER_IN_CDATA;
+ self->_level = 0;
}
- _last = _i + 1;
+ self->_last = self->_i + 1;
}
-- (void)of_inCDATAState
+static void
+inCDATAState(OFXMLParser *self)
{
-
- if (_data[_i] == ']')
- _level++;
- else if (_data[_i] == '>' && _level >= 2) {
+ if (self->_data[self->_i] == ']')
+ self->_level++;
+ else if (self->_data[self->_i] == '>' && self->_level >= 2) {
void *pool = objc_autoreleasePoolPush();
OFString *CDATA;
- appendToBuffer(_buffer, _data + _last, _encoding, _i - _last);
- CDATA = transformString(self, _buffer, 2, false);
+ appendToBuffer(self->_buffer, self->_data + self->_last,
+ self->_encoding, self->_i - self->_last);
+ CDATA = transformString(self, self->_buffer, 2, false);
- if ([_delegate respondsToSelector:
+ if ([self->_delegate respondsToSelector:
@selector(parser:foundCDATA:)])
- [_delegate parser: self
- foundCDATA: CDATA];
+ [self->_delegate parser: self
+ foundCDATA: CDATA];
objc_autoreleasePoolPop(pool);
- [_buffer removeAllItems];
+ [self->_buffer removeAllItems];
- _last = _i + 1;
- _state = OF_XMLPARSER_OUTSIDE_TAG;
+ self->_last = self->_i + 1;
+ self->_state = OF_XMLPARSER_OUTSIDE_TAG;
} else
- _level = 0;
+ self->_level = 0;
}
/* Comment */
-- (void)of_inCommentOpeningState
+static void
+inCommentOpeningState(OFXMLParser *self)
{
- if (_data[_i] != '-')
+ if (self->_data[self->_i] != '-')
@throw [OFMalformedXMLException exceptionWithParser: self];
- _last = _i + 1;
- _state = OF_XMLPARSER_IN_COMMENT_1;
- _level = 0;
+ self->_last = self->_i + 1;
+ self->_state = OF_XMLPARSER_IN_COMMENT_1;
+ self->_level = 0;
}
-- (void)of_inCommentState1
+static void
+inCommentState1(OFXMLParser *self)
{
- if (_data[_i] == '-')
- _level++;
+ if (self->_data[self->_i] == '-')
+ self->_level++;
else
- _level = 0;
+ self->_level = 0;
- if (_level == 2)
- _state = OF_XMLPARSER_IN_COMMENT_2;
+ if (self->_level == 2)
+ self->_state = OF_XMLPARSER_IN_COMMENT_2;
}
-- (void)of_inCommentState2
+static void
+inCommentState2(OFXMLParser *self)
{
void *pool;
OFString *comment;
- if (_data[_i] != '>')
+ if (self->_data[self->_i] != '>')
@throw [OFMalformedXMLException exceptionWithParser: self];
pool = objc_autoreleasePoolPush();
- appendToBuffer(_buffer, _data + _last, _encoding, _i - _last);
- comment = transformString(self, _buffer, 2, false);
+ appendToBuffer(self->_buffer, self->_data + self->_last,
+ self->_encoding, self->_i - self->_last);
+ comment = transformString(self, self->_buffer, 2, false);
- if ([_delegate respondsToSelector: @selector(parser:foundComment:)])
- [_delegate parser: self
- foundComment: comment];
+ if ([self->_delegate respondsToSelector:
+ @selector(parser:foundComment:)])
+ [self->_delegate parser: self
+ foundComment: comment];
objc_autoreleasePoolPop(pool);
- [_buffer removeAllItems];
+ [self->_buffer removeAllItems];
- _last = _i + 1;
- _state = OF_XMLPARSER_OUTSIDE_TAG;
+ self->_last = self->_i + 1;
+ self->_state = OF_XMLPARSER_OUTSIDE_TAG;
}
/* In <!DOCTYPE ...> */
-- (void)of_inDOCTYPEState
+static void
+inDOCTYPEState(OFXMLParser *self)
{
- if ((_level < 6 && _data[_i] != "OCTYPE"[_level]) ||
- (_level == 6 && _data[_i] != ' ' && _data[_i] != '\t' &&
- _data[_i] != '\n' && _data[_i] != '\r'))
+ if ((self->_level < 6 &&
+ self->_data[self->_i] != "OCTYPE"[self->_level]) ||
+ (self->_level == 6 && self->_data[self->_i] != ' ' &&
+ self->_data[self->_i] != '\t' && self->_data[self->_i] != '\n' &&
+ self->_data[self->_i] != '\r'))
@throw [OFMalformedXMLException exceptionWithParser: self];
- _level++;
+ self->_level++;
- if (_level > 6 && _data[_i] == '>')
- _state = OF_XMLPARSER_OUTSIDE_TAG;
+ if (self->_level > 6 && self->_data[self->_i] == '>')
+ self->_state = OF_XMLPARSER_OUTSIDE_TAG;
- _last = _i + 1;
+ self->_last = self->_i + 1;
}
- (size_t)lineNumber
diff --git a/src/OFZIPArchive.m b/src/OFZIPArchive.m
index 67b076dc..f5701fd4 100644
--- a/src/OFZIPArchive.m
+++ b/src/OFZIPArchive.m
@@ -52,6 +52,7 @@
* - Encrypted files cannot be read.
*/
+OF_DIRECT_MEMBERS
@interface OFZIPArchive ()
- (void)of_readZIPInfo;
- (void)of_readEntries;
@@ -59,6 +60,7 @@
- (void)of_writeCentralDirectory;
@end
+OF_DIRECT_MEMBERS
@interface OFZIPArchiveLocalFileHeader: OFObject
{
@public
@@ -74,6 +76,7 @@
- (bool)matchesEntry: (OFZIPArchiveEntry *)entry;
@end
+OF_DIRECT_MEMBERS
@interface OFZIPArchiveFileReadStream: OFStream
{
OFStream *_stream, *_decompressedStream;
@@ -87,6 +90,7 @@
entry: (OFZIPArchiveEntry *)entry;
@end
+OF_DIRECT_MEMBERS
@interface OFZIPArchiveFileWriteStream: OFStream
{
OFStream *_stream;
diff --git a/src/OFZIPArchiveEntry+Private.h b/src/OFZIPArchiveEntry+Private.h
index 23232528..a49bde6c 100644
--- a/src/OFZIPArchiveEntry+Private.h
+++ b/src/OFZIPArchiveEntry+Private.h
@@ -24,8 +24,9 @@ OF_ASSUME_NONNULL_BEGIN
uint16_t of_lastModifiedFileTime, of_lastModifiedFileDate;
@property (readonly, nonatomic) int64_t of_localFileHeaderOffset;
-- (instancetype)of_initWithStream: (OFStream *)stream OF_METHOD_FAMILY(init);
-- (uint64_t)of_writeToStream: (OFStream *)stream;
+- (instancetype)of_initWithStream: (OFStream *)stream
+ OF_METHOD_FAMILY(init) OF_DIRECT;
+- (uint64_t)of_writeToStream: (OFStream *)stream OF_DIRECT;
@end
@interface OFMutableZIPArchiveEntry ()
diff --git a/src/ObjFW.h b/src/ObjFW.h
index 8e51c14d..3b406e55 100644
--- a/src/ObjFW.h
+++ b/src/ObjFW.h
@@ -70,6 +70,8 @@
#endif
#ifdef OF_HAVE_SOCKETS
# import "OFStreamSocket.h"
+# import "OFDatagramSocket.h"
+# import "OFSequencedPacketSocket.h"
# import "OFTCPSocket.h"
# import "OFUDPSocket.h"
# import "OFTLSSocket.h"
@@ -248,6 +250,7 @@
#import "once.h"
#ifdef OF_HAVE_THREADS
# import "thread.h"
+# import "tlskey.h"
# import "mutex.h"
# import "condition.h"
# import "OFMutex.h"
diff --git a/src/exceptions/OFDNSQueryFailedException.m b/src/exceptions/OFDNSQueryFailedException.m
index 4e783a49..688a6fe3 100644
--- a/src/exceptions/OFDNSQueryFailedException.m
+++ b/src/exceptions/OFDNSQueryFailedException.m
@@ -44,6 +44,8 @@ of_dns_resolver_error_to_string(of_dns_resolver_error_t error)
@"query.";
case OF_DNS_RESOLVER_ERROR_SERVER_REFUSED:
return @"The server refused the query.";
+ case OF_DNS_RESOLVER_ERROR_NO_NAME_SERVER:
+ return @"There was no name server to query.";
default:
return @"Unknown error.";
}
diff --git a/src/forwarding/apple-forwarding-i386.S b/src/forwarding/apple-forwarding-i386.S
index 49aca2c6..35816578 100644
--- a/src/forwarding/apple-forwarding-i386.S
+++ b/src/forwarding/apple-forwarding-i386.S
@@ -17,121 +17,131 @@
#include "config.h"
+.intel_syntax noprefix
+
.globl _of_forward
.globl _of_forward_stret
.section __TEXT, __cstring, cstring_literals
-str_forwardingTargetForSelector_:
+Lstr_forwardingTargetForSelector_:
.asciz "forwardingTargetForSelector:"
.section __OBJC, __message_refs, literal_pointers, no_dead_strip
-sel_forwardingTargetForSelector_:
- .long str_forwardingTargetForSelector_
+Lsel_forwardingTargetForSelector_:
+ .long Lstr_forwardingTargetForSelector_
.section __OBJC, __image_info
.long 0, 0
.section __TEXT, __text, regular, pure_instructions
_of_forward:
- pushl %ebp
- movl %esp, %ebp
+ push ebp
+ mov ebp, esp
- pushl %ebx
- subl $20, %esp
+ push ebx
+ sub esp, 20
call get_eip
0:
- movl 8(%ebp), %eax
- movl %eax, (%esp)
+ mov eax, [ebp+8]
+ mov [esp], eax
call _object_getClass
- movl %eax, (%esp)
- movl sel_forwardingTargetForSelector_-0b(%ebx), %eax
- movl %eax, 4(%esp)
+ mov [esp], eax
+ .att_syntax /* Next line is broken in Intel syntax */
+ movl Lsel_forwardingTargetForSelector_-0b(%ebx), %eax
+ .intel_syntax noprefix
+ mov [esp+4], eax
call _class_respondsToSelector
- testl %eax, %eax
+ test eax, eax
jz 0f
- movl 8(%ebp), %eax
- movl %eax, (%esp)
- movl sel_forwardingTargetForSelector_-0b(%ebx), %eax
- movl %eax, 4(%esp)
- movl 12(%ebp), %eax
- movl %eax, 8(%esp)
+ mov eax, [ebp+8]
+ mov [esp], eax
+ .att_syntax /* Next line is broken in Intel syntax */
+ movl Lsel_forwardingTargetForSelector_-0b(%ebx), %eax
+ .intel_syntax noprefix
+ mov [esp+4], eax
+ mov eax, [ebp+12]
+ mov [esp+8], eax
call _objc_msgSend
- testl %eax, %eax
+ test eax, eax
jz 0f
- cmpl 8(%ebp), %eax
+ cmp eax, [ebp+8]
je 0f
- movl %eax, 8(%ebp)
+ mov [ebp+8], eax
- addl $20, %esp
- popl %ebx
- popl %ebp
+ add esp, 20
+ pop ebx
+ pop ebp
jmp _objc_msgSend
0:
- addl $20, %esp
- popl %ebx
- popl %ebp
+ add esp, 20
+ pop ebx
+ pop ebp
jmp _of_method_not_found
_of_forward_stret:
- pushl %ebp
- movl %esp, %ebp
+ push ebp
+ mov ebp, esp
- pushl %ebx
- subl $20, %esp
+ push ebx
+ sub esp, 20
call get_eip
0:
- movl 12(%ebp), %eax
- movl %eax, (%esp)
+ mov eax, [ebp+12]
+ mov [esp], eax
call _object_getClass
- movl %eax, (%esp)
- movl sel_forwardingTargetForSelector_-0b(%ebx), %eax
- movl %eax, 4(%esp)
+ mov [esp], eax
+ .att_syntax /* Next line is broken in Intel syntax */
+ movl Lsel_forwardingTargetForSelector_-0b(%ebx), %eax
+ .intel_syntax noprefix
+ mov [esp+4], eax
call _class_respondsToSelector
- testl %eax, %eax
+ test eax, eax
jz 0f
- movl 12(%ebp), %eax
- movl %eax, (%esp)
- movl sel_forwardingTargetForSelector_-0b(%ebx), %eax
- movl %eax, 4(%esp)
- movl 16(%ebp), %eax
- movl %eax, 8(%esp)
+ mov eax, [ebp+12]
+ mov [esp], eax
+ .att_syntax /* Next line is broken in Intel syntax */
+ movl Lsel_forwardingTargetForSelector_-0b(%ebx), %eax
+ .intel_syntax noprefix
+ mov [esp+4], eax
+ mov eax, [ebp+16]
+ mov [esp+8], eax
call _objc_msgSend
- testl %eax, %eax
+ test eax, eax
jz 0f
- cmpl 12(%ebp), %eax
+ cmp eax, [ebp+12]
je 0f
- movl %eax, 12(%ebp)
+ mov [ebp+12], eax
- addl $20, %esp
- popl %ebx
- popl %ebp
+ add esp, 20
+ pop ebx
+ pop ebp
jmp _objc_msgSend_stret
0:
- addl $20, %esp
- popl %ebx
- popl %ebp
+ add esp, 20
+ pop ebx
+ pop ebp
jmp _of_method_not_found_stret
get_eip:
- movl (%esp), %ebx
+ mov ebx, [esp]
ret
diff --git a/src/forwarding/apple-forwarding-x86_64.S b/src/forwarding/apple-forwarding-x86_64.S
index b6876c38..b810a2bc 100644
--- a/src/forwarding/apple-forwarding-x86_64.S
+++ b/src/forwarding/apple-forwarding-x86_64.S
@@ -17,6 +17,8 @@
#include "config.h"
+.intel_syntax noprefix
+
.globl _of_forward
.globl _of_forward_stret
@@ -33,148 +35,148 @@ sel_forwardingTargetForSelector_:
.section __TEXT, __text, regular, pure_instructions
_of_forward:
- pushq %rbp
- movq %rsp, %rbp
+ push rbp
+ mov rbp, rsp
/* Save all arguments */
- subq $0xC0, %rsp /* 16-byte alignment */
- movq %rax, -0x8(%rbp)
- movq %rdi, -0x10(%rbp)
- movq %rsi, -0x18(%rbp)
- movq %rdx, -0x20(%rbp)
- movq %rcx, -0x28(%rbp)
- movq %r8, -0x30(%rbp)
- movq %r9, -0x38(%rbp)
- movaps %xmm0, -0x50(%rbp)
- movaps %xmm1, -0x60(%rbp)
- movaps %xmm2, -0x70(%rbp)
- movaps %xmm3, -0x80(%rbp)
- movaps %xmm4, -0x90(%rbp)
- movaps %xmm5, -0xA0(%rbp)
- movaps %xmm6, -0xB0(%rbp)
- movaps %xmm7, -0xC0(%rbp)
+ sub rsp, 0xC0 /* 16-byte alignment */
+ mov [rbp-0x08], rax
+ mov [rbp-0x10], rdi
+ mov [rbp-0x18], rsi
+ mov [rbp-0x20], rdx
+ mov [rbp-0x28], rcx
+ mov [rbp-0x30], r8
+ mov [rbp-0x38], r9
+ movaps [rbp-0x50], xmm0
+ movaps [rbp-0x60], xmm1
+ movaps [rbp-0x70], xmm2
+ movaps [rbp-0x80], xmm3
+ movaps [rbp-0x90], xmm4
+ movaps [rbp-0xA0], xmm5
+ movaps [rbp-0xB0], xmm6
+ movaps [rbp-0xC0], xmm7
call _object_getClass
- movq %rax, %rdi
- movq sel_forwardingTargetForSelector_(%rip), %rsi
+ mov rdi, rax
+ mov rsi, [rip+sel_forwardingTargetForSelector_]
call _class_respondsToSelector
- testq %rax, %rax
+ test rax, rax
jz 0f
- movq -0x10(%rbp), %rdi
- movq sel_forwardingTargetForSelector_(%rip), %rsi
- movq -0x18(%rbp), %rdx
+ mov rdi, [rbp-0x10]
+ mov rsi, [rip+sel_forwardingTargetForSelector_]
+ mov rdx, [rbp-0x18]
call _objc_msgSend
- testq %rax, %rax
+ test rax, rax
jz 0f
- cmpq -0x10(%rbp), %rax
+ cmp rax, [rbp-0x10]
je 0f
- movq %rax, %rdi
+ mov rdi, rax
/* Restore all arguments, except %rdi */
- movaps -0xC0(%rbp), %xmm7
- movaps -0xB0(%rbp), %xmm6
- movaps -0xA0(%rbp), %xmm5
- movaps -0x90(%rbp), %xmm4
- movaps -0x80(%rbp), %xmm3
- movaps -0x70(%rbp), %xmm2
- movaps -0x60(%rbp), %xmm1
- movaps -0x50(%rbp), %xmm0
- movq -0x38(%rbp), %r9
- movq -0x30(%rbp), %r8
- movq -0x28(%rbp), %rcx
- movq -0x20(%rbp), %rdx
- movq -0x18(%rbp), %rsi
- movq -0x8(%rbp), %rax
-
- movq %rbp, %rsp
- popq %rbp
+ movaps xmm7, [rbp-0xC0]
+ movaps xmm6, [rbp-0xB0]
+ movaps xmm5, [rbp-0xA0]
+ movaps xmm4, [rbp-0x90]
+ movaps xmm3, [rbp-0x80]
+ movaps xmm2, [rbp-0x70]
+ movaps xmm1, [rbp-0x60]
+ movaps xmm0, [rbp-0x50]
+ mov r9, [rbp-0x38]
+ mov r8, [rbp-0x30]
+ mov rcx, [rbp-0x28]
+ mov rdx, [rbp-0x20]
+ mov rsi, [rbp-0x18]
+ mov rax, [rbp-0x08]
+
+ mov rsp, rbp
+ pop rbp
jmp _objc_msgSend
0:
- movq -0x10(%rbp), %rdi
- movq -0x18(%rbp), %rsi
+ mov rdi, [rbp-0x10]
+ mov rsi, [rbp-0x18]
- movq %rbp, %rsp
- popq %rbp
+ mov rsp, rbp
+ pop rbp
jmp _of_method_not_found
_of_forward_stret:
- pushq %rbp
- movq %rsp, %rbp
+ push rbp
+ mov rbp, rsp
/* Save all arguments */
- subq $0xC0, %rsp /* 16-byte alignment */
- movq %rax, -0x8(%rbp)
- movq %rdi, -0x10(%rbp)
- movq %rsi, -0x18(%rbp)
- movq %rdx, -0x20(%rbp)
- movq %rcx, -0x28(%rbp)
- movq %r8, -0x30(%rbp)
- movq %r9, -0x38(%rbp)
- movaps %xmm0, -0x50(%rbp)
- movaps %xmm1, -0x60(%rbp)
- movaps %xmm2, -0x70(%rbp)
- movaps %xmm3, -0x80(%rbp)
- movaps %xmm4, -0x90(%rbp)
- movaps %xmm5, -0xA0(%rbp)
- movaps %xmm6, -0xB0(%rbp)
- movaps %xmm7, -0xC0(%rbp)
-
- movq %rsi, %rdi
+ sub rsp, 0xC0 /* 16-byte alignment */
+ mov [rbp-0x08], rax
+ mov [rbp-0x10], rdi
+ mov [rbp-0x18], rsi
+ mov [rbp-0x20], rdx
+ mov [rbp-0x28], rcx
+ mov [rbp-0x30], r8
+ mov [rbp-0x38], r9
+ movaps [rbp-0x50], xmm0
+ movaps [rbp-0x60], xmm1
+ movaps [rbp-0x70], xmm2
+ movaps [rbp-0x80], xmm3
+ movaps [rbp-0x90], xmm4
+ movaps [rbp-0xA0], xmm5
+ movaps [rbp-0xB0], xmm6
+ movaps [rbp-0xC0], xmm7
+
+ mov rdi, rsi
call _object_getClass
- movq %rax, %rdi
- movq sel_forwardingTargetForSelector_(%rip), %rsi
+ mov rdi, rax
+ mov rsi, [rip+sel_forwardingTargetForSelector_]
call _class_respondsToSelector
- testq %rax, %rax
+ test rax, rax
jz 0f
- movq -0x18(%rbp), %rdi
- movq sel_forwardingTargetForSelector_(%rip), %rsi
- movq -0x20(%rbp), %rdx
+ mov rdi, [rbp-0x18]
+ mov rsi, [rip+sel_forwardingTargetForSelector_]
+ mov rdx, [rbp-0x20]
call _objc_msgSend
- testq %rax, %rax
+ test rax, rax
jz 0f
- cmpq -0x18(%rbp), %rax
+ cmp rax, [rbp-0x18]
je 0f
- movq %rax, %rsi
+ mov rsi, rax
/* Restore all arguments, except %rsi */
- movaps -0xC0(%rbp), %xmm7
- movaps -0xB0(%rbp), %xmm6
- movaps -0xA0(%rbp), %xmm5
- movaps -0x90(%rbp), %xmm4
- movaps -0x80(%rbp), %xmm3
- movaps -0x70(%rbp), %xmm2
- movaps -0x60(%rbp), %xmm1
- movaps -0x50(%rbp), %xmm0
- movq -0x38(%rbp), %r9
- movq -0x30(%rbp), %r8
- movq -0x28(%rbp), %rcx
- movq -0x20(%rbp), %rdx
- movq -0x10(%rbp), %rdi
- movq -0x8(%rbp), %rax
-
- movq %rbp, %rsp
- popq %rbp
+ movaps xmm7, [rbp-0xC0]
+ movaps xmm6, [rbp-0xB0]
+ movaps xmm5, [rbp-0xA0]
+ movaps xmm4, [rbp-0x90]
+ movaps xmm3, [rbp-0x80]
+ movaps xmm2, [rbp-0x70]
+ movaps xmm1, [rbp-0x60]
+ movaps xmm0, [rbp-0x50]
+ mov r9, [rbp-0x38]
+ mov r8, [rbp-0x30]
+ mov rcx, [rbp-0x28]
+ mov rdx, [rbp-0x20]
+ mov rdi, [rbp-0x10]
+ mov rax, [rbp-0x08]
+
+ mov rsp, rbp
+ pop rbp
jmp _objc_msgSend_stret
0:
- movq -0x10(%rbp), %rdi
- movq -0x18(%rbp), %rsi
- movq -0x20(%rbp), %rdx
+ mov rdi, [rbp-0x10]
+ mov rsi, [rbp-0x18]
+ mov rdx, [rbp-0x20]
- movq %rbp, %rsp
- popq %rbp
+ mov rsp, rbp
+ pop rbp
jmp _of_method_not_found_stret
diff --git a/src/forwarding/forwarding-sparc-elf.S b/src/forwarding/forwarding-sparc-elf.S
new file mode 100644
index 00000000..112ec569
--- /dev/null
+++ b/src/forwarding/forwarding-sparc-elf.S
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017,
+ * 2018, 2019, 2020
+ * Jonathan Schleifer <js@nil.im>
+ *
+ * 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"
+
+#include "platform.h"
+
+.globl of_forward
+.globl of_forward_stret
+
+.section .text
+of_forward:
+ save %sp, -96, %sp
+
+ sethi %hi(_GLOBAL_OFFSET_TABLE_ - 4), %l7
+ call add_pc
+ add %l7, %lo(_GLOBAL_OFFSET_TABLE_ + 4), %l7
+
+ mov %i0, %o0
+ call object_getClass
+ nop
+
+ sethi %hi(sel_forwardingTargetForSelector_), %o1
+ or %o1, %lo(sel_forwardingTargetForSelector_), %o1
+ ld [%l7 + %o1], %o1
+ call class_respondsToSelector
+ nop
+
+ cmp %o0, 0
+ be 0f
+
+ mov %i0, %o0
+ sethi %hi(sel_forwardingTargetForSelector_), %o1
+ or %o1, %lo(sel_forwardingTargetForSelector_), %o1
+ ld [%l7 + %o1], %o1
+ call objc_msg_lookup
+ nop
+ mov %o0, %l0
+
+ mov %i0, %o0
+ sethi %hi(sel_forwardingTargetForSelector_), %o1
+ or %o1, %lo(sel_forwardingTargetForSelector_), %o1
+ ld [%l7 + %o1], %o1
+ jmpl %l0, %o7
+ mov %i1, %o2
+
+ cmp %o0, 0
+ be 0f
+ cmp %o0, %i0
+ be 0f
+
+ mov %o0, %i0
+ call objc_msg_lookup
+ mov %i1, %o1
+
+ jmpl %o0, %g0
+ restore
+
+0:
+ call of_method_not_found
+ restore
+.type of_forward, %function
+.size of_forward, .-of_forward
+
+of_forward_stret:
+ save %sp, -96, %sp
+
+ sethi %hi(_GLOBAL_OFFSET_TABLE_ - 4), %l7
+ call add_pc
+ add %l7, %lo(_GLOBAL_OFFSET_TABLE_ + 4), %l7
+
+ mov %i1, %o0
+ call object_getClass
+ nop
+
+ sethi %hi(sel_forwardingTargetForSelector_), %o1
+ or %o1, %lo(sel_forwardingTargetForSelector_), %o1
+ ld [%l7 + %o1], %o1
+ call class_respondsToSelector
+ nop
+
+ cmp %o0, 0
+ be 0f
+
+ mov %i1, %o0
+ sethi %hi(sel_forwardingTargetForSelector_), %o1
+ or %o1, %lo(sel_forwardingTargetForSelector_), %o1
+ ld [%l7 + %o1], %o1
+ call objc_msg_lookup
+ nop
+ mov %o0, %l0
+
+ mov %i1, %o0
+ sethi %hi(sel_forwardingTargetForSelector_), %o1
+ or %o1, %lo(sel_forwardingTargetForSelector_), %o1
+ ld [%l7 + %o1], %o1
+ jmpl %l0, %o7
+ mov %i2, %o2
+
+ cmp %o0, 0
+ be 0f
+ cmp %o0, %i1
+ be 0f
+
+ mov %o0, %i1
+ call objc_msg_lookup
+ mov %i2, %o1
+
+ jmpl %o0, %g0
+ restore
+
+0:
+ call of_method_not_found_stret
+ restore
+.type of_forward_stret, %function
+.size of_forward_stret, .-of_forward_stret
+
+init:
+ save %sp, -96, %sp
+
+ sethi %hi(_GLOBAL_OFFSET_TABLE_ - 4), %l7
+ call add_pc
+ add %l7, %lo(_GLOBAL_OFFSET_TABLE_ + 4), %l7
+
+ sethi %hi(module), %i0
+ or %i0, %lo(module), %i0
+ ld [%l7 + %i0], %i0
+
+ call __objc_exec_class
+ restore
+
+add_pc:
+ jmp %o7 + 8
+ add %l7, %o7, %l7
+
+#ifdef OF_SOLARIS
+.section .init_array, "aw"
+#else
+.section .ctors, "aw", %progbits
+#endif
+ .word init
+
+.section .rodata
+str_forwardingTargetForSelector_:
+ .asciz "forwardingTargetForSelector:"
+
+.section .data
+sel_forwardingTargetForSelector_:
+ .word str_forwardingTargetForSelector_, 0
+ .word 0, 0
+symtab:
+ .word 0, sel_forwardingTargetForSelector_
+ .half 0, 0
+ .word 0
+ .word 0
+module:
+ .word 8, 16, 0, symtab
+
+#ifdef OF_LINUX
+.section .note.GNU-stack, "", %progbits
+#endif
diff --git a/src/forwarding/forwarding-sparc64-elf.S b/src/forwarding/forwarding-sparc64-elf.S
index 09766186..57df0edb 100644
--- a/src/forwarding/forwarding-sparc64-elf.S
+++ b/src/forwarding/forwarding-sparc64-elf.S
@@ -63,11 +63,9 @@ of_forward:
call class_respondsToSelector
nop
- cmp %o0, 0
- be,pn %xcc, 0f
- nop
+ brz,pn %o0, 0f
- mov %i0, %o0
+ mov %i0, %o0
sethi %hi(sel_forwardingTargetForSelector_), %o1
or %o1, %lo(sel_forwardingTargetForSelector_), %o1
ldx [%l7 + %o1], %o1
@@ -82,14 +80,11 @@ of_forward:
jmpl %l0, %o7
mov %i1, %o2
- cmp %o0, 0
+ brz,pn %o0, 0f
+ cmp %o0, %i0
be,pn %xcc, 0f
- nop
- cmp %o0, %i0
- be,pn %xcc, 0f
- nop
- mov %o0, %i0
+ mov %o0, %i0
call objc_msg_lookup
mov %i1, %o1
@@ -161,11 +156,9 @@ of_forward_stret:
call class_respondsToSelector
nop
- cmp %o0, 0
- be,pn %xcc, 0f
- nop
+ brz,pn %o0, 0f
- mov %i1, %o0
+ mov %i1, %o0
sethi %hi(sel_forwardingTargetForSelector_), %o1
or %o1, %lo(sel_forwardingTargetForSelector_), %o1
ldx [%l7 + %o1], %o1
@@ -180,14 +173,11 @@ of_forward_stret:
jmpl %l0, %o7
mov %i2, %o2
- cmp %o0, 0
+ brz,pn %o0, 0f
+ cmp %o0, %i1
be,pn %xcc, 0f
- nop
- cmp %o0, %i1
- be,pn %xcc, 0f
- nop
- mov %o0, %i1
+ mov %o0, %i1
call objc_msg_lookup
mov %i2, %o1
diff --git a/src/forwarding/forwarding-x86-elf.S b/src/forwarding/forwarding-x86-elf.S
index 861a06e1..471719f4 100644
--- a/src/forwarding/forwarding-x86-elf.S
+++ b/src/forwarding/forwarding-x86-elf.S
@@ -19,171 +19,161 @@
#include "platform.h"
+.intel_syntax noprefix
+
.globl of_forward
.globl of_forward_stret
.section .text
of_forward:
- pushl %ebp
- movl %esp, %ebp
+ push ebp
+ mov ebp, esp
- pushl %ebx
- subl $20, %esp
+ push ebx
+ sub esp, 20
call get_eip
+ add ebx, offset _GLOBAL_OFFSET_TABLE_
+
+ mov eax, [ebp+8]
+ mov [esp], eax
+ call object_getClass@PLT
+
+ mov [esp], eax
+ lea eax, [ebx+sel_forwardingTargetForSelector_@GOTOFF]
+ mov [esp+4], eax
+ call class_respondsToSelector@PLT
+
+ test eax, eax
+ jz short 0f
+
+ mov eax, [ebp+8]
+ mov [esp], eax
+ lea eax, [ebx+sel_forwardingTargetForSelector_@GOTOFF]
+ mov [esp+4], eax
+ call objc_msg_lookup@PLT
+
+ mov edx, [ebp+8]
+ mov [esp], edx
+ lea edx, [ebx+sel_forwardingTargetForSelector_@GOTOFF]
+ mov [esp+4], edx
+ mov edx, [ebp+12]
+ mov [esp+8], edx
+ call eax
+
+ test eax, eax
+ jz short 0f
+ cmp eax, [ebp+8]
+ je short 0f
+
+ mov [ebp+8], eax
+ mov [esp], eax
+ mov eax, [ebp+12]
+ mov [esp+4], eax
+ call objc_msg_lookup@PLT
+
+ add esp, 20
+ pop ebx
+ pop ebp
+
+ jmp eax
+
0:
- addl $_GLOBAL_OFFSET_TABLE_, %ebx
-
- movl 8(%ebp), %eax
- movl %eax, (%esp)
- movl object_getClass@GOT(%ebx), %eax
- call *%eax
-
- movl %eax, (%esp)
- leal sel_forwardingTargetForSelector_@GOTOFF(%ebx), %eax
- movl %eax, 4(%esp)
- movl class_respondsToSelector@GOT(%ebx), %eax
- call *%eax
-
- testl %eax, %eax
- jz 1f
-
- movl 8(%ebp), %eax
- movl %eax, (%esp)
- leal sel_forwardingTargetForSelector_@GOTOFF(%ebx), %eax
- movl %eax, 4(%esp)
- movl objc_msg_lookup@GOT(%ebx), %eax
- call *%eax
-
- movl 8(%ebp), %edx
- movl %edx, (%esp)
- leal sel_forwardingTargetForSelector_@GOTOFF(%ebx), %edx
- movl %edx, 4(%esp)
- movl 12(%ebp), %edx
- movl %edx, 8(%esp)
- call *%eax
-
- testl %eax, %eax
- jz 1f
- cmpl 8(%ebp), %eax
- je 1f
-
- movl %eax, 8(%ebp)
- movl %eax, (%esp)
- movl 12(%ebp), %eax
- movl %eax, 4(%esp)
- movl objc_msg_lookup@GOT(%ebx), %eax
- call *%eax
-
- addl $20, %esp
- popl %ebx
- popl %ebp
-
- jmp *%eax
-
-1:
- movl of_method_not_found@GOT(%ebx), %eax
-
- addl $20, %esp
- popl %ebx
- popl %ebp
-
- jmp *%eax
+ lea eax, [ebx+of_method_not_found@GOTOFF]
+
+ add esp, 20
+ pop ebx
+ pop ebp
+
+ jmp eax
.type of_forward, %function
.size of_forward, .-of_forward
of_forward_stret:
- pushl %ebp
- movl %esp, %ebp
+ push ebp
+ mov ebp, esp
- pushl %ebx
- subl $20, %esp
+ push ebx
+ sub esp, 20
call get_eip
+ add ebx, offset _GLOBAL_OFFSET_TABLE_
+
+ mov eax, [ebp+12]
+ mov [esp], eax
+ call object_getClass@PLT
+
+ mov [esp], eax
+ lea eax, [ebx+sel_forwardingTargetForSelector_@GOTOFF]
+ mov [esp+4], eax
+ call class_respondsToSelector@PLT
+
+ test eax, eax
+ jz short 0f
+
+ mov eax, [ebp+12]
+ mov [esp], eax
+ lea eax, [ebx+sel_forwardingTargetForSelector_@GOTOFF]
+ mov [esp+4], eax
+ call objc_msg_lookup@PLT
+
+ mov edx, [ebp+12]
+ mov [esp], edx
+ lea edx, [ebx+sel_forwardingTargetForSelector_@GOTOFF]
+ mov [esp+4], edx
+ mov edx, [ebp+16]
+ mov [esp+8], edx
+ call eax
+
+ test eax, eax
+ jz short 0f
+ cmp eax, [ebp+12]
+ je short 0f
+
+ mov [ebp+12], eax
+ mov [esp], eax
+ mov eax, [ebp+16]
+ mov [esp+4], eax
+ call objc_msg_lookup_stret@PLT
+
+ add esp, 20
+ pop ebx
+ pop ebp
+
+ jmp eax
+
0:
- addl $_GLOBAL_OFFSET_TABLE_, %ebx
-
- movl 12(%ebp), %eax
- movl %eax, (%esp)
- movl object_getClass@GOT(%ebx), %eax
- call *%eax
-
- movl %eax, (%esp)
- leal sel_forwardingTargetForSelector_@GOTOFF(%ebx), %eax
- movl %eax, 4(%esp)
- movl class_respondsToSelector@GOT(%ebx), %eax
- call *%eax
-
- testl %eax, %eax
- jz 1f
-
- movl 12(%ebp), %eax
- movl %eax, (%esp)
- leal sel_forwardingTargetForSelector_@GOTOFF(%ebx), %eax
- movl %eax, 4(%esp)
- movl objc_msg_lookup@GOT(%ebx), %eax
- call *%eax
-
- movl 12(%ebp), %edx
- movl %edx, (%esp)
- leal sel_forwardingTargetForSelector_@GOTOFF(%ebx), %edx
- movl %edx, 4(%esp)
- movl 16(%ebp), %edx
- movl %edx, 8(%esp)
- call *%eax
-
- testl %eax, %eax
- jz 1f
- cmpl 12(%ebp), %eax
- je 1f
-
- movl %eax, 12(%ebp)
- movl %eax, (%esp)
- movl 16(%ebp), %eax
- movl %eax, 4(%esp)
- movl objc_msg_lookup_stret@GOT(%ebx), %eax
- call *%eax
-
- addl $20, %esp
- popl %ebx
- popl %ebp
-
- jmp *%eax
-
-1:
- movl of_method_not_found_stret@GOT(%ebx), %eax
-
- addl $20, %esp
- popl %ebx
- popl %ebp
-
- jmp *%eax
+ lea eax, [ebx+of_method_not_found_stret@GOTOFF]
+
+ add esp, 20
+ pop ebx
+ pop ebp
+
+ jmp eax
.type of_forward_stret, %function
.size of_forward_stret, .-of_forward_stret
init:
- pushl %ebp
- movl %esp, %ebp
+ push ebp
+ mov ebp, esp
- pushl %ebx
- subl $4, %esp
+ push ebx
+ sub esp, 4
call get_eip
-0:
- add $_GLOBAL_OFFSET_TABLE_, %ebx
+ add ebx, offset _GLOBAL_OFFSET_TABLE_
- leal module@GOTOFF(%ebx), %eax
- movl %eax, (%esp)
- movl __objc_exec_class@GOT(%ebx), %eax
- call *%eax
+ lea eax, [ebx+module@GOTOFF]
+ mov [esp], eax
+ call __objc_exec_class@PLT
- addl $4, %esp
- popl %ebx
- popl %ebp
+ add esp, 4
+ pop ebx
+ pop ebp
ret
get_eip:
- movl (%esp), %ebx
+ mov ebx, [esp]
ret
#ifdef OF_SOLARIS
diff --git a/src/forwarding/forwarding-x86-win32.S b/src/forwarding/forwarding-x86-win32.S
index 391403f5..a3cc1fab 100644
--- a/src/forwarding/forwarding-x86-win32.S
+++ b/src/forwarding/forwarding-x86-win32.S
@@ -17,163 +17,140 @@
#include "config.h"
+.intel_syntax noprefix
+
.globl _of_forward
.globl _of_forward_stret
.section .text
_of_forward:
- pushl %ebp
- movl %esp, %ebp
-
- pushl %ebx
- subl $20, %esp
+ push ebp
+ mov ebp, esp
+
+ push ebx
+ sub esp, 20
+
+ mov eax, [ebp+8]
+ mov [esp], eax
+ call _object_getClass
+
+ mov [esp], eax
+ mov eax, offset sel_forwardingTargetForSelector_
+ mov [esp+4], eax
+ call _class_respondsToSelector
+
+ test eax, eax
+ jz short 0f
+
+ mov eax, [ebp+8]
+ mov [esp], eax
+ mov eax, offset sel_forwardingTargetForSelector_
+ mov [esp+4], eax
+ call _objc_msg_lookup
+
+ mov edx, [ebp+8]
+ mov [esp], edx
+ mov edx, offset sel_forwardingTargetForSelector_
+ mov [esp+4], edx
+ mov edx, [ebp+12]
+ mov [esp+8], edx
+ call eax
+
+ test eax, eax
+ jz short 0f
+ cmp eax, [ebp+8]
+ je short 0f
+
+ mov [ebp+8], eax
+ mov [esp], eax
+ mov eax, [ebp+12]
+ mov [esp+4], eax
+ call _objc_msg_lookup
+
+ add esp, 20
+ pop ebx
+ pop ebp
+
+ jmp eax
- call get_eip
0:
+ add esp, 20
+ pop ebx
+ pop ebp
- movl 8(%ebp), %eax
- movl %eax, (%esp)
- leal _object_getClass-0b(%ebx), %eax
- call *%eax
-
- movl %eax, (%esp)
- leal sel_forwardingTargetForSelector_-0b(%ebx), %eax
- movl %eax, 4(%esp)
- leal _class_respondsToSelector-0b(%ebx), %eax
- call *%eax
-
- testl %eax, %eax
- jz 1f
-
- movl 8(%ebp), %eax
- movl %eax, (%esp)
- leal sel_forwardingTargetForSelector_-0b(%ebx), %eax
- movl %eax, 4(%esp)
- leal _objc_msg_lookup-0b(%ebx), %eax
- call *%eax
-
- movl 8(%ebp), %edx
- movl %edx, (%esp)
- leal sel_forwardingTargetForSelector_-0b(%ebx), %edx
- movl %edx, 4(%esp)
- movl 12(%ebp), %edx
- movl %edx, 8(%esp)
- call *%eax
-
- testl %eax, %eax
- jz 1f
- cmpl 8(%ebp), %eax
- je 1f
-
- movl %eax, 8(%ebp)
- movl %eax, (%esp)
- movl 12(%ebp), %eax
- movl %eax, 4(%esp)
- leal _objc_msg_lookup-0b(%ebx), %eax
- call *%eax
-
- addl $20, %esp
- popl %ebx
- popl %ebp
-
- jmp *%eax
-
-1:
- leal _of_method_not_found-0b(%ebx), %eax
-
- addl $20, %esp
- popl %ebx
- popl %ebp
-
- jmp *%eax
+ jmp _of_method_not_found
_of_forward_stret:
- pushl %ebp
- movl %esp, %ebp
-
- pushl %ebx
- subl $20, %esp
+ push ebp
+ mov ebp, esp
+
+ push ebx
+ sub esp, 20
+
+ mov eax, [ebp+12]
+ mov [esp], eax
+ call _object_getClass
+
+ mov [esp], eax
+ mov eax, offset sel_forwardingTargetForSelector_
+ mov [esp+4], eax
+ call _class_respondsToSelector
+
+ test eax, eax
+ jz short 0f
+
+ mov eax, [ebp+12]
+ mov [esp], eax
+ mov eax, offset sel_forwardingTargetForSelector_
+ mov [esp+4], eax
+ call _objc_msg_lookup
+
+ mov edx, [ebp+12]
+ mov [esp], edx
+ mov edx, offset sel_forwardingTargetForSelector_
+ mov [esp+4], edx
+ mov edx, [ebp+16]
+ mov [esp+8], edx
+ call eax
+
+ test eax, eax
+ jz short 0f
+ cmp eax, [ebp+12]
+ je short 0f
+
+ mov [ebp+12], eax
+ mov [esp], eax
+ mov eax, [ebp+16]
+ mov [esp+4], eax
+ call _objc_msg_lookup_stret
+
+ add esp, 20
+ pop ebx
+ pop ebp
+
+ jmp eax
- call get_eip
0:
+ add esp, 20
+ pop ebx
+ pop ebp
- movl 12(%ebp), %eax
- movl %eax, (%esp)
- leal _object_getClass-0b(%ebx), %eax
- call *%eax
-
- movl %eax, (%esp)
- leal sel_forwardingTargetForSelector_-0b(%ebx), %eax
- movl %eax, 4(%esp)
- leal _class_respondsToSelector-0b(%ebx), %eax
- call *%eax
-
- testl %eax, %eax
- jz 1f
-
- movl 12(%ebp), %eax
- movl %eax, (%esp)
- leal sel_forwardingTargetForSelector_-0b(%ebx), %eax
- movl %eax, 4(%esp)
- leal _objc_msg_lookup-0b(%ebx), %eax
- call *%eax
-
- movl 12(%ebp), %edx
- movl %edx, (%esp)
- leal sel_forwardingTargetForSelector_-0b(%ebx), %edx
- movl %edx, 4(%esp)
- movl 16(%ebp), %edx
- movl %edx, 8(%esp)
- call *%eax
-
- testl %eax, %eax
- jz 1f
- cmpl 12(%ebp), %eax
- je 1f
-
- movl %eax, 12(%ebp)
- movl %eax, (%esp)
- movl 16(%ebp), %eax
- movl %eax, 4(%esp)
- leal _objc_msg_lookup_stret-0b(%ebx), %eax
- call *%eax
-
- addl $20, %esp
- popl %ebx
- popl %ebp
-
- jmp *%eax
-
-1:
- leal _of_method_not_found_stret-0b(%ebx), %eax
-
- addl $20, %esp
- popl %ebx
- popl %ebp
-
- jmp *%eax
+ jmp _of_method_not_found_stret
init:
- pushl %ebp
- movl %esp, %ebp
+ push ebp
+ mov ebp, esp
- pushl %ebx
- subl $4, %esp
+ push ebx
+ sub esp, 4
- call get_eip
-0:
- leal module-0b(%ebx), %eax
- movl %eax, (%esp)
- leal ___objc_exec_class-0b(%ebx), %eax
- call *%eax
-
- addl $4, %esp
- popl %ebx
- popl %ebp
- ret
+ mov eax, offset module
+ mov [esp], eax
+ call ___objc_exec_class
-get_eip:
- movl (%esp), %ebx
+ add esp, 4
+ pop ebx
+ pop ebp
ret
.section .ctors, "aw"
diff --git a/src/forwarding/forwarding-x86_64-elf.S b/src/forwarding/forwarding-x86_64-elf.S
index ee0752b3..b485d702 100644
--- a/src/forwarding/forwarding-x86_64-elf.S
+++ b/src/forwarding/forwarding-x86_64-elf.S
@@ -19,184 +19,186 @@
#include "platform.h"
+.intel_syntax noprefix
+
.globl of_forward
.globl of_forward_stret
.section .text
of_forward:
- pushq %rbp
- movq %rsp, %rbp
+ push rbp
+ mov rbp, rsp
/* Save all arguments */
- subq $0xC0, %rsp /* 16-byte alignment */
- movq %rax, -0x8(%rbp)
- movq %rdi, -0x10(%rbp)
- movq %rsi, -0x18(%rbp)
- movq %rdx, -0x20(%rbp)
- movq %rcx, -0x28(%rbp)
- movq %r8, -0x30(%rbp)
- movq %r9, -0x38(%rbp)
- movaps %xmm0, -0x50(%rbp)
- movaps %xmm1, -0x60(%rbp)
- movaps %xmm2, -0x70(%rbp)
- movaps %xmm3, -0x80(%rbp)
- movaps %xmm4, -0x90(%rbp)
- movaps %xmm5, -0xA0(%rbp)
- movaps %xmm6, -0xB0(%rbp)
- movaps %xmm7, -0xC0(%rbp)
+ sub rsp, 0xC0 /* 16-byte alignment */
+ mov [rbp-0x08], rax
+ mov [rbp-0x10], rdi
+ mov [rbp-0x18], rsi
+ mov [rbp-0x20], rdx
+ mov [rbp-0x28], rcx
+ mov [rbp-0x30], r8
+ mov [rbp-0x38], r9
+ movaps [rbp-0x50], xmm0
+ movaps [rbp-0x60], xmm1
+ movaps [rbp-0x70], xmm2
+ movaps [rbp-0x80], xmm3
+ movaps [rbp-0x90], xmm4
+ movaps [rbp-0xA0], xmm5
+ movaps [rbp-0xB0], xmm6
+ movaps [rbp-0xC0], xmm7
call object_getClass@PLT
- movq %rax, %rdi
- leaq sel_forwardingTargetForSelector_(%rip), %rsi
+ mov rdi, rax
+ lea rsi, [rip+sel_forwardingTargetForSelector_]
call class_respondsToSelector@PLT
- testq %rax, %rax
- jz 0f
+ test rax, rax
+ jz short 0f
- movq -0x10(%rbp), %rdi
- leaq sel_forwardingTargetForSelector_(%rip), %rsi
+ mov rdi, [rbp-0x10]
+ lea rsi, [rip+sel_forwardingTargetForSelector_]
call objc_msg_lookup@PLT
- movq -0x10(%rbp), %rdi
- leaq sel_forwardingTargetForSelector_(%rip), %rsi
- movq -0x18(%rbp), %rdx
- call *%rax
+ mov rdi, [rbp-0x10]
+ lea rsi, [rip+sel_forwardingTargetForSelector_]
+ mov rdx, [rbp-0x18]
+ call rax
- testq %rax, %rax
- jz 0f
- cmpq -0x10(%rbp), %rax
- je 0f
+ test rax, rax
+ jz short 0f
+ cmp rax, [rbp-0x10]
+ je short 0f
- movq %rax, -0x10(%rbp)
+ mov [rbp-0x10], rax
- movq %rax, %rdi
- movq -0x18(%rbp), %rsi
+ mov rdi, rax
+ mov rsi, [rbp-0x18]
call objc_msg_lookup@PLT
- movq %rax, %r11
+ mov r11, rax
/* Restore all arguments */
- movaps -0xC0(%rbp), %xmm7
- movaps -0xB0(%rbp), %xmm6
- movaps -0xA0(%rbp), %xmm5
- movaps -0x90(%rbp), %xmm4
- movaps -0x80(%rbp), %xmm3
- movaps -0x70(%rbp), %xmm2
- movaps -0x60(%rbp), %xmm1
- movaps -0x50(%rbp), %xmm0
- movq -0x38(%rbp), %r9
- movq -0x30(%rbp), %r8
- movq -0x28(%rbp), %rcx
- movq -0x20(%rbp), %rdx
- movq -0x18(%rbp), %rsi
- movq -0x10(%rbp), %rdi
- movq -0x8(%rbp), %rax
-
- movq %rbp, %rsp
- popq %rbp
-
- jmpq *%r11
+ movaps xmm7, [rbp-0xC0]
+ movaps xmm6, [rbp-0xB0]
+ movaps xmm5, [rbp-0xA0]
+ movaps xmm4, [rbp-0x90]
+ movaps xmm3, [rbp-0x80]
+ movaps xmm2, [rbp-0x70]
+ movaps xmm1, [rbp-0x60]
+ movaps xmm0, [rbp-0x50]
+ mov r9, [rbp-0x38]
+ mov r8, [rbp-0x30]
+ mov rcx, [rbp-0x28]
+ mov rdx, [rbp-0x20]
+ mov rsi, [rbp-0x18]
+ mov rdi, [rbp-0x10]
+ mov rax, [rbp-0x08]
+
+ mov rsp, rbp
+ pop rbp
+
+ jmp r11
0:
- movq -0x10(%rbp), %rdi
- movq -0x18(%rbp), %rsi
+ mov rdi, [rbp-0x10]
+ mov rsi, [rbp-0x18]
- movq %rbp, %rsp
- popq %rbp
+ mov rsp, rbp
+ pop rbp
jmp of_method_not_found@PLT
.type of_forward, %function
.size of_forward, .-of_forward
of_forward_stret:
- pushq %rbp
- movq %rsp, %rbp
+ push rbp
+ mov rbp, rsp
/* Save all arguments */
- subq $0xC0, %rsp /* 16-byte alignment */
- movq %rax, -0x8(%rbp)
- movq %rdi, -0x10(%rbp)
- movq %rsi, -0x18(%rbp)
- movq %rdx, -0x20(%rbp)
- movq %rcx, -0x28(%rbp)
- movq %r8, -0x30(%rbp)
- movq %r9, -0x38(%rbp)
- movaps %xmm0, -0x50(%rbp)
- movaps %xmm1, -0x60(%rbp)
- movaps %xmm2, -0x70(%rbp)
- movaps %xmm3, -0x80(%rbp)
- movaps %xmm4, -0x90(%rbp)
- movaps %xmm5, -0xA0(%rbp)
- movaps %xmm6, -0xB0(%rbp)
- movaps %xmm7, -0xC0(%rbp)
-
- movq %rsi, %rdi
+ sub rsp, 0xC0 /* 16-byte alignment */
+ mov [rbp-0x08], rax
+ mov [rbp-0x10], rdi
+ mov [rbp-0x18], rsi
+ mov [rbp-0x20], rdx
+ mov [rbp-0x28], rcx
+ mov [rbp-0x30], r8
+ mov [rbp-0x38], r9
+ movaps [rbp-0x50], xmm0
+ movaps [rbp-0x60], xmm1
+ movaps [rbp-0x70], xmm2
+ movaps [rbp-0x80], xmm3
+ movaps [rbp-0x90], xmm4
+ movaps [rbp-0xA0], xmm5
+ movaps [rbp-0xB0], xmm6
+ movaps [rbp-0xC0], xmm7
+
+ mov rdi, rsi
call object_getClass@PLT
- movq %rax, %rdi
- leaq sel_forwardingTargetForSelector_(%rip), %rsi
+ mov rdi, rax
+ lea rsi, [rip+sel_forwardingTargetForSelector_]
call class_respondsToSelector@PLT
- testq %rax, %rax
- jz 0f
+ test rax, rax
+ jz short 0f
- movq -0x18(%rbp), %rdi
- leaq sel_forwardingTargetForSelector_(%rip), %rsi
+ mov rdi, [rbp-0x18]
+ lea rsi, [rip+sel_forwardingTargetForSelector_]
call objc_msg_lookup@PLT
- movq -0x18(%rbp), %rdi
- leaq sel_forwardingTargetForSelector_(%rip), %rsi
- movq -0x20(%rbp), %rdx
- call *%rax
+ mov rdi, [rbp-0x18]
+ lea rsi, [rip+sel_forwardingTargetForSelector_]
+ mov rdx, [rbp-0x20]
+ call rax
- testq %rax, %rax
- jz 0f
- cmpq -0x18(%rbp), %rax
- je 0f
+ test rax, rax
+ jz short 0f
+ cmp rax, [rbp-0x18]
+ je short 0f
- movq %rax, -0x18(%rbp)
+ mov [rbp-0x18], rax
- movq %rax, %rdi
- movq -0x20(%rbp), %rsi
+ mov rdi, rax
+ mov rsi, [rbp-0x20]
call objc_msg_lookup_stret@PLT
- movq %rax, %r11
+ mov r11, rax
/* Restore all arguments */
- movaps -0xC0(%rbp), %xmm7
- movaps -0xB0(%rbp), %xmm6
- movaps -0xA0(%rbp), %xmm5
- movaps -0x90(%rbp), %xmm4
- movaps -0x80(%rbp), %xmm3
- movaps -0x70(%rbp), %xmm2
- movaps -0x60(%rbp), %xmm1
- movaps -0x50(%rbp), %xmm0
- movq -0x38(%rbp), %r9
- movq -0x30(%rbp), %r8
- movq -0x28(%rbp), %rcx
- movq -0x20(%rbp), %rdx
- movq -0x18(%rbp), %rsi
- movq -0x10(%rbp), %rdi
- movq -0x8(%rbp), %rax
-
- movq %rbp, %rsp
- popq %rbp
-
- jmpq *%r11
+ movaps xmm7, [rbp-0xC0]
+ movaps xmm6, [rbp-0xB0]
+ movaps xmm5, [rbp-0xA0]
+ movaps xmm4, [rbp-0x90]
+ movaps xmm3, [rbp-0x80]
+ movaps xmm2, [rbp-0x70]
+ movaps xmm1, [rbp-0x60]
+ movaps xmm0, [rbp-0x50]
+ mov r9, [rbp-0x38]
+ mov r8, [rbp-0x30]
+ mov rcx, [rbp-0x28]
+ mov rdx, [rbp-0x20]
+ mov rsi, [rbp-0x18]
+ mov rdi, [rbp-0x10]
+ mov rax, [rbp-0x08]
+
+ mov rsp, rbp
+ pop rbp
+
+ jmp r11
0:
- movq -0x10(%rbp), %rdi
- movq -0x18(%rbp), %rsi
- movq -0x20(%rbp), %rdx
+ mov rdi, [rbp-0x10]
+ mov rsi, [rbp-0x18]
+ mov rdx, [rbp-0x20]
- movq %rbp, %rsp
- popq %rbp
+ mov rsp, rbp
+ pop rbp
jmp of_method_not_found_stret@PLT
.type of_forward_stret, %function
.size of_forward_stret, .-of_forward_stret
init:
- leaq module(%rip), %rdi
+ lea rdi, [rip+module]
jmp __objc_exec_class@PLT
#ifdef OF_SOLARIS
diff --git a/src/forwarding/forwarding-x86_64-macho.S b/src/forwarding/forwarding-x86_64-macho.S
index bdc1a797..496bfdde 100644
--- a/src/forwarding/forwarding-x86_64-macho.S
+++ b/src/forwarding/forwarding-x86_64-macho.S
@@ -19,180 +19,182 @@
#include "platform.h"
+.intel_syntax noprefix
+
.globl _of_forward
.globl _of_forward_stret
.section __TEXT, __text, regular, pure_instructions
_of_forward:
- pushq %rbp
- movq %rsp, %rbp
+ push rbp
+ mov rbp, rsp
/* Save all arguments */
- subq $0xC0, %rsp /* 16-byte alignment */
- movq %rax, -0x8(%rbp)
- movq %rdi, -0x10(%rbp)
- movq %rsi, -0x18(%rbp)
- movq %rdx, -0x20(%rbp)
- movq %rcx, -0x28(%rbp)
- movq %r8, -0x30(%rbp)
- movq %r9, -0x38(%rbp)
- movaps %xmm0, -0x50(%rbp)
- movaps %xmm1, -0x60(%rbp)
- movaps %xmm2, -0x70(%rbp)
- movaps %xmm3, -0x80(%rbp)
- movaps %xmm4, -0x90(%rbp)
- movaps %xmm5, -0xA0(%rbp)
- movaps %xmm6, -0xB0(%rbp)
- movaps %xmm7, -0xC0(%rbp)
+ sub rsp, 0xC0 /* 16-byte alignment */
+ mov [rbp-0x08], rax
+ mov [rbp-0x10], rdi
+ mov [rbp-0x18], rsi
+ mov [rbp-0x20], rdx
+ mov [rbp-0x28], rcx
+ mov [rbp-0x30], r8
+ mov [rbp-0x38], r9
+ movaps [rbp-0x50], xmm0
+ movaps [rbp-0x60], xmm1
+ movaps [rbp-0x70], xmm2
+ movaps [rbp-0x80], xmm3
+ movaps [rbp-0x90], xmm4
+ movaps [rbp-0xA0], xmm5
+ movaps [rbp-0xB0], xmm6
+ movaps [rbp-0xC0], xmm7
call _object_getClass
- movq %rax, %rdi
- leaq sel_forwardingTargetForSelector_(%rip), %rsi
+ mov rdi, rax
+ lea rsi, [rip+sel_forwardingTargetForSelector_]
call _class_respondsToSelector
- testq %rax, %rax
+ test rax, rax
jz 0f
- movq -0x10(%rbp), %rdi
- leaq sel_forwardingTargetForSelector_(%rip), %rsi
+ mov rdi, [rbp-0x10]
+ lea rsi, [rip+sel_forwardingTargetForSelector_]
call _objc_msg_lookup
- movq -0x10(%rbp), %rdi
- leaq sel_forwardingTargetForSelector_(%rip), %rsi
- movq -0x18(%rbp), %rdx
- call *%rax
+ mov rdi, [rbp-0x10]
+ lea rsi, [rip+sel_forwardingTargetForSelector_]
+ mov rdx, [rbp-0x18]
+ call rax
- testq %rax, %rax
+ test rax, rax
jz 0f
- cmpq -0x10(%rbp), %rax
+ cmp rax, [rbp-0x10]
je 0f
- movq %rax, -0x10(%rbp)
+ mov [rbp-0x10], rax
- movq %rax, %rdi
- movq -0x18(%rbp), %rsi
+ mov rdi, rax
+ mov rsi, [rbp-0x18]
call _objc_msg_lookup
- movq %rax, %r11
+ mov r11, rax
/* Restore all arguments */
- movaps -0xC0(%rbp), %xmm7
- movaps -0xB0(%rbp), %xmm6
- movaps -0xA0(%rbp), %xmm5
- movaps -0x90(%rbp), %xmm4
- movaps -0x80(%rbp), %xmm3
- movaps -0x70(%rbp), %xmm2
- movaps -0x60(%rbp), %xmm1
- movaps -0x50(%rbp), %xmm0
- movq -0x38(%rbp), %r9
- movq -0x30(%rbp), %r8
- movq -0x28(%rbp), %rcx
- movq -0x20(%rbp), %rdx
- movq -0x18(%rbp), %rsi
- movq -0x10(%rbp), %rdi
- movq -0x8(%rbp), %rax
-
- movq %rbp, %rsp
- popq %rbp
-
- jmpq *%r11
+ movaps xmm7, [rbp-0xC0]
+ movaps xmm6, [rbp-0xB0]
+ movaps xmm5, [rbp-0xA0]
+ movaps xmm4, [rbp-0x90]
+ movaps xmm3, [rbp-0x80]
+ movaps xmm2, [rbp-0x70]
+ movaps xmm1, [rbp-0x60]
+ movaps xmm0, [rbp-0x50]
+ mov r9, [rbp-0x38]
+ mov r8, [rbp-0x30]
+ mov rcx, [rbp-0x28]
+ mov rdx, [rbp-0x20]
+ mov rsi, [rbp-0x18]
+ mov rdi, [rbp-0x10]
+ mov rax, [rbp-0x08]
+
+ mov rsp, rbp
+ pop rbp
+
+ jmp r11
0:
- movq -0x10(%rbp), %rdi
- movq -0x18(%rbp), %rsi
+ mov rdi, [rbp-0x10]
+ mov rsi, [rbp-0x18]
- movq %rbp, %rsp
- popq %rbp
+ mov rsp, rbp
+ pop rbp
jmp _of_method_not_found
_of_forward_stret:
- pushq %rbp
- movq %rsp, %rbp
+ push rbp
+ mov rbp, rsp
/* Save all arguments */
- subq $0xC0, %rsp /* 16-byte alignment */
- movq %rax, -0x8(%rbp)
- movq %rdi, -0x10(%rbp)
- movq %rsi, -0x18(%rbp)
- movq %rdx, -0x20(%rbp)
- movq %rcx, -0x28(%rbp)
- movq %r8, -0x30(%rbp)
- movq %r9, -0x38(%rbp)
- movaps %xmm0, -0x50(%rbp)
- movaps %xmm1, -0x60(%rbp)
- movaps %xmm2, -0x70(%rbp)
- movaps %xmm3, -0x80(%rbp)
- movaps %xmm4, -0x90(%rbp)
- movaps %xmm5, -0xA0(%rbp)
- movaps %xmm6, -0xB0(%rbp)
- movaps %xmm7, -0xC0(%rbp)
-
- movq %rsi, %rdi
+ sub rsp, 0xC0 /* 16-byte alignment */
+ mov [rbp-0x08], rax
+ mov [rbp-0x10], rdi
+ mov [rbp-0x18], rsi
+ mov [rbp-0x20], rdx
+ mov [rbp-0x28], rcx
+ mov [rbp-0x30], r8
+ mov [rbp-0x38], r9
+ movaps [rbp-0x50], xmm0
+ movaps [rbp-0x60], xmm1
+ movaps [rbp-0x70], xmm2
+ movaps [rbp-0x80], xmm3
+ movaps [rbp-0x90], xmm4
+ movaps [rbp-0xA0], xmm5
+ movaps [rbp-0xB0], xmm6
+ movaps [rbp-0xC0], xmm7
+
+ mov rdi, rsi
call _object_getClass
- movq %rax, %rdi
- leaq sel_forwardingTargetForSelector_(%rip), %rsi
+ mov rdi, rax
+ lea rsi, [rip+sel_forwardingTargetForSelector_]
call _class_respondsToSelector
- testq %rax, %rax
+ test rax, rax
jz 0f
- movq -0x18(%rbp), %rdi
- leaq sel_forwardingTargetForSelector_(%rip), %rsi
+ mov rdi, [rbp-0x18]
+ lea rsi, [rip+sel_forwardingTargetForSelector_]
call _objc_msg_lookup
- movq -0x18(%rbp), %rdi
- leaq sel_forwardingTargetForSelector_(%rip), %rsi
- movq -0x20(%rbp), %rdx
- call *%rax
+ mov rdi, [rbp-0x18]
+ lea rsi, [rip+sel_forwardingTargetForSelector_]
+ mov rdx, [rbp-0x20]
+ call rax
- testq %rax, %rax
+ test rax, rax
jz 0f
- cmpq -0x18(%rbp), %rax
+ cmp rax, [rbp-0x18]
je 0f
- movq %rax, -0x18(%rbp)
+ mov [rbp-0x18], rax
- movq %rax, %rdi
- movq -0x20(%rbp), %rsi
+ mov rdi, rax
+ mov rsi, [rbp-0x20]
call _objc_msg_lookup_stret
- movq %rax, %r11
+ mov r11, rax
/* Restore all arguments */
- movaps -0xC0(%rbp), %xmm7
- movaps -0xB0(%rbp), %xmm6
- movaps -0xA0(%rbp), %xmm5
- movaps -0x90(%rbp), %xmm4
- movaps -0x80(%rbp), %xmm3
- movaps -0x70(%rbp), %xmm2
- movaps -0x60(%rbp), %xmm1
- movaps -0x50(%rbp), %xmm0
- movq -0x38(%rbp), %r9
- movq -0x30(%rbp), %r8
- movq -0x28(%rbp), %rcx
- movq -0x20(%rbp), %rdx
- movq -0x18(%rbp), %rsi
- movq -0x10(%rbp), %rdi
- movq -0x8(%rbp), %rax
-
- movq %rbp, %rsp
- popq %rbp
-
- jmpq *%r11
+ movaps xmm7, [rbp-0xC0]
+ movaps xmm6, [rbp-0xB0]
+ movaps xmm5, [rbp-0xA0]
+ movaps xmm4, [rbp-0x90]
+ movaps xmm3, [rbp-0x80]
+ movaps xmm2, [rbp-0x70]
+ movaps xmm1, [rbp-0x60]
+ movaps xmm0, [rbp-0x50]
+ mov r9, [rbp-0x38]
+ mov r8, [rbp-0x30]
+ mov rcx, [rbp-0x28]
+ mov rdx, [rbp-0x20]
+ mov rsi, [rbp-0x18]
+ mov rdi, [rbp-0x10]
+ mov rax, [rbp-0x08]
+
+ mov rsp, rbp
+ pop rbp
+
+ jmp r11
0:
- movq -0x10(%rbp), %rdi
- movq -0x18(%rbp), %rsi
- movq -0x20(%rbp), %rdx
+ mov rdi, [rbp-0x10]
+ mov rsi, [rbp-0x18]
+ mov rdx, [rbp-0x20]
- movq %rbp, %rsp
- popq %rbp
+ mov rsp, rbp
+ pop rbp
jmp _of_method_not_found_stret
init:
- leaq module(%rip), %rdi
+ lea rdi, [rip+module]
jmp ___objc_exec_class
.section __DATA, __mod_init_func, mod_init_funcs
diff --git a/src/forwarding/forwarding-x86_64-win64.S b/src/forwarding/forwarding-x86_64-win64.S
index 6fbfddef..66e9840a 100644
--- a/src/forwarding/forwarding-x86_64-win64.S
+++ b/src/forwarding/forwarding-x86_64-win64.S
@@ -17,156 +17,158 @@
#include "config.h"
+.intel_syntax noprefix
+
.globl of_forward
.globl of_forward_stret
.section .text
of_forward:
- pushq %rbp
- movq %rsp, %rbp
+ push rbp
+ mov rbp, rsp
/* Save all arguments */
- subq $0x90, %rsp /* 16-byte alignment */
- movq %rax, -0x28(%rbp)
- movq %rcx, -0x30(%rbp)
- movq %rdx, -0x38(%rbp)
- movq %r8, -0x40(%rbp)
- movq %r9, -0x48(%rbp)
- movaps %xmm0, -0x60(%rbp)
- movaps %xmm1, -0x70(%rbp)
- movaps %xmm2, -0x80(%rbp)
- movaps %xmm3, -0x90(%rbp)
+ sub rsp, 0x90 /* 16-byte alignment */
+ mov [rbp-0x28], rax
+ mov [rbp-0x30], rcx
+ mov [rbp-0x38], rdx
+ mov [rbp-0x40], r8
+ mov [rbp-0x48], r9
+ movaps [rbp-0x60], xmm0
+ movaps [rbp-0x70], xmm1
+ movaps [rbp-0x80], xmm2
+ movaps [rbp-0x90], xmm3
call object_getClass
- movq %rax, %rcx
- leaq sel_forwardingTargetForSelector_(%rip), %rdx
+ mov rcx, rax
+ mov rdx, offset sel_forwardingTargetForSelector_
call class_respondsToSelector
- testq %rax, %rax
- jz 0f
+ test rax, rax
+ jz short 0f
- movq -0x30(%rbp), %rcx
- leaq sel_forwardingTargetForSelector_(%rip), %rdx
+ mov rcx, [rbp-0x30]
+ mov rdx, offset sel_forwardingTargetForSelector_
call objc_msg_lookup
- movq -0x30(%rbp), %rcx
- leaq sel_forwardingTargetForSelector_(%rip), %rdx
- movq -0x38(%rbp), %r8
- call *%rax
+ mov rcx, [rbp-0x30]
+ mov rdx, offset sel_forwardingTargetForSelector_
+ mov r8, [rbp-0x38]
+ call rax
- testq %rax, %rax
- jz 0f
- cmpq -0x30(%rbp), %rax
- je 0f
+ test rax, rax
+ jz short 0f
+ cmp rax, [rbp-0x30]
+ je short 0f
- movq %rax, -0x30(%rbp)
+ mov [rbp-0x30], rax
- movq %rax, %rcx
- movq -0x38(%rbp), %rdx
+ mov rcx, rax
+ mov rdx, [rbp-0x38]
call objc_msg_lookup
- movq %rax, %r11
+ mov r11, rax
/* Restore all arguments */
- movaps -0x90(%rbp), %xmm3
- movaps -0x80(%rbp), %xmm2
- movaps -0x70(%rbp), %xmm1
- movaps -0x60(%rbp), %xmm0
- movq -0x48(%rbp), %r9
- movq -0x40(%rbp), %r8
- movq -0x38(%rbp), %rdx
- movq -0x30(%rbp), %rcx
- movq -0x28(%rbp), %rax
+ movaps xmm3, [rbp-0x90]
+ movaps xmm2, [rbp-0x80]
+ movaps xmm1, [rbp-0x70]
+ movaps xmm0, [rbp-0x60]
+ mov r9, [rbp-0x48]
+ mov r8, [rbp-0x40]
+ mov rdx, [rbp-0x38]
+ mov rcx, [rbp-0x30]
+ mov rax, [rbp-0x28]
- movq %rbp, %rsp
- popq %rbp
+ mov rsp, rbp
+ pop rbp
- jmpq *%r11
+ jmp r11
0:
- movq -0x30(%rbp), %rcx
- movq -0x38(%rbp), %rdx
+ mov rcx, [rbp-0x30]
+ mov rdx, [rbp-0x38]
- movq %rbp, %rsp
- popq %rbp
+ mov rsp, rbp
+ pop rbp
jmp of_method_not_found
of_forward_stret:
- pushq %rbp
- movq %rsp, %rbp
+ push rbp
+ mov rbp, rsp
/* Save all arguments */
- subq $0x90, %rsp /* 16-byte alignment */
- movq %rax, -0x28(%rbp)
- movq %rcx, -0x30(%rbp)
- movq %rdx, -0x38(%rbp)
- movq %r8, -0x40(%rbp)
- movq %r9, -0x48(%rbp)
- movaps %xmm0, -0x60(%rbp)
- movaps %xmm1, -0x70(%rbp)
- movaps %xmm2, -0x80(%rbp)
- movaps %xmm3, -0x90(%rbp)
-
- movq %rdx, %rcx
+ sub rsp, 0x90 /* 16-byte alignment */
+ mov [rbp-0x28], rax
+ mov [rbp-0x30], rcx
+ mov [rbp-0x38], rdx
+ mov [rbp-0x40], r8
+ mov [rbp-0x48], r9
+ movaps [rbp-0x60], xmm0
+ movaps [rbp-0x70], xmm1
+ movaps [rbp-0x80], xmm2
+ movaps [rbp-0x90], xmm3
+
+ mov rcx, rdx
call object_getClass
- movq %rax, %rcx
- leaq sel_forwardingTargetForSelector_(%rip), %rdx
+ mov rcx, rax
+ mov rdx, offset sel_forwardingTargetForSelector_
call class_respondsToSelector
- testq %rax, %rax
- jz 0f
+ test rax, rax
+ jz short 0f
- movq -0x38(%rbp), %rcx
- leaq sel_forwardingTargetForSelector_(%rip), %rdx
+ mov rcx, [rbp-0x38]
+ mov rdx, offset sel_forwardingTargetForSelector_
call objc_msg_lookup
- movq -0x38(%rbp), %rcx
- leaq sel_forwardingTargetForSelector_(%rip), %rdx
- movq -0x40(%rbp), %r8
- call *%rax
+ mov rcx, [rbp-0x38]
+ mov rdx, offset sel_forwardingTargetForSelector_
+ mov r8, [rbp-0x40]
+ call rax
- testq %rax, %rax
- jz 0f
- cmpq -0x38(%rbp), %rax
- je 0f
+ test rax, rax
+ jz short 0f
+ cmp rax, [rbp-0x38]
+ je short 0f
- movq %rax, -0x38(%rbp)
+ mov [rbp-0x38], rax
- movq %rax, %rcx
- movq -0x40(%rbp), %rdx
+ mov rcx, rax
+ mov rdx, [rbp-0x40]
call objc_msg_lookup_stret
- movq %rax, %r11
+ mov r11, rax
/* Restore all arguments */
- movaps -0x90(%rbp), %xmm3
- movaps -0x80(%rbp), %xmm2
- movaps -0x70(%rbp), %xmm1
- movaps -0x60(%rbp), %xmm0
- movq -0x48(%rbp), %r9
- movq -0x40(%rbp), %r8
- movq -0x38(%rbp), %rdx
- movq -0x30(%rbp), %rcx
- movq -0x28(%rbp), %rax
+ movaps xmm3, [rbp-0x90]
+ movaps xmm2, [rbp-0x80]
+ movaps xmm1, [rbp-0x70]
+ movaps xmm0, [rbp-0x60]
+ mov r9, [rbp-0x48]
+ mov r8, [rbp-0x40]
+ mov rdx, [rbp-0x38]
+ mov rcx, [rbp-0x30]
+ mov rax, [rbp-0x28]
- movq %rbp, %rsp
- popq %rbp
+ mov rsp, rbp
+ pop rbp
- jmpq *%r11
+ jmp r11
0:
- movq -0x30(%rbp), %rcx
- movq -0x38(%rbp), %rdx
- movq -0x40(%rbp), %r8
+ mov rcx, [rbp-0x30]
+ mov rdx, [rbp-0x38]
+ mov r8, [rbp-0x40]
- movq %rbp, %rsp
- popq %rbp
+ mov rsp, rbp
+ pop rbp
jmp of_method_not_found_stret
init:
- leaq module(%rip), %rcx
+ mov rcx, offset module
jmp __objc_exec_class
.section .ctors, "aw"
diff --git a/src/forwarding/forwarding.S b/src/forwarding/forwarding.S
index 7bf815a3..432b2b19 100644
--- a/src/forwarding/forwarding.S
+++ b/src/forwarding/forwarding.S
@@ -47,6 +47,8 @@
# include "forwarding-mips-elf.S"
# elif defined(OF_SPARC64)
# include "forwarding-sparc64-elf.S"
+# elif defined(OF_SPARC)
+# include "forwarding-sparc-elf.S"
# endif
# elif defined(OF_MACH_O)
# if defined(OF_X86_64)
diff --git a/src/macros.h b/src/macros.h
index a65e1b33..bbb87437 100644
--- a/src/macros.h
+++ b/src/macros.h
@@ -309,6 +309,17 @@
# define OF_SWIFT_NAME(name)
#endif
+#if __has_attribute(__objc_direct__) && defined(OF_APPLE_RUNTIME)
+# define OF_DIRECT __attribute__((__objc_direct__))
+#else
+# define OF_DIRECT
+#endif
+#if __has_attribute(__objc_direct_members__) && defined(OF_APPLE_RUNTIME)
+# define OF_DIRECT_MEMBERS __attribute__((__objc_direct_members__))
+#else
+# define OF_DIRECT_MEMBERS
+#endif
+
#ifdef __GNUC__
# ifdef OF_X86_64
# define OF_X86_64_ASM
@@ -355,7 +366,7 @@
# if defined(OF_ELF)
# if defined(OF_X86_64) || defined(OF_X86) || \
defined(OF_ARM64) || defined(OF_ARM) || defined(OF_POWERPC) || \
- defined(OF_MIPS) || defined(OF_SPARC64)
+ defined(OF_MIPS) || defined(OF_SPARC64) || defined(OF_SPARC)
# define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR
# if __OBJFW_RUNTIME_ABI__ >= 800
# define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET
diff --git a/src/pbkdf2.h b/src/pbkdf2.h
index c106b2d0..4259b2b3 100644
--- a/src/pbkdf2.h
+++ b/src/pbkdf2.h
@@ -30,32 +30,47 @@ OF_ASSUME_NONNULL_BEGIN
@class OFHMAC;
+/*!
+ * @brief The parameters for @ref of_pbkdf2.
+ */
+typedef struct of_pbkdf2_parameters_t {
+ /*! @brief The HMAC to use to derive a key. */
+ OFHMAC *HMAC;
+ /*! @brief The number of iterations to perform. */
+ size_t iterations;
+ /*! @brief The salt to derive a key with. */
+ const unsigned char *salt;
+ /*! @brief The length of the salt. */
+ size_t saltLength;
+ /*! @brief The password to derive a key from. */
+ const char *password;
+ /*! @brief The length of the password. */
+ size_t passwordLength;
+ /*! @brief The buffer to write the key to. */
+ unsigned char *key;
+ /*!
+ * @brief The desired length for the derived key.
+ *
+ * @ref key needs to have enough storage.
+ */
+ size_t keyLength;
+ /*! @brief Whether data may be stored in swappable memory. */
+ bool allowsSwappableMemory;
+} of_pbkdf2_parameters_t;
+
#ifdef __cplusplus
extern "C" {
#endif
/*!
- * @brief Derive a key from a password and a salt.
+ * @brief Derives a key from a password and a salt using PBKDF2.
*
- * @note This will call @ref OFHMAC::reset on the @ref OFHMAC first, making it
- * possible to reuse the @ref OFHMAC, but also meaning all previous
- * results from the @ref OFHMAC get invalidated if they have not been
- * copied.
+ * @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 HMAC The HMAC to use to derive a key
- * @param iterations The number of iterations to perform
- * @param salt The salt to derive a key with
- * @param saltLength The length of the salt
- * @param password The password to derive a key from
- * @param passwordLength The length of the password
- * @param key The buffer to write the key to
- * @param keyLength The desired length for the derived key (key needs to have
- * enough storage)
- * @param allowsSwappableMemory Whether data may be stored in swappable memory
+ * @param param The parameters to use
*/
-extern void of_pbkdf2(OFHMAC *HMAC, size_t iterations,
- const unsigned char *salt, size_t saltLength,
- const char *password, size_t passwordLength,
- unsigned char *key, size_t keyLength, bool allowsSwappableMemory);
+extern void of_pbkdf2(of_pbkdf2_parameters_t param);
#ifdef __cplusplus
}
#endif
diff --git a/src/pbkdf2.m b/src/pbkdf2.m
index 56de4757..d4c5cafc 100644
--- a/src/pbkdf2.m
+++ b/src/pbkdf2.m
@@ -28,75 +28,75 @@
#import "pbkdf2.h"
-void of_pbkdf2(OFHMAC *HMAC, size_t iterations,
- const unsigned char *salt, size_t saltLength,
- const char *password, size_t passwordLength,
- unsigned char *key, size_t keyLength, bool allowsSwappableMemory)
+void
+of_pbkdf2(of_pbkdf2_parameters_t param)
{
void *pool = objc_autoreleasePoolPush();
- size_t blocks, digestSize = HMAC.digestSize;
+ size_t blocks, digestSize = param.HMAC.digestSize;
OFSecureData *buffer = [OFSecureData
dataWithCount: digestSize
- allowsSwappableMemory: allowsSwappableMemory];
+ allowsSwappableMemory: param.allowsSwappableMemory];
OFSecureData *digest = [OFSecureData
dataWithCount: digestSize
- allowsSwappableMemory: allowsSwappableMemory];
+ allowsSwappableMemory: param.allowsSwappableMemory];
unsigned char *bufferItems = buffer.mutableItems;
unsigned char *digestItems = digest.mutableItems;
OFSecureData *extendedSalt;
unsigned char *extendedSaltItems;
- if (HMAC == nil || iterations == 0 || salt == NULL ||
- password == NULL || key == NULL || keyLength == 0)
+ if (param.HMAC == nil || param.iterations == 0 || param.salt == NULL ||
+ param.password == NULL || param.key == NULL || param.keyLength == 0)
@throw [OFInvalidArgumentException exception];
- blocks = keyLength / digestSize;
- if (keyLength % digestSize != 0)
+ blocks = param.keyLength / digestSize;
+ if (param.keyLength % digestSize != 0)
blocks++;
- if (saltLength > SIZE_MAX - 4 || blocks > UINT32_MAX)
+ if (param.saltLength > SIZE_MAX - 4 || blocks > UINT32_MAX)
@throw [OFOutOfRangeException exception];
- extendedSalt = [OFSecureData dataWithCount: saltLength + 4
- allowsSwappableMemory: allowsSwappableMemory];
+ extendedSalt = [OFSecureData
+ dataWithCount: param.saltLength + 4
+ allowsSwappableMemory: param.allowsSwappableMemory];
extendedSaltItems = extendedSalt.mutableItems;
@try {
uint32_t i = OF_BSWAP32_IF_LE(1);
- [HMAC setKey: password
- length: passwordLength];
+ [param.HMAC setKey: param.password
+ length: param.passwordLength];
- memcpy(extendedSaltItems, salt, saltLength);
+ memcpy(extendedSaltItems, param.salt, param.saltLength);
- while (keyLength > 0) {
+ while (param.keyLength > 0) {
size_t length;
- memcpy(extendedSaltItems + saltLength, &i, 4);
+ memcpy(extendedSaltItems + param.saltLength, &i, 4);
- [HMAC reset];
- [HMAC updateWithBuffer: extendedSaltItems
- length: saltLength + 4];
- memcpy(bufferItems, HMAC.digest, digestSize);
- memcpy(digestItems, HMAC.digest, digestSize);
+ [param.HMAC reset];
+ [param.HMAC updateWithBuffer: extendedSaltItems
+ length: param.saltLength + 4];
+ memcpy(bufferItems, param.HMAC.digest, digestSize);
+ memcpy(digestItems, param.HMAC.digest, digestSize);
- for (size_t j = 1; j < iterations; j++) {
- [HMAC reset];
- [HMAC updateWithBuffer: digestItems
- length: digestSize];
- memcpy(digestItems, HMAC.digest, digestSize);
+ for (size_t j = 1; j < param.iterations; j++) {
+ [param.HMAC reset];
+ [param.HMAC updateWithBuffer: digestItems
+ length: digestSize];
+ memcpy(digestItems, param.HMAC.digest,
+ digestSize);
for (size_t k = 0; k < digestSize; k++)
bufferItems[k] ^= digestItems[k];
}
length = digestSize;
- if (length > keyLength)
- length = keyLength;
+ if (length > param.keyLength)
+ length = param.keyLength;
- memcpy(key, bufferItems, length);
- key += length;
- keyLength -= length;
+ memcpy(param.key, bufferItems, length);
+ param.key += length;
+ param.keyLength -= length;
i = OF_BSWAP32_IF_LE(OF_BSWAP32_IF_LE(i) + 1);
}
@@ -107,7 +107,7 @@ void of_pbkdf2(OFHMAC *HMAC, size_t iterations,
@throw e;
} @finally {
- [HMAC zero];
+ [param.HMAC zero];
}
objc_autoreleasePoolPop(pool);
diff --git a/src/platform/amiga/thread.m b/src/platform/amiga/thread.m
index ddd123fd..507e6a4a 100644
--- a/src/platform/amiga/thread.m
+++ b/src/platform/amiga/thread.m
@@ -168,12 +168,15 @@ bool
of_thread_join(of_thread_t thread)
{
ObtainSemaphore(&thread->semaphore);
- @try {
- if (thread->done) {
- free(thread);
- return true;
- }
+ if (thread->done) {
+ ReleaseSemaphore(&thread->semaphore);
+
+ free(thread);
+ return true;
+ }
+
+ @try {
if (thread->detached || thread->joinTask != NULL) {
errno = EINVAL;
return false;
diff --git a/src/platform/windows/thread.m b/src/platform/windows/thread.m
index 657eda8f..e4c33d1b 100644
--- a/src/platform/windows/thread.m
+++ b/src/platform/windows/thread.m
@@ -24,6 +24,19 @@
#include <windows.h>
+struct thread_context {
+ void (*function)(id);
+ id object;
+};
+
+static WINAPI void
+functionWrapper(struct thread_context *context)
+{
+ context->function(context->object);
+
+ free(context);
+}
+
bool
of_thread_attr_init(of_thread_attr_t *attr)
{
@@ -37,25 +50,11 @@ bool
of_thread_new(of_thread_t *thread, const char *name, void (*function)(id),
id object, const of_thread_attr_t *attr)
{
- *thread = CreateThread(NULL, (attr != NULL ? attr->stackSize : 0),
- (LPTHREAD_START_ROUTINE)function, (void *)object, 0, NULL);
-
- if (thread == NULL) {
- switch (GetLastError()) {
- case ERROR_NOT_ENOUGH_MEMORY:
- errno = ENOMEM;
- return false;
- case ERROR_ACCESS_DENIED:
- errno = EACCES;
- return false;
- default:
- OF_ENSURE(0);
- }
- }
+ DWORD priority = THREAD_PRIORITY_NORMAL;
+ struct thread_context *context;
+ DWORD threadID;
if (attr != NULL && attr->priority != 0) {
- DWORD priority;
-
if (attr->priority < -1 || attr->priority > 1) {
errno = EINVAL;
return false;
@@ -69,10 +68,41 @@ of_thread_new(of_thread_t *thread, const char *name, void (*function)(id),
priority = THREAD_PRIORITY_NORMAL +
attr->priority *
(THREAD_PRIORITY_HIGHEST - THREAD_PRIORITY_NORMAL);
+ }
- OF_ENSURE(!SetThreadPriority(*thread, priority));
+ if ((context = malloc(sizeof(*context))) == NULL) {
+ errno = ENOMEM;
+ return false;
+ }
+
+ context->function = function;
+ context->object = object;
+
+ *thread = CreateThread(NULL, (attr != NULL ? attr->stackSize : 0),
+ (LPTHREAD_START_ROUTINE)functionWrapper, context, 0, &threadID);
+
+ if (thread == NULL) {
+ int errNo;
+
+ switch (GetLastError()) {
+ case ERROR_NOT_ENOUGH_MEMORY:
+ errNo = ENOMEM;
+ break;
+ case ERROR_ACCESS_DENIED:
+ errNo = EACCES;
+ break;
+ default:
+ OF_ENSURE(0);
+ }
+
+ free(context);
+ errno = errNo;
+ return false;
}
+ if (attr != NULL && attr->priority != 0)
+ OF_ENSURE(!SetThreadPriority(*thread, priority));
+
return true;
}
diff --git a/src/runtime/exception.m b/src/runtime/exception.m
index 52a64db4..d04fb0de 100644
--- a/src/runtime/exception.m
+++ b/src/runtime/exception.m
@@ -754,8 +754,9 @@ objc_exception_throw(id object)
? emergencyExceptionCleanup : cleanup);
e->object = object;
- if (_Unwind_RaiseException(&e->exception) == _URC_END_OF_STACK &&
- uncaughtExceptionHandler != NULL)
+ _Unwind_RaiseException(&e->exception);
+
+ if (uncaughtExceptionHandler != NULL)
uncaughtExceptionHandler(object);
OBJC_ERROR("_Unwind_RaiseException() returned!")
diff --git a/src/runtime/lookup-asm/lookup-asm-sparc-elf.S b/src/runtime/lookup-asm/lookup-asm-sparc-elf.S
index 9ce1ccb6..1d3fee04 100644
--- a/src/runtime/lookup-asm/lookup-asm-sparc-elf.S
+++ b/src/runtime/lookup-asm/lookup-asm-sparc-elf.S
@@ -54,11 +54,16 @@
ld [%o2 + %o5], %o2
cmp %o2, 0
- be \not_found
+ be 0f
nop
retl
mov %o2, %o0
+
+0:
+ mov %o7, %g1
+ call \not_found
+ mov %g1, %o7
.type \name, %function
.size \name, .-\name
.endm
diff --git a/src/runtime/lookup-asm/lookup-asm-x86-elf.S b/src/runtime/lookup-asm/lookup-asm-x86-elf.S
index 4042803f..b4ab9627 100644
--- a/src/runtime/lookup-asm/lookup-asm-x86-elf.S
+++ b/src/runtime/lookup-asm/lookup-asm-x86-elf.S
@@ -19,6 +19,8 @@
#include "platform.h"
+.intel_syntax noprefix
+
.globl objc_msg_lookup
.globl objc_msg_lookup_stret
.globl objc_msg_lookup_super
@@ -27,51 +29,50 @@
.section .text
.macro generate_lookup name not_found
\name:
- movl 4(%esp), %edx
- testl %edx, %edx
- jz ret_nil
+ mov edx, [esp+4]
+ test edx, edx
+ jz short ret_nil
- movl (%edx), %edx
- movl 32(%edx), %edx
+ mov edx, [edx]
+ mov edx, [edx+32]
.Lmain_\name:
- movl 8(%esp), %eax
+ mov eax, [esp+8]
#ifdef OF_SELUID24
- movzbl 2(%eax), %ecx
- movl (%edx,%ecx,4), %edx
+ movzx ecx, byte ptr [eax+2]
+ mov edx, [edx+ecx*4]
#endif
- movzbl 1(%eax), %ecx
- movl (%edx,%ecx,4), %edx
- movzbl (%eax), %ecx
- movl (%edx,%ecx,4), %eax
+ movzx ecx, byte ptr [eax+1]
+ mov edx, [edx+ecx*4]
+ movzx ecx, byte ptr [eax]
+ mov eax, [edx+ecx*4]
- testl %eax, %eax
- jz 0f
+ test eax, eax
+ jz short 0f
ret
0:
call get_eip
-1:
- addl $_GLOBAL_OFFSET_TABLE_, %eax
- movl \not_found@GOT(%eax), %eax
- jmp *%eax
+ add eax, offset _GLOBAL_OFFSET_TABLE_
+ lea eax, [eax+\not_found@GOTOFF]
+ jmp eax
.type \name, %function
.size \name, .-\name
.endm
.macro generate_lookup_super name lookup
\name:
- movl 4(%esp), %edx
- movl (%edx), %eax
- cmpl $0, %eax
- je ret_nil
-
- movl %eax, 4(%esp)
- movl 4(%edx), %edx
- movl 32(%edx), %edx
- jmp .Lmain_\lookup
+ mov edx, [esp+4]
+ mov eax, [edx]
+ test eax, eax
+ jz short ret_nil
+
+ mov [esp+4], eax
+ mov edx, [edx+4]
+ mov edx, [edx+32]
+ jmp short .Lmain_\lookup
.type \name, %function
.size \name, .-\name
.endm
@@ -83,16 +84,16 @@ generate_lookup_super objc_msg_lookup_super_stret objc_msg_lookup_stret
ret_nil:
call get_eip
-0:
- addl $nil_method-0b, %eax
+ add eax, offset _GLOBAL_OFFSET_TABLE_
+ lea eax, [eax+nil_method@GOTOFF]
ret
nil_method:
- xorl %eax, %eax
+ xor eax, eax
ret
get_eip:
- movl (%esp), %eax
+ mov eax, [esp]
ret
#ifdef OF_LINUX
diff --git a/src/runtime/lookup-asm/lookup-asm-x86-win32.S b/src/runtime/lookup-asm/lookup-asm-x86-win32.S
index 2e7d9295..a68d3338 100644
--- a/src/runtime/lookup-asm/lookup-asm-x86-win32.S
+++ b/src/runtime/lookup-asm/lookup-asm-x86-win32.S
@@ -17,6 +17,8 @@
#include "config.h"
+.intel_syntax noprefix
+
.globl _objc_msg_lookup
.globl _objc_msg_lookup_stret
.globl _objc_msg_lookup_super
@@ -25,48 +27,45 @@
.section .text
.macro generate_lookup name not_found
\name:
- movl 4(%esp), %edx
- testl %edx, %edx
- jz ret_nil
+ mov edx, [esp+4]
+ test edx, edx
+ jz short ret_nil
- movl (%edx), %edx
- movl 32(%edx), %edx
+ mov edx, [edx]
+ mov edx, [edx+32]
.Lmain_\name:
- movl 8(%esp), %eax
+ mov eax, [esp+8]
#ifdef OF_SELUID24
- movzbl 2(%eax), %ecx
- movl (%edx,%ecx,4), %edx
+ movzx ecx, byte ptr [eax+2]
+ mov edx, [edx+ecx*4]
#endif
- movzbl 1(%eax), %ecx
- movl (%edx,%ecx,4), %edx
- movzbl (%eax), %ecx
- movl (%edx,%ecx,4), %eax
+ movzx ecx, byte ptr [eax+1]
+ mov edx, [edx+ecx*4]
+ movzx ecx, byte ptr [eax]
+ mov eax, [edx+ecx*4]
- testl %eax, %eax
- jz 0f
+ test eax, eax
+ jz short 0f
ret
0:
- call get_eip
-1:
- addl $\not_found-1b, %eax
- jmp *%eax
+ jmp \not_found
.endm
.macro generate_lookup_super name lookup
\name:
- movl 4(%esp), %edx
- movl (%edx), %eax
- cmpl $0, %eax
- je ret_nil
+ mov edx, [esp+4]
+ mov eax, [edx]
+ test eax, eax
+ jz short ret_nil
- movl %eax, 4(%esp)
- movl 4(%edx), %edx
- movl 32(%edx), %edx
- jmp .Lmain_\lookup
+ mov [esp+4], eax
+ mov edx, [edx+4]
+ mov edx, [edx+32]
+ jmp short .Lmain_\lookup
.endm
generate_lookup _objc_msg_lookup _objc_method_not_found
@@ -75,15 +74,9 @@ generate_lookup_super _objc_msg_lookup_super _objc_msg_lookup
generate_lookup_super _objc_msg_lookup_super_stret _objc_msg_lookup_stret
ret_nil:
- call get_eip
-0:
- addl $nil_method-0b, %eax
+ mov eax, offset nil_method
ret
nil_method:
- xorl %eax, %eax
- ret
-
-get_eip:
- movl (%esp), %eax
+ xor eax, eax
ret
diff --git a/src/runtime/lookup-asm/lookup-asm-x86_64-elf.S b/src/runtime/lookup-asm/lookup-asm-x86_64-elf.S
index 46731786..5f1dd44d 100644
--- a/src/runtime/lookup-asm/lookup-asm-x86_64-elf.S
+++ b/src/runtime/lookup-asm/lookup-asm-x86_64-elf.S
@@ -19,6 +19,8 @@
#include "platform.h"
+.intel_syntax noprefix
+
.globl objc_msg_lookup
.globl objc_msg_lookup_stret
.globl objc_msg_lookup_super
@@ -27,26 +29,26 @@
.section .text
.macro generate_lookup name not_found
\name:
- testq %rdi, %rdi
- jz ret_nil
+ test rdi, rdi
+ jz short ret_nil
- movq (%rdi), %r8
- movq 64(%r8), %r8
+ mov r8, [rdi]
+ mov r8, [r8+64]
.Lmain_\name:
- movq (%rsi), %rax
- movzbl %ah, %ecx
- movzbl %al, %edx
+ mov rax, [rsi]
+ movzx ecx, ah
+ movzx edx, al
#ifdef OF_SELUID24
- shrl $16, %eax
+ shr eax, 16
- movq (%r8,%rax,8), %r8
+ mov r8, [r8+rax*8]
#endif
- movq (%r8,%rcx,8), %r8
- movq (%r8,%rdx,8), %rax
+ mov r8, [r8+rcx*8]
+ mov rax, [r8+rdx*8]
- testq %rax, %rax
- jz \not_found@PLT
+ test rax, rax
+ jz short \not_found@PLT
ret
.type \name, %function
@@ -55,14 +57,14 @@
.macro generate_lookup_super name lookup
\name:
- movq %rdi, %r8
- movq (%rdi), %rdi
- testq %rdi, %rdi
- jz ret_nil
-
- movq 8(%r8), %r8
- movq 64(%r8), %r8
- jmp .Lmain_\lookup
+ mov r8, rdi
+ mov rdi, [rdi]
+ test rdi, rdi
+ jz short ret_nil
+
+ mov r8, [r8+8]
+ mov r8, [r8+64]
+ jmp short .Lmain_\lookup
.type \name, %function
.size \name, .-\name
.endm
@@ -73,11 +75,11 @@ generate_lookup_super objc_msg_lookup_super objc_msg_lookup
generate_lookup_super objc_msg_lookup_super_stret objc_msg_lookup_stret
ret_nil:
- leaq nil_method(%rip), %rax
+ lea rax, [rip+nil_method]
ret
nil_method:
- xorq %rax, %rax
+ xor rax, rax
ret
#ifdef OF_LINUX
diff --git a/src/runtime/lookup-asm/lookup-asm-x86_64-macho.S b/src/runtime/lookup-asm/lookup-asm-x86_64-macho.S
index 8ae5f210..e13a6ae3 100644
--- a/src/runtime/lookup-asm/lookup-asm-x86_64-macho.S
+++ b/src/runtime/lookup-asm/lookup-asm-x86_64-macho.S
@@ -17,6 +17,8 @@
#include "config.h"
+.intel_syntax noprefix
+
.globl _objc_msg_lookup
.globl _objc_msg_lookup_stret
.globl _objc_msg_lookup_super
@@ -25,25 +27,25 @@
.section __TEXT, __text, regular, pure_instructions
.macro generate_lookup
$0:
- testq %rdi, %rdi
+ test rdi, rdi
jz ret_nil
- movq (%rdi), %r8
- movq 64(%r8), %r8
+ mov r8, [rdi]
+ mov r8, [r8+64]
Lmain_$0:
- movq (%rsi), %rax
- movzbl %ah, %ecx
- movzbl %al, %edx
+ mov rax, [rsi]
+ movzx ecx, ah
+ movzx edx, al
#ifdef OF_SELUID24
- shrl $$16, %eax
+ shr eax, 16
- movq (%r8,%rax,8), %r8
+ mov r8, [r8+rax*8]
#endif
- movq (%r8,%rcx,8), %r8
- movq (%r8,%rdx,8), %rax
+ mov r8, [r8+rcx*8]
+ mov rax, [r8+rdx*8]
- testq %rax, %rax
+ test rax, rax
jz $1
ret
@@ -51,13 +53,13 @@ Lmain_$0:
.macro generate_lookup_super
$0:
- movq %rdi, %r8
- movq (%rdi), %rdi
- testq %rdi, %rdi
+ mov r8, rdi
+ mov rdi, [rdi]
+ test rdi, rdi
jz ret_nil
- movq 8(%r8), %r8
- movq 64(%r8), %r8
+ mov r8, [r8+8]
+ mov r8, [r8+64]
jmp Lmain_$1
.endmacro
@@ -67,9 +69,9 @@ generate_lookup_super _objc_msg_lookup_super, _objc_msg_lookup
generate_lookup_super _objc_msg_lookup_super_stret, _objc_msg_lookup_stret
ret_nil:
- leaq nil_method(%rip), %rax
+ lea rax, [rip+nil_method]
ret
nil_method:
- movq %rdi, %rax
+ mov rax, rdi
ret
diff --git a/src/runtime/lookup-asm/lookup-asm-x86_64-win64.S b/src/runtime/lookup-asm/lookup-asm-x86_64-win64.S
index 779497c5..4bb216c1 100644
--- a/src/runtime/lookup-asm/lookup-asm-x86_64-win64.S
+++ b/src/runtime/lookup-asm/lookup-asm-x86_64-win64.S
@@ -17,6 +17,8 @@
#include "config.h"
+.intel_syntax noprefix
+
.globl objc_msg_lookup
.globl objc_msg_lookup_stret
.globl objc_msg_lookup_super
@@ -25,48 +27,48 @@
.section .text
.macro generate_lookup name not_found
\name:
- testq %rcx, %rcx
- jz ret_nil
+ test %rcx, %rcx
+ jz short ret_nil
- movq (%rcx), %r8
- movq 56(%r8), %r8
+ mov r8, [rcx]
+ mov r8, [r8+56]
.Lmain_\name:
- movq %rcx, %r10
- movq %rdx, %r11
+ mov r10, rcx
+ mov r11, rdx
- movq (%rdx), %rax
- movzbl %ah, %ecx
- movzbl %al, %edx
+ mov rax, [rdx]
+ movzx ecx, ah
+ movzx edx, al
#ifdef OF_SELUID24
- shrl $16, %eax
+ shr eax, 16
- movq (%r8,%rax,8), %r8
+ mov r8, [r8+rax*8]
#endif
- movq (%r8,%rcx,8), %r8
- movq (%r8,%rdx,8), %rax
+ mov r8, [r8+rcx*8]
+ mov rax, [r8+rdx*8]
- testq %rax, %rax
- jz 0f
+ test rax, rax
+ jz short 0f
ret
0:
- movq %r10, %rcx
- movq %r11, %rdx
+ mov rcx, r10
+ mov rdx, r11
jmp \not_found
.endm
.macro generate_lookup_super name lookup
\name:
- movq %rcx, %r8
- movq (%rcx), %rcx
- testq %rcx, %rcx
- jz ret_nil
-
- movq 8(%r8), %r8
- movq 56(%r8), %r8
- jmp .Lmain_\lookup
+ mov r8, rcx
+ mov rcx, [rcx]
+ test rcx, rcx
+ jz short ret_nil
+
+ mov r8, [r8+8]
+ mov r8, [r8+56]
+ jmp short .Lmain_\lookup
.endm
generate_lookup objc_msg_lookup objc_method_not_found
@@ -75,9 +77,9 @@ generate_lookup_super objc_msg_lookup_super objc_msg_lookup
generate_lookup_super objc_msg_lookup_super_stret objc_msg_lookup_stret
ret_nil:
- leaq nil_method(%rip), %rax
+ mov rax, offset nil_method
ret
nil_method:
- xorq %rax, %rax
+ xor rax, rax
ret
diff --git a/src/scrypt.h b/src/scrypt.h
index 74e18fcd..30302160 100644
--- a/src/scrypt.h
+++ b/src/scrypt.h
@@ -30,6 +30,36 @@ OF_ASSUME_NONNULL_BEGIN
@class OFHMAC;
+/*!
+ * @brief The parameters for @ref of_scrypt.
+ */
+typedef struct of_scrypt_parameters_t {
+ /*! @brief The block size to use. */
+ size_t blockSize;
+ /*! @brief The CPU/memory cost factor to use. */
+ size_t costFactor;
+ /*! @brief The parallelization to use. */
+ size_t parallelization;
+ /*! @brief The salt to derive a key with. */
+ const unsigned char *salt;
+ /*! @brief The length of the salt. */
+ size_t saltLength;
+ /*! @brief The password to derive a key from. */
+ const char *password;
+ /*! @brief The length of the password. */
+ size_t passwordLength;
+ /*! @brief The buffer to write the key to. */
+ unsigned char *key;
+ /*!
+ * @brief The desired length for the derived key.
+ *
+ * @ref key needs to have enough storage.
+ */
+ size_t keyLength;
+ /*! @brief Whether data may be stored in swappable memory. */
+ bool allowsSwappableMemory;
+} of_scrypt_parameters_t;
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -38,10 +68,13 @@ extern void of_scrypt_block_mix(uint32_t *output, const uint32_t *input,
size_t blockSize);
extern void of_scrypt_romix(uint32_t *buffer, size_t blockSize,
size_t costFactor, uint32_t *tmp);
-extern void of_scrypt(size_t blockSize, size_t costFactor,
- size_t parallelization, const unsigned char *salt, size_t saltLength,
- const char *password, size_t passwordLength,
- unsigned char *key, size_t keyLength, bool allowsSwappableMemory);
+
+/*!
+ * @brief Derives a key from a password and a salt using scrypt.
+ *
+ * @param param The parameters to use
+ */
+extern void of_scrypt(of_scrypt_parameters_t param);
#ifdef __cplusplus
}
#endif
diff --git a/src/scrypt.m b/src/scrypt.m
index 8e80ac5e..ddebf36b 100644
--- a/src/scrypt.m
+++ b/src/scrypt.m
@@ -85,8 +85,8 @@ of_scrypt_block_mix(uint32_t *output, const uint32_t *input, size_t blockSize)
/* Check defined here and executed in of_scrypt() */
#define OVERFLOW_CHECK_1 \
- if (blockSize > SIZE_MAX / 2 || \
- 2 * blockSize - 1 > SIZE_MAX / 16) \
+ if (param.blockSize > SIZE_MAX / 2 || \
+ 2 * param.blockSize - 1 > SIZE_MAX / 16) \
@throw [OFOutOfRangeException exception];
memcpy(tmp, input + (2 * blockSize - 1) * 16, 64);
@@ -112,8 +112,8 @@ of_scrypt_romix(uint32_t *buffer, size_t blockSize, size_t costFactor,
uint32_t *tmp)
{
/* Check defined here and executed in of_scrypt() */
-#define OVERFLOW_CHECK_2 \
- if (blockSize > SIZE_MAX / 128 / costFactor) \
+#define OVERFLOW_CHECK_2 \
+ if (param.blockSize > SIZE_MAX / 128 / param.costFactor) \
@throw [OFOutOfRangeException exception];
uint32_t *tmp2 = tmp + 32 * blockSize;
@@ -139,16 +139,15 @@ of_scrypt_romix(uint32_t *buffer, size_t blockSize, size_t costFactor,
}
}
-void of_scrypt(size_t blockSize, size_t costFactor,
- size_t parallelization, const unsigned char *salt, size_t saltLength,
- const char *password, size_t passwordLength,
- unsigned char *key, size_t keyLength, bool allowsSwappableMemory)
+void
+of_scrypt(of_scrypt_parameters_t param)
{
OFSecureData *tmp = nil, *buffer = nil;
OFHMAC *HMAC = nil;
- if (blockSize == 0 || costFactor <= 1 ||
- (costFactor & (costFactor - 1)) != 0 || parallelization == 0)
+ if (param.blockSize == 0 || param.costFactor <= 1 ||
+ (param.costFactor & (param.costFactor - 1)) != 0 ||
+ param.parallelization == 0)
@throw [OFInvalidArgumentException exception];
/*
@@ -162,40 +161,58 @@ void of_scrypt(size_t blockSize, size_t costFactor,
@try {
uint32_t *tmpItems, *bufferItems;
- if (costFactor > SIZE_MAX - 1 ||
- (costFactor + 1) > SIZE_MAX / 128)
+ if (param.costFactor > SIZE_MAX - 1 ||
+ (param.costFactor + 1) > SIZE_MAX / 128)
@throw [OFOutOfRangeException exception];
tmp = [[OFSecureData alloc]
- initWithItemSize: blockSize
- count: (costFactor + 1) * 128
- allowsSwappableMemory: allowsSwappableMemory];
+ initWithItemSize: param.blockSize
+ count: (param.costFactor + 1) * 128
+ allowsSwappableMemory: param.allowsSwappableMemory];
tmpItems = tmp.mutableItems;
- if (parallelization > SIZE_MAX / 128)
+ if (param.parallelization > SIZE_MAX / 128)
@throw [OFOutOfRangeException exception];
buffer = [[OFSecureData alloc]
- initWithItemSize: blockSize
- count: parallelization * 128
- allowsSwappableMemory: allowsSwappableMemory];
+ initWithItemSize: param.blockSize
+ count: param.parallelization * 128
+ allowsSwappableMemory: param.allowsSwappableMemory];
bufferItems = buffer.mutableItems;
HMAC = [[OFHMAC alloc]
initWithHashClass: [OFSHA256Hash class]
- allowsSwappableMemory: allowsSwappableMemory];
-
- of_pbkdf2(HMAC, 1, salt, saltLength, password, passwordLength,
- (unsigned char *)bufferItems,
- parallelization * 128 * blockSize, allowsSwappableMemory);
-
- for (size_t i = 0; i < parallelization; i++)
- of_scrypt_romix(bufferItems + i * 32 * blockSize,
- blockSize, costFactor, tmpItems);
-
- of_pbkdf2(HMAC, 1, (unsigned char *)bufferItems,
- parallelization * 128 * blockSize, password, passwordLength,
- key, keyLength, allowsSwappableMemory);
+ allowsSwappableMemory: param.allowsSwappableMemory];
+
+ of_pbkdf2((of_pbkdf2_parameters_t){
+ .HMAC = HMAC,
+ .iterations = 1,
+ .salt = param.salt,
+ .saltLength = param.saltLength,
+ .password = param.password,
+ .passwordLength = param.passwordLength,
+ .key = (unsigned char *)bufferItems,
+ .keyLength = param.parallelization * 128 *
+ param.blockSize,
+ .allowsSwappableMemory = param.allowsSwappableMemory
+ });
+
+ for (size_t i = 0; i < param.parallelization; i++)
+ of_scrypt_romix(bufferItems + i * 32 * param.blockSize,
+ param.blockSize, param.costFactor, tmpItems);
+
+ of_pbkdf2((of_pbkdf2_parameters_t){
+ .HMAC = HMAC,
+ .iterations = 1,
+ .salt = (unsigned char *)bufferItems,
+ .saltLength = param.parallelization * 128 *
+ param.blockSize,
+ .password = param.password,
+ .passwordLength = param.passwordLength,
+ .key = param.key,
+ .keyLength = param.keyLength,
+ .allowsSwappableMemory = param.allowsSwappableMemory
+ });
} @finally {
[tmp release];
[buffer release];
diff --git a/tests/Makefile b/tests/Makefile
index 3d1ed291..22d79779 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -6,6 +6,7 @@ CLEAN = EBOOT.PBP \
boot.dol \
${PROG_NOINST}.arm9 \
${PROG_NOINST}.nds
+DISTCLEAN = Info.plist
PROG_NOINST = tests${PROG_SUFFIX}
STATIC_LIB_NOINST = ${TESTS_STATIC_LIB}
diff --git a/tests/OFDNSResolverTests.m b/tests/OFDNSResolverTests.m
index 7365ed2e..ac8dba1a 100644
--- a/tests/OFDNSResolverTests.m
+++ b/tests/OFDNSResolverTests.m
@@ -19,8 +19,6 @@
#import "TestsAppDelegate.h"
-static OFString *module = @"OFDNSResolverTests";
-
@implementation TestsAppDelegate (OFDNSResolverTests)
- (void)DNSResolverTests
{
@@ -64,7 +62,7 @@ static OFString *module = @"OFDNSResolverTests";
resolver.minNumberOfDotsInAbsoluteName];
[of_stdout writeFormat: @"[OFDNSResolver] Uses TCP: %u\n",
- module, resolver.usesTCP];
+ resolver.usesTCP];
[of_stdout writeFormat:
@"[OFDNSResolver] Config reload interval: %lf\n",
diff --git a/tests/OFLocaleTests.m b/tests/OFLocaleTests.m
index ea5fb7ff..f495c493 100644
--- a/tests/OFLocaleTests.m
+++ b/tests/OFLocaleTests.m
@@ -26,16 +26,16 @@
of_stdout.foregroundColor = [OFColor lime];
- [of_stdout writeFormat: @"[OFLocale]: Language: %@\n",
+ [of_stdout writeFormat: @"[OFLocale] Language: %@\n",
[OFLocale language]];
- [of_stdout writeFormat: @"[OFLocale]: Territory: %@\n",
+ [of_stdout writeFormat: @"[OFLocale] Territory: %@\n",
[OFLocale territory]];
- [of_stdout writeFormat: @"[OFLocale]: Encoding: %@\n",
+ [of_stdout writeFormat: @"[OFLocale] Encoding: %@\n",
of_string_name_of_encoding([OFLocale encoding])];
- [of_stdout writeFormat: @"[OFLocale]: Decimal point: %@\n",
+ [of_stdout writeFormat: @"[OFLocale] Decimal point: %@\n",
[OFLocale decimalPoint]];
objc_autoreleasePoolPop(pool);
diff --git a/tests/OFSPXSocketTests.m b/tests/OFSPXSocketTests.m
index 036204a6..f4ac4441 100755
--- a/tests/OFSPXSocketTests.m
+++ b/tests/OFSPXSocketTests.m
@@ -165,15 +165,29 @@ static OFString *module = @"OFSPXSocket";
of_socket_address_get_ipx_network(&address1);
delegate->_expectedPort = port = of_socket_address_get_port(&address1);
- [sockClient asyncConnectToNode: node
- network: network
- port: port];
+ @try {
+ [sockClient asyncConnectToNode: node
+ network: network
+ port: port];
- [[OFRunLoop mainRunLoop] runUntilDate:
- [OFDate dateWithTimeIntervalSinceNow: 2]];
+ [[OFRunLoop mainRunLoop] runUntilDate:
+ [OFDate dateWithTimeIntervalSinceNow: 2]];
- TEST(@"-[asyncAccept] & -[asyncConnectToNode:network:port:]",
- delegate->_accepted && delegate->_connected)
+ TEST(@"-[asyncAccept] & -[asyncConnectToNode:network:port:]",
+ delegate->_accepted && delegate->_connected)
+ } @catch (OFObserveFailedException *e) {
+ switch (e.errNo) {
+ case ENOTSOCK:
+ of_stdout.foregroundColor = [OFColor lime];
+ [of_stdout writeLine:
+ @"[OFSPXSocket] -[asyncAccept] & "
+ @"-[asyncConnectToNode:network:port:]: select() "
+ @"not supported for SPX, skipping test"];
+ break;
+ default:
+ @throw e;
+ }
+ }
objc_autoreleasePoolPop(pool);
}
diff --git a/tests/OFSPXStreamSocketTests.m b/tests/OFSPXStreamSocketTests.m
index 1f543953..a88730c2 100755
--- a/tests/OFSPXStreamSocketTests.m
+++ b/tests/OFSPXStreamSocketTests.m
@@ -169,15 +169,29 @@ static OFString *module = @"OFSPXStreamSocket";
of_socket_address_get_ipx_network(&address1);
delegate->_expectedPort = port = of_socket_address_get_port(&address1);
- [sockClient asyncConnectToNode: node
- network: network
- port: port];
+ @try {
+ [sockClient asyncConnectToNode: node
+ network: network
+ port: port];
- [[OFRunLoop mainRunLoop] runUntilDate:
- [OFDate dateWithTimeIntervalSinceNow: 2]];
+ [[OFRunLoop mainRunLoop] runUntilDate:
+ [OFDate dateWithTimeIntervalSinceNow: 2]];
- TEST(@"-[asyncAccept] & -[asyncConnectToNode:network:port:]",
- delegate->_accepted && delegate->_connected)
+ TEST(@"-[asyncAccept] & -[asyncConnectToNode:network:port:]",
+ delegate->_accepted && delegate->_connected)
+ } @catch (OFObserveFailedException *e) {
+ switch (e.errNo) {
+ case ENOTSOCK:
+ of_stdout.foregroundColor = [OFColor lime];
+ [of_stdout writeLine:
+ @"[OFSPXStreamSocket] -[asyncAccept] & "
+ @"-[asyncConnectToNode:network:port:]: select() "
+ @"not supported for SPX, skipping test"];
+ break;
+ default:
+ @throw e;
+ }
+ }
objc_autoreleasePoolPop(pool);
}
diff --git a/tests/PBKDF2Tests.m b/tests/PBKDF2Tests.m
index 207106cf..952b9b52 100644
--- a/tests/PBKDF2Tests.m
+++ b/tests/PBKDF2Tests.m
@@ -34,44 +34,93 @@ static OFString *module = @"PBKDF2";
/* Test vectors from RFC 6070 */
TEST(@"PBKDF2-SHA1, 1 iteration",
- R(of_pbkdf2(HMAC, 1, (unsigned char *)"salt", 4, "password", 8, key,
- 20, true)) &&
- memcmp(key, "\x0C\x60\xC8\x0F\x96\x1F\x0E\x71\xF3\xA9\xB5\x24\xAF"
- "\x60\x12\x06\x2F\xE0\x37\xA6", 20) == 0)
+ R(of_pbkdf2((of_pbkdf2_parameters_t){
+ .HMAC = HMAC,
+ .iterations = 1,
+ .salt = (unsigned char *)"salt",
+ .saltLength = 4,
+ .password = "password",
+ .passwordLength = 8,
+ .key = key,
+ .keyLength = 20,
+ .allowsSwappableMemory = true
+ })) && memcmp(key, "\x0C\x60\xC8\x0F\x96\x1F\x0E\x71\xF3\xA9\xB5"
+ "\x24\xAF\x60\x12\x06\x2F\xE0\x37\xA6", 20) == 0)
TEST(@"PBKDF2-SHA1, 2 iterations",
- R(of_pbkdf2(HMAC, 2, (unsigned char *)"salt", 4, "password", 8, key,
- 20, true)) &&
- memcmp(key, "\xEA\x6C\x01\x4D\xC7\x2D\x6F\x8C\xCD\x1E\xD9\x2A\xCE"
- "\x1D\x41\xF0\xD8\xDE\x89\x57", 20) == 0)
+ R(of_pbkdf2((of_pbkdf2_parameters_t){
+ .HMAC = HMAC,
+ .iterations = 2,
+ .salt = (unsigned char *)"salt",
+ .saltLength = 4,
+ .password = "password",
+ .passwordLength = 8,
+ .key = key,
+ .keyLength = 20,
+ .allowsSwappableMemory = true
+ })) && memcmp(key, "\xEA\x6C\x01\x4D\xC7\x2D\x6F\x8C\xCD\x1E\xD9"
+ "\x2A\xCE\x1D\x41\xF0\xD8\xDE\x89\x57", 20) == 0)
TEST(@"PBKDF2-SHA1, 4096 iterations",
- R(of_pbkdf2(HMAC, 4096, (unsigned char *)"salt", 4, "password", 8,
- key, 20, true)) &&
- memcmp(key, "\x4B\x00\x79\x01\xB7\x65\x48\x9A\xBE\xAD\x49\xD9\x26"
- "\xF7\x21\xD0\x65\xA4\x29\xC1", 20) == 0)
+ R(of_pbkdf2((of_pbkdf2_parameters_t){
+ .HMAC = HMAC,
+ .iterations = 4096,
+ .salt = (unsigned char *)"salt",
+ .saltLength = 4,
+ .password = "password",
+ .passwordLength = 8,
+ .key = key,
+ .keyLength = 20,
+ .allowsSwappableMemory = true
+ })) && memcmp(key, "\x4B\x00\x79\x01\xB7\x65\x48\x9A\xBE\xAD\x49"
+ "\xD9\x26\xF7\x21\xD0\x65\xA4\x29\xC1", 20) == 0)
/* This test takes too long, even on a fast machine. */
#if 0
TEST(@"PBKDF2-SHA1, 16777216 iterations",
- R(of_pbkdf2(HMAC, 16777216, (unsigned char *)"salt", 4, "password",
- 8, key, 20, true)) &&
- memcmp(key, "\xEE\xFE\x3D\x61\xCD\x4D\xA4\xE4\xE9\x94\x5B\x3D\x6B"
- "\xA2\x15\x8C\x26\x34\xE9\x84", 20) == 0)
+ R(of_pbkdf2((of_pbkdf2_parameters_t){
+ .HMAC = HMAC,
+ .iterations = 16777216,
+ .salt = (unsigned char *)"salt",
+ .saltLength = 4,
+ .password = "password",
+ .passwordLength = 8,
+ .key = key,
+ .keyLength = 20,
+ .allowsSwappableMemory = true
+ })) && memcmp(key, "\xEE\xFE\x3D\x61\xCD\x4D\xA4\xE4\xE9\x94\x5B"
+ "\x3D\x6B\xA2\x15\x8C\x26\x34\xE9\x84", 20) == 0)
#endif
TEST(@"PBKDF2-SHA1, 4096 iterations, key > 1 block",
- R(of_pbkdf2(HMAC, 4096,
- (unsigned char *)"saltSALTsaltSALTsaltSALTsaltSALTsalt", 36,
- "passwordPASSWORDpassword", 24, key, 25, true)) &&
+ R(of_pbkdf2((of_pbkdf2_parameters_t){
+ .HMAC = HMAC,
+ .iterations = 4096,
+ .salt = (unsigned char *)"saltSALTsaltSALTsalt"
+ "SALTsaltSALTsalt",
+ .saltLength = 36,
+ .password = "passwordPASSWORDpassword",
+ .passwordLength = 24,
+ .key = key,
+ .keyLength = 25,
+ .allowsSwappableMemory = true
+ })) &&
memcmp(key, "\x3D\x2E\xEC\x4F\xE4\x1C\x84\x9B\x80\xC8\xD8\x36\x62"
- "\xC0\xE4\x4A\x8B\x29\x1A\x96\x4C\xF2\xF0\x70\x38", 25) == 0)
+ "\xC0\xE4\x4A\x8B\x29\x1A\x96\x4C\xF2\xF0\x70\x38", 25) == 0)
TEST(@"PBKDF2-SHA1, 4096 iterations, key < 1 block",
- R(of_pbkdf2(HMAC, 4096, (unsigned char *)"sa\0lt", 5, "pass\0word",
- 9, key, 16, true)) &&
- memcmp(key, "\x56\xFA\x6A\xA7\x55\x48\x09\x9D\xCC\x37\xD7\xF0\x34"
- "\x25\xE0\xC3", 16) == 0)
+ R(of_pbkdf2((of_pbkdf2_parameters_t){
+ .HMAC = HMAC,
+ .iterations = 4096,
+ .salt = (unsigned char *)"sa\0lt",
+ .saltLength = 5,
+ .password = "pass\0word",
+ .passwordLength = 9,
+ .key = key,
+ .keyLength = 16,
+ .allowsSwappableMemory = true
+ })) && memcmp(key, "\x56\xFA\x6A\xA7\x55\x48\x09\x9D\xCC\x37\xD7"
+ "\xF0\x34\x25\xE0\xC3", 16) == 0)
objc_autoreleasePoolPop(pool);
}
diff --git a/tests/ScryptTests.m b/tests/ScryptTests.m
index 3426d3c6..d0dc84da 100644
--- a/tests/ScryptTests.m
+++ b/tests/ScryptTests.m
@@ -156,24 +156,62 @@ static const unsigned char testVector4[64] = {
memcmp(ROMixBuffer, ROMixOutput, 128) == 0)
TEST(@"scrypt test vector #1",
- R(of_scrypt(1, 16, 1, (unsigned char *)"", 0, "", 0, output, 64,
- true)) && memcmp(output, testVector1, 64) == 0)
+ R(of_scrypt((of_scrypt_parameters_t){
+ .blockSize = 1,
+ .costFactor = 16,
+ .parallelization = 1,
+ .salt = (unsigned char *)"",
+ .saltLength = 0,
+ .password = "",
+ .passwordLength = 0,
+ .key = output,
+ .keyLength = 64,
+ .allowsSwappableMemory = true
+ })) && memcmp(output, testVector1, 64) == 0)
TEST(@"scrypt test vector #2",
- R(of_scrypt(8, 1024, 16, (unsigned char *)"NaCl", 4, "password", 8,
- output, 64, true)) && memcmp(output, testVector2, 64) == 0)
+ R(of_scrypt((of_scrypt_parameters_t){
+ .blockSize = 8,
+ .costFactor = 1024,
+ .parallelization = 16,
+ .salt = (unsigned char *)"NaCl",
+ .saltLength = 4,
+ .password = "password",
+ .passwordLength = 8,
+ .key = output,
+ .keyLength = 64,
+ .allowsSwappableMemory = true
+ })) && memcmp(output, testVector2, 64) == 0)
TEST(@"scrypt test vector #3",
- R(of_scrypt(8, 16384, 1, (unsigned char *)"SodiumChloride", 14,
- "pleaseletmein", 13, output, 64, true)) &&
- memcmp(output, testVector3, 64) == 0)
+ R(of_scrypt((of_scrypt_parameters_t){
+ .blockSize = 8,
+ .costFactor = 16384,
+ .parallelization = 1,
+ .salt = (unsigned char *)"SodiumChloride",
+ .saltLength = 14,
+ .password = "pleaseletmein",
+ .passwordLength = 13,
+ .key = output,
+ .keyLength = 64,
+ .allowsSwappableMemory = true
+ })) && memcmp(output, testVector3, 64) == 0)
/* The forth test vector is too expensive to include it in the tests. */
#if 0
TEST(@"scrypt test vector #4",
- R(of_scrypt(8, 1048576, 1, (unsigned char *)"SodiumChloride", 14,
- "pleaseletmein", 13, output, 64, true)) &&
- memcmp(output, testVector4, 64) == 0)
+ R(of_scrypt((of_scrypt_parameters_t){
+ .blockSize = 8,
+ .costFactor = 1048576,
+ .parallelization = 1,
+ .salt = (unsigned char *)"SodiumChloride",
+ .saltLength = 14,
+ .password = "pleaseletmein",
+ .passwordLength = 13,
+ .key = output,
+ .keyLength = 64,
+ .allowsSwappableMemory = true
+ })) && memcmp(output, testVector4, 64) == 0)
#endif
objc_autoreleasePoolPop(pool);
diff --git a/tests/TestsAppDelegate.m b/tests/TestsAppDelegate.m
index 0cedc59e..9ca00c16 100644
--- a/tests/TestsAppDelegate.m
+++ b/tests/TestsAppDelegate.m
@@ -215,10 +215,9 @@ main(int argc, char *argv[])
inModule: (OFString *)module
{
if (of_stdout.hasTerminal) {
- of_stdout.cursorColumn = 0;
of_stdout.foregroundColor = [OFColor lime];
[of_stdout eraseLine];
- [of_stdout writeFormat: @"[%@] %@: ok\n", module, test];
+ [of_stdout writeFormat: @"\r[%@] %@: ok\n", module, test];
} else
[of_stdout writeLine: @"ok"];
}
@@ -227,10 +226,9 @@ main(int argc, char *argv[])
inModule: (OFString *)module
{
if (of_stdout.hasTerminal) {
- of_stdout.cursorColumn = 0;
of_stdout.foregroundColor = [OFColor red];
[of_stdout eraseLine];
- [of_stdout writeFormat: @"[%@] %@: failed\n", module, test];
+ [of_stdout writeFormat: @"\r[%@] %@: failed\n", module, test];
#ifdef OF_WII
[of_stdout reset];
@@ -287,7 +285,7 @@ main(int argc, char *argv[])
}
#endif
- of_stdout.cursorColumn = 0;
+ [of_stdout writeString: @"\r"];
[of_stdout reset];
[of_stdout eraseLine];
} else
diff --git a/tests/plugin/Makefile b/tests/plugin/Makefile
index ad1d89a9..eec3cc7c 100644
--- a/tests/plugin/Makefile
+++ b/tests/plugin/Makefile
@@ -1,3 +1,5 @@
+DISTCLEAN = Info.plist
+
PLUGIN_NOINST = TestPlugin${PLUGIN_SUFFIX}
SRCS = TestPlugin.m
diff --git a/utils/ofarc/GZIPArchive.m b/utils/ofarc/GZIPArchive.m
index 6337ef78..24cd5f49 100644
--- a/utils/ofarc/GZIPArchive.m
+++ b/utils/ofarc/GZIPArchive.m
@@ -44,6 +44,22 @@ setPermissions(OFString *destination, OFString *source)
#endif
}
+static void
+setModificationDate(OFString *path, OFGZIPStream *stream)
+{
+ OFDate *modificationDate = stream.modificationDate;
+ of_file_attributes_t attributes;
+
+ if (modificationDate == nil)
+ return;
+
+ attributes = [OFDictionary
+ dictionaryWithObject: modificationDate
+ forKey: of_file_attribute_key_modification_date];
+ [[OFFileManager defaultManager] setAttributes: attributes
+ ofItemAtPath: path];
+}
+
@implementation GZIPArchive
+ (void)initialize
{
@@ -131,6 +147,9 @@ setPermissions(OFString *destination, OFString *source)
}
}
+ [output close];
+ setModificationDate(fileName, _stream);
+
if (app->_outputLevel >= 0) {
[of_stdout writeString: @"\r"];
[of_stdout writeLine: OF_LOCALIZED(@"extracting_file_done",
diff --git a/utils/ofarc/LHAArchive.m b/utils/ofarc/LHAArchive.m
index c85f0c3b..96a5be1b 100644
--- a/utils/ofarc/LHAArchive.m
+++ b/utils/ofarc/LHAArchive.m
@@ -56,6 +56,30 @@ setPermissions(OFString *path, OFLHAArchiveEntry *entry)
#endif
}
+static void
+setModificationDate(OFString *path, OFLHAArchiveEntry *entry)
+{
+ OFDate *modificationDate = entry.modificationDate;
+ of_file_attributes_t attributes;
+
+ if (modificationDate == nil) {
+ /*
+ * Fall back to the original date if we have no modification
+ * date, as the modification date is a UNIX extension.
+ */
+ modificationDate = entry.date;
+
+ if (modificationDate == nil)
+ return;
+ }
+
+ attributes = [OFDictionary
+ dictionaryWithObject: modificationDate
+ forKey: of_file_attribute_key_modification_date];
+ [[OFFileManager defaultManager] setAttributes: attributes
+ ofItemAtPath: path];
+}
+
@implementation LHAArchive
+ (void)initialize
{
@@ -285,6 +309,7 @@ setPermissions(OFString *path, OFLHAArchiveEntry *entry)
[fileManager createDirectoryAtPath: outFileName
createParents: true];
setPermissions(outFileName, entry);
+ setModificationDate(outFileName, entry);
if (app->_outputLevel >= 0) {
[of_stdout writeString: @"\r"];
@@ -341,6 +366,9 @@ setPermissions(OFString *path, OFLHAArchiveEntry *entry)
}
}
+ [output close];
+ setModificationDate(outFileName, entry);
+
if (app->_outputLevel >= 0) {
[of_stdout writeString: @"\r"];
[of_stdout writeLine: OF_LOCALIZED(
diff --git a/utils/ofarc/TarArchive.m b/utils/ofarc/TarArchive.m
index bf2b98cd..e2d3ef07 100644
--- a/utils/ofarc/TarArchive.m
+++ b/utils/ofarc/TarArchive.m
@@ -44,6 +44,22 @@ setPermissions(OFString *path, OFTarArchiveEntry *entry)
#endif
}
+static void
+setModificationDate(OFString *path, OFTarArchiveEntry *entry)
+{
+ OFDate *modificationDate = entry.modificationDate;
+ of_file_attributes_t attributes;
+
+ if (modificationDate == nil)
+ return;
+
+ attributes = [OFDictionary
+ dictionaryWithObject: modificationDate
+ forKey: of_file_attribute_key_modification_date];
+ [[OFFileManager defaultManager] setAttributes: attributes
+ ofItemAtPath: path];
+}
+
@implementation TarArchive
+ (void)initialize
{
@@ -306,6 +322,7 @@ setPermissions(OFString *path, OFTarArchiveEntry *entry)
[fileManager createDirectoryAtPath: outFileName
createParents: true];
setPermissions(outFileName, entry);
+ setModificationDate(outFileName, entry);
if (app->_outputLevel >= 0) {
[of_stdout writeString: @"\r"];
@@ -362,6 +379,9 @@ setPermissions(OFString *path, OFTarArchiveEntry *entry)
}
}
+ [output close];
+ setModificationDate(outFileName, entry);
+
if (app->_outputLevel >= 0) {
[of_stdout writeString: @"\r"];
[of_stdout writeLine: OF_LOCALIZED(
diff --git a/utils/ofarc/ZIPArchive.m b/utils/ofarc/ZIPArchive.m
index 586d1bbc..d6cf6196 100644
--- a/utils/ofarc/ZIPArchive.m
+++ b/utils/ofarc/ZIPArchive.m
@@ -57,6 +57,22 @@ setPermissions(OFString *path, OFZIPArchiveEntry *entry)
#endif
}
+static void
+setModificationDate(OFString *path, OFZIPArchiveEntry *entry)
+{
+ OFDate *modificationDate = entry.modificationDate;
+ of_file_attributes_t attributes;
+
+ if (modificationDate == nil)
+ return;
+
+ attributes = [OFDictionary
+ dictionaryWithObject: modificationDate
+ forKey: of_file_attribute_key_modification_date];
+ [[OFFileManager defaultManager] setAttributes: attributes
+ ofItemAtPath: path];
+}
+
@implementation ZIPArchive
+ (void)initialize
{
@@ -262,6 +278,7 @@ setPermissions(OFString *path, OFZIPArchiveEntry *entry)
[fileManager createDirectoryAtPath: outFileName
createParents: true];
setPermissions(outFileName, entry);
+ setModificationDate(outFileName, entry);
if (app->_outputLevel >= 0) {
[of_stdout writeString: @"\r"];
@@ -318,6 +335,9 @@ setPermissions(OFString *path, OFZIPArchiveEntry *entry)
}
}
+ [output close];
+ setModificationDate(outFileName, entry);
+
if (app->_outputLevel >= 0) {
[of_stdout writeString: @"\r"];
[of_stdout writeLine: OF_LOCALIZED(