Index: .fossil-settings/clean-glob
==================================================================
--- .fossil-settings/clean-glob
+++ .fossil-settings/clean-glob
@@ -37,11 +37,10 @@
tests/EBOOT.PBP
tests/Info.plist
tests/PARAM.SFO
tests/objc_sync/objc_sync
tests/plugin/Info.plist
-tests/serialization_xml.m
tests/terminal/terminal_tests
tests/testfile_bin.m
tests/testfile_ini.m
tests/tests
tests/tests.3dsx
Index: .fossil-settings/ignore-glob
==================================================================
--- .fossil-settings/ignore-glob
+++ .fossil-settings/ignore-glob
@@ -42,11 +42,10 @@
tests/iOS.xcodeproj/*.pbxuser
tests/iOS.xcodeproj/project.xcworkspace
tests/iOS.xcodeproj/xcuserdata
tests/objc_sync/objc_sync
tests/plugin/Info.plist
-tests/serialization_xml.m
tests/terminal/terminal_tests
tests/testfile_bin.m
tests/testfile_ini.m
tests/tests
tests/tests.3dsx
Index: .github/workflows/amiga-gcc.yml
==================================================================
--- .github/workflows/amiga-gcc.yml
+++ .github/workflows/amiga-gcc.yml
@@ -2,20 +2,15 @@
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
container: amigadev/crosstools:m68k-amigaos
- strategy:
- matrix:
- configure_flags:
- -
- - --disable-amiga-lib
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: autogen.sh
run: ./autogen.sh
- name: configure
- run: ./configure --host=m68k-amigaos ${{ matrix.configure_flags }}
+ run: ./configure --host=m68k-amigaos
- name: make
run: make -j$(nproc)
- name: make install
run: make install
Index: .github/workflows/ios.yml
==================================================================
--- .github/workflows/ios.yml
+++ .github/workflows/ios.yml
@@ -12,11 +12,11 @@
-
- --disable-shared
steps:
- name: Install dependencies
run: brew install autoconf automake
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: autogen.sh
run: ./autogen.sh
- name: configure
run: |
export IPHONEOS_DEPLOYMENT_TARGET="9.0"
Index: .github/workflows/macos-11.yml
==================================================================
--- .github/workflows/macos-11.yml
+++ .github/workflows/macos-11.yml
@@ -16,11 +16,11 @@
- --disable-files
- --disable-shared
steps:
- name: Install dependencies
run: brew install autoconf automake
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: autogen.sh
run: ./autogen.sh
- name: configure
run: ./configure ${{ matrix.configure_flags }}
- name: make
Index: .github/workflows/macos-12.yml
==================================================================
--- .github/workflows/macos-12.yml
+++ .github/workflows/macos-12.yml
@@ -16,11 +16,11 @@
- --disable-files
- --disable-shared
steps:
- name: Install dependencies
run: brew install autoconf automake
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: autogen.sh
run: ./autogen.sh
- name: configure
run: ./configure ${{ matrix.configure_flags }}
- name: make
ADDED .github/workflows/macos-13.yml
Index: .github/workflows/macos-13.yml
==================================================================
--- /dev/null
+++ .github/workflows/macos-13.yml
@@ -0,0 +1,31 @@
+name: macos-13
+on: [push, pull_request]
+jobs:
+ tests:
+ runs-on: macos-13
+ strategy:
+ matrix:
+ configure_flags:
+ -
+ - --disable-threads
+ - --disable-threads --disable-sockets
+ - --disable-threads --disable-files
+ - --disable-threads --disable-sockets --disable-files
+ - --disable-sockets
+ - --disable-sockets --disable-files
+ - --disable-files
+ - --disable-shared
+ steps:
+ - name: Install dependencies
+ run: brew install autoconf automake
+ - uses: actions/checkout@v4
+ - name: autogen.sh
+ run: ./autogen.sh
+ - name: configure
+ run: ./configure ${{ matrix.configure_flags }}
+ - name: make
+ run: make -j$(sysctl -n hw.logicalcpu)
+ - name: make check
+ run: make check
+ - name: make install
+ run: sudo make install
Index: .github/workflows/morphos.yml
==================================================================
--- .github/workflows/morphos.yml
+++ .github/workflows/morphos.yml
@@ -2,20 +2,15 @@
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
container: amigadev/crosstools:ppc-morphos
- strategy:
- matrix:
- configure_flags:
- -
- - --disable-amiga-lib
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: autogen.sh
run: ./autogen.sh
- name: configure
- run: ./configure --host=ppc-morphos ${{ matrix.configure_flags }}
+ run: ./configure --host=ppc-morphos
- name: make
run: make -j$(nproc)
- name: make install
run: make install
Index: .github/workflows/nintendo-3ds.yml
==================================================================
--- .github/workflows/nintendo-3ds.yml
+++ .github/workflows/nintendo-3ds.yml
@@ -4,11 +4,11 @@
build:
runs-on: ubuntu-latest
steps:
- name: Install dependencies
run: docker pull devkitpro/devkitarm
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: autogen.sh
run: ./autogen.sh
- name: configure
run: |
docker run \
Index: .github/workflows/nintendo-ds.yml
==================================================================
--- .github/workflows/nintendo-ds.yml
+++ .github/workflows/nintendo-ds.yml
@@ -4,11 +4,11 @@
build:
runs-on: ubuntu-latest
steps:
- name: Install dependencies
run: docker pull devkitpro/devkitarm
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: autogen.sh
run: ./autogen.sh
- name: configure
run: |
docker run \
Index: .github/workflows/nintendo-switch.yml
==================================================================
--- .github/workflows/nintendo-switch.yml
+++ .github/workflows/nintendo-switch.yml
@@ -4,11 +4,11 @@
build:
runs-on: ubuntu-latest
steps:
- name: Install dependencies
run: docker pull devkitpro/devkita64
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: autogen.sh
run: ./autogen.sh
- name: configure
run: |
docker run \
Index: .github/workflows/ubuntu-20.04-32bit.yml
==================================================================
--- .github/workflows/ubuntu-20.04-32bit.yml
+++ .github/workflows/ubuntu-20.04-32bit.yml
@@ -22,11 +22,11 @@
steps:
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install gcc-multilib
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: autogen.sh
run: ./autogen.sh
- name: configure
run: ./configure OBJC="clang -m32" ${{ matrix.configure_flags }}
- name: make
Index: .github/workflows/ubuntu-20.04-gcc-32bit.yml
==================================================================
--- .github/workflows/ubuntu-20.04-gcc-32bit.yml
+++ .github/workflows/ubuntu-20.04-gcc-32bit.yml
@@ -22,11 +22,11 @@
steps:
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install gcc-multilib gobjc
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: autogen.sh
run: ./autogen.sh
- name: configure
run: ./configure OBJC="gcc -m32" ${{ matrix.configure_flags }}
- name: make
Index: .github/workflows/ubuntu-20.04-gcc.yml
==================================================================
--- .github/workflows/ubuntu-20.04-gcc.yml
+++ .github/workflows/ubuntu-20.04-gcc.yml
@@ -24,11 +24,11 @@
steps:
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install gobjc libssl-dev gnutls-dev
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: autogen.sh
run: ./autogen.sh
- name: configure
run: ./configure OBJC="gcc" ${{ matrix.configure_flags }}
- name: make
Index: .github/workflows/ubuntu-20.04.yml
==================================================================
--- .github/workflows/ubuntu-20.04.yml
+++ .github/workflows/ubuntu-20.04.yml
@@ -24,11 +24,11 @@
steps:
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install libssl-dev gnutls-dev
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: autogen.sh
run: ./autogen.sh
- name: configure
run: ./configure ${{ matrix.configure_flags }}
- name: make
Index: .github/workflows/ubuntu-latest-32bit.yml
==================================================================
--- .github/workflows/ubuntu-latest-32bit.yml
+++ .github/workflows/ubuntu-latest-32bit.yml
@@ -22,11 +22,11 @@
steps:
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install gcc-multilib
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: autogen.sh
run: ./autogen.sh
- name: configure
run: ./configure OBJC="clang -m32" ${{ matrix.configure_flags }}
- name: make
Index: .github/workflows/ubuntu-latest-gcc-32bit.yml
==================================================================
--- .github/workflows/ubuntu-latest-gcc-32bit.yml
+++ .github/workflows/ubuntu-latest-gcc-32bit.yml
@@ -22,11 +22,11 @@
steps:
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install gcc-multilib gobjc
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: autogen.sh
run: ./autogen.sh
- name: configure
run: ./configure OBJC="gcc -m32" ${{ matrix.configure_flags }}
- name: make
Index: .github/workflows/ubuntu-latest-gcc.yml
==================================================================
--- .github/workflows/ubuntu-latest-gcc.yml
+++ .github/workflows/ubuntu-latest-gcc.yml
@@ -24,11 +24,11 @@
steps:
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install gobjc libssl-dev gnutls-dev
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: autogen.sh
run: ./autogen.sh
- name: configure
run: ./configure OBJC="gcc" ${{ matrix.configure_flags }}
- name: make
Index: .github/workflows/ubuntu-latest.yml
==================================================================
--- .github/workflows/ubuntu-latest.yml
+++ .github/workflows/ubuntu-latest.yml
@@ -24,11 +24,11 @@
steps:
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install libssl-dev gnutls-dev
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: autogen.sh
run: ./autogen.sh
- name: configure
run: ./configure ${{ matrix.configure_flags }}
- name: make
Index: .github/workflows/wii-u.yml
==================================================================
--- .github/workflows/wii-u.yml
+++ .github/workflows/wii-u.yml
@@ -4,11 +4,11 @@
build:
runs-on: ubuntu-latest
steps:
- name: Install dependencies
run: docker pull devkitpro/devkitppc
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: autogen.sh
run: ./autogen.sh
- name: configure
run: |
docker run \
Index: .github/workflows/wii.yml
==================================================================
--- .github/workflows/wii.yml
+++ .github/workflows/wii.yml
@@ -4,11 +4,11 @@
build:
runs-on: ubuntu-latest
steps:
- name: Install dependencies
run: docker pull devkitpro/devkitppc
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: autogen.sh
run: ./autogen.sh
- name: configure
run: |
docker run \
Index: .gitignore
==================================================================
--- .gitignore
+++ .gitignore
@@ -42,11 +42,10 @@
tests/iOS.xcodeproj/*.pbxuser
tests/iOS.xcodeproj/project.xcworkspace
tests/iOS.xcodeproj/xcuserdata
tests/objc_sync/objc_sync
tests/plugin/Info.plist
-tests/serialization_xml.m
tests/terminal/terminal_tests
tests/testfile_bin.m
tests/testfile_ini.m
tests/tests
tests/tests.3dsx
Index: ChangeLog
==================================================================
--- ChangeLog
+++ ChangeLog
@@ -2,11 +2,51 @@
* Changes of existing features or bugfixes
+ New features
This file only contains the most significant changes.
-ObjFW 0.90.1 -> ObjFW 0.90.2, 23.10.2017
+ObjFW 1.0.4 -> ObjFW 1.0.5, 2023-11-05
+ * Fixes the calculation of the extra alignment in OFAllocObject()
+ * Fixes +[OFSystemInfo networkInterfaces] on OpenBSD and Windows 98
+ * Fixes OFSocketAddressString() for AppleTalk addresses
+ * Uses GetModuleHandle() instead of LoadLibrary() where possible on Windows
+ * Disables tests for global blocks on Win64 due to broken compilers
+ * Adds PGP keys to verify tarballs and commits in the code repository
+
+ObjFW 1.0.3 -> ObjFW 1.0.4, 2023-10-08
+ * Fixes OFFile closing fd 0 when initialization fails
+ * Fixes -[stringByAppendingPathComponent:] on empty strings
+ * Fixes +[OFSystemInfo operatingSystemName] and
+ +[OFSystemInfo operatingSystemVersion] returning nil on some systems
+ * Adds a license for localizations
+
+ObjFW 1.0.2 -> ObjFW 1.0.3, 2023-09-14
+ * Fixes -[OFConcreteData initWithItemSize:] not setting freeWhenDone to true,
+ which resulted in a memory leak
+ * Fixes -[OFData initWithContentsOfIRI:] freeing the buffer in @catch instead
+ of @finally, which resulted in a memory leak
+
+ObjFW 1.0.1 -> ObjFW 1.0.2, 2023-09-11
+ * The build system has been updated to fix building .frameworks and to build
+ them differently for macOS and iOS
+
+ObjFW 1.0 -> ObjFW 1.0.1, 2023-09-10
+ * Hanging connections with OFTLSStream have been fixed when using OpenSSL
+ * The same fix as for OpenSSL has been applied to GnuTLS and SecureTransport
+ out of caution, even though there have been no hangs in practice
+ * The build system has been updated to fix building .frameworks among other
+ minor changes
+ * Some headers have been changed to fix compatibility with ObjC++
+ * Warnings about empty .o files on x86_64 Darwin have been fixed
+ * The OFDate documentation has been improved to list supported formats
+
+ObjFW 0.90.2 -> ObjFW 1.0, 2023-08-29
+ + First stable release with stable API and ABI
+ * Too many changes to list, as it has been almost 6 years since the last
+ release. See commits in the repository for details.
+
+ObjFW 0.90.1 -> ObjFW 0.90.2, 2017-10-23
* Fix shadowed variables which caused many bugs (e.g. using the wrong object)
* Many, many nullability fixes
* OFTCPSocket: Fix exception not being retained for async connect
* OFThread: Fix setting the name on the wrong thread
* OFMutableSet: Fix missing override for -[copy]
@@ -13,11 +53,11 @@
* configure: Fix posix_spawnp check
* Xcode project: Set the correct version for the bridge
* Better check for iOS
* tests: Fix testing the wrong OFKernelEventObserver
-ObjFW 0.90 -> ObjFW 0.90.1, 20.08.2017
+ObjFW 0.90 -> ObjFW 0.90.1, 2017-08-20
* OFData: Fix -[description]
* OFFileManager: Set errno to 0 before readdir()
* OFDate: Add -[localMinute]
* OFTarArchiveEntry: Fix prefix handling for ustar
* OFZIPArchive: Fix uncompressed + data descriptor
@@ -26,11 +66,11 @@
* OFGZIPStream: Add missing documentation
* Fix a linker warning on OpenBSD/SPARC64
* Remove the OFFile b modes from MorphOS
(they were already removed for all other OSes)
-ObjFW 0.8.1 -> ObjFW 0.90, 01.08.2017
+ObjFW 0.8.1 -> ObjFW 0.90, 2017-08-01
+ New classes: OFFileManager, OFGZIPStream, OFTarArchive, OFTarArchiveEntry
OFHMAC, OFSandbox, OFHTTPCookie, OFHTTPCookieManager,
OFLocalization
+ New platforms: Nintendo 3DS, MorphOS
+ New lookup assembly for platforms: SPARC64/ELF, ARM64/ELF
@@ -58,11 +98,11 @@
+ scrypt
+ Xcode project to build for iOS
+ String decomposition to NFD
* OFFile modes simplified ('b' removed)
-ObjFW 0.8 -> ObjFW 0.8.1, 04.10.2015
+ObjFW 0.8 -> ObjFW 0.8.1, 2015-10-04
* Adjust to __nullable / __nonnull being changed to _Nullable / _Nonnull in
Clang 3.7 (this fixes compilation with Clang 3.7)
* Blocks: Proper handling when called from a byref handler
* Fix compilation on Solaris
* Fix compilation for Wii, PSP and Nintendo DS
@@ -72,11 +112,11 @@
* Special cases for the Wii's weird network stack (fixes the tests)
* Better length checks for write / send calls
* Don't use -pedantic on platforms where it's broken by the system headers
* Documentation fixes
-ObjFW 0.7.1 -> ObjFW 0.8, 14.08.2015
+ObjFW 0.7.1 -> ObjFW 0.8, 2015-08-14
+ An insanely huge amount of new APIs
+ New classes: OFHTTPServer, OFINICategory, OFINIFile, OFInflate64Stream,
OFInflateStream, OFMapTable, OFRIPEMD160Hash, OFSHA224Hash, OFSHA256Hash,
OFSHA384Hash, OFSHA512Hash, OFSettings, OFStdIOStream, OFSystemInfo,
@@ -121,20 +161,20 @@
* Rewritten OFMD5Hash and OFSHA1Hash
* Reworked OFTLSSocket API (easier verification)
* Unicode support updated to Unicode 8.0
* OFURL: Proper escaping and unescaping
-ObjFW 0.7 -> ObjFW 0.7.1, 12.11.2012
+ObjFW 0.7 -> ObjFW 0.7.1, 2012-11-12
+ Support for Haiku
* Autorelease pools now work properly without __thread
* Incorrect framework version in Xcode project fixed
* Documentation fixes and improvements
* Blocks now only use 16 bits for the reference count in order to avoid
problems with newer Clang versions
* More use of OF_SENTINEL
-ObjFW 0.6 -> ObjFW 0.7, 27.10.2012
+ObjFW 0.6 -> ObjFW 0.7, 2012-10-27
Again, the differences are more than in any release before, thus listing them
all would be too much. The major differences are:
+ ObjFW now comes with its own runtime, which greatly increases performance
compared to the GNU runtime and is even faster than the Apple runtime
(using Clang >= 3.2 is recommended, but not necessary)
@@ -154,11 +194,11 @@
* All private methods use the prefix OF_ now instead of _, making it possible
to use the _ prefix in applications
* Most ObjC compiler feature checks are not part of configure anymore, making
it possible to use the same installation with different compilers
-ObjFW 0.5.4 -> ObjFW 0.6, 27.02.2012
+ObjFW 0.5.4 -> ObjFW 0.6, 2012-02-27
The differences between 0.5.4 and 0.6 are too big to list them all. However,
the major new features are:
* OFString, OFArray, OFDictionary, OFSet and OFCountedSet are now class
clusters
+ Serialization and deserialization of objects into/from XML and JSON
@@ -170,38 +210,38 @@
+ There are several backends for OFStreamObserver now, including kqueue, poll
and select
+ SOCKS5 support for OFTCPSockets (client only)
* Several API changes
-ObjFW 0.5.3 -> ObjFW 0.5.4, 30.08.2011
+ObjFW 0.5.3 -> ObjFW 0.5.4, 2011-08-30
* The blocks runtime is now working correctly
* Documentation fixes
* -framework works with objfw-compile now
+ Support for QNX
* Various small fixes
-ObjFW 0.5.2 -> ObjFW 0.5.3, 01.07.2011
+ObjFW 0.5.2 -> ObjFW 0.5.3, 2011-07-01
* Lots of bugfixes, see Git log for details
-ObjFW 0.5.1 -> ObjFW 0.5.2, 25.04.2011
+ObjFW 0.5.1 -> ObjFW 0.5.2, 2011-04-25
* Fix double-retain in OFList
* Don't ignore the timeout in OFStreamObserver when using select()
* Do -[OFURL copy] in a try block to prevent a leak when an exception occurs
* Fix too big buffer in -[OFMutableString _applyTable:withSize:]
* Call madvise() on the correct length variable so it covers the whole string
* Fix a warning when sizeof(size_t) < sizeof(long long)
* Skip possible BOMs when appending strings
-ObjFW 0.5 -> ObjFW 0.5.1, 21.04.2011
+ObjFW 0.5 -> ObjFW 0.5.1, 2011-04-21
* Work around a wrong warning produced by Apple GCC 4.0.1 which would cause
the build to fail due to -Werror
* Call objc_thread_{add,remove} when using the GNU runtime to make sure the
runtime knows about our thread
* Detach a thread before restarting if it was never joined
* Release the old return value when restarting a thread
-ObjFW 0.4-alpha1 -> 0.5, 09.04.2011
+ObjFW 0.4-alpha1 -> 0.5, 2011-04-09
+ %@ is now allowed in format strings
+ Added of_log for easy logging
* Exceptions have one header per exception now
* Lots of exception improvements
* Huge improvements in XML handling
@@ -217,11 +257,11 @@
+ Support for Base64
+ Use a real Xcode project instead of just calling make
+ Add Haiku to the list of supported platforms
* Lots of small bugfixes and countless small changes. Read the commits!
-ObjFW 0.3.1 -> 0.4-alpha1, 03.01.2011
+ObjFW 0.3.1 -> 0.4-alpha1, 2011-01-03
* ObjFW is now available under the terms of the QPL, GPLv2 and GPLv3
+ Support for blocks was added, including a blocks runtime
+ Added support for the new GNU runtime, introduced in GCC 4.6
* Objects returned from collections are no longer retained and autoreleased
+ Added new classes OFXMLParser, OFXMLElement, OFXMLAttribute and
@@ -236,20 +276,20 @@
* objfw-compile now has a new syntax
+ objfw-compile can now compile libraries and plugins
* Many small changes and new features that would be too much to list here
The diff between 0.3.1 and 0.4-alpha1 has almost 24000 lines!
-ObjFW 0.3 -> 0.3.1, 19.06.2010
+ObjFW 0.3 -> 0.3.1, 2010-06-19
* Fix a typo in OFMutableDictionary that prevented termination in case
the last bucket is already used when the dictionary is resized
* The mutations pointer is now correctly initialized in enumerators for
immutable collections
* The objc_sync test was still using the old threads API and was
updated to use the new one now
* PLATFORMS has been updated to be more specific
-ObjFW 0.2.1 -> 0.3, 09.05.2010
+ObjFW 0.2.1 -> 0.3, 2010-05-09
+ Many new methods were added to different classes
+ A huge amount of methods was added to OFStream, allowing easy binary
stream handling and even mixing string-based and binary operations
+ An optional write buffer was added to OFStream
+ OFSeekableStream was added for streams that allow seeking, for example
@@ -286,19 +326,19 @@
by the compiler
+ The library version is now included in the resulting dylib and libobjc is
reexported now. Additionally, objfw-config offers --reexport now to produce
libraries that link against ObjFW and reexport it
-ObjFW 0.2 -> 0.2.1, 14.03.2010
+ObjFW 0.2 -> 0.2.1, 2010-03-14
* Fix for OFNumbers not doing calculations
* Improved -[hash] for OFNumbers with floats and doubles
+ Tests for OFNumber
* Small optimization for OFArray's -[componentsJoinedByString:]
* Documentation improvements
* Updated copyright
-ObjFW 0.1.2 -> 0.2, 01.02.2010
+ObjFW 0.1.2 -> 0.2, 2010-02-01
+ Support for ObjC 2 Fast Enumerations on every platform which has
compiler support for fast enumerations
+ Support for ObjC 2 properties on every platform with compiler support
+ Fast Enumeration through arrays and dictionaries
* OFIterator has been removed
@@ -323,17 +363,17 @@
* File methods unavailable on Windows don't throw an exception at
runtime anymore, but instead are not even in the interface on
Windows. This way, it is a compile time error instead of a runtime
error
-ObjFW 0.1.1 -> 0.1.2, 15.01.2010
+ObjFW 0.1.1 -> 0.1.2, 2010-01-15
* Fix a bug in OFMutableArray's -[removeObject:] and
-[removeObjectIdenticalTo:] that could lead to not removing all
occurrences of the object from the array and to out of bounds reads
* Change the URL in the framework plist to the homepage
-ObjFW 0.1 -> 0.1.1, 04.01.2010
+ObjFW 0.1 -> 0.1.1, 2010-01-04
* Fix a missing out of range check for -[removeNItems:atIndex:] that
allowed the programmer to specify too big ranges so it would crash
instead of throwing an exception
* Fix missing calls to -[retain] and -[autorelease] when getting
objects from an OFArray or OFDictionary
@@ -344,7 +384,7 @@
this is a serious programmer error
* -[readLineWithEncoding:] is more fault-tolerant now and does not
lose data when it stumbles upon invalid encoding. Instead, it allows
recalling with the correct encoding now
-ObjFW 0.1, 24.12.2009
+ObjFW 0.1, 2009-12-24
+ Initial release
Index: Doxyfile
==================================================================
--- Doxyfile
+++ Doxyfile
@@ -6,37 +6,46 @@
HAVE_DOT = NO
GENERATE_LATEX = NO
HIDE_UNDOC_CLASSES = YES
HIDE_UNDOC_MEMBERS = YES
TYPEDEF_HIDES_STRUCT = YES
-PREDEFINED = __OBJC__ \
- _Nonnull= \
- _Nullable= \
- DOXYGEN \
- OF_BOXABLE= \
- OF_CONSUMED= \
- OF_DESIGNATED_INITIALIZER= \
- OF_GENERIC(...)= \
- OF_HAVE_BLOCKS \
- OF_HAVE_FILES \
- OF_HAVE_SANDBOX \
- OF_HAVE_SOCKETS \
- OF_HAVE_THREADS \
- OF_KINDOF(...)= \
- OF_NO_RETURN= \
- OF_NO_RETURN_FUNC= \
- OF_NULLABLE_PROPERTY(...)= \
- OF_NULL_RESETTABLE_PROPERTY(...)= \
- OF_REQUIRES_SUPER= \
- OF_RETURNS_INNER_POINTER= \
- OF_RETURNS_NOT_RETAINED= \
- OF_RETURNS_RETAINED= \
- OF_ROOT_CLASS= \
- OF_SENTINEL= \
- OF_WARN_UNUSED_RESULT= \
- OF_WEAK_UNAVAILABLE= \
- SIGHUP \
- SIGUSR1 \
+PREDEFINED = _Nonnull= \
+ _Nullable= \
+ DOXYGEN \
+ OF_BOXABLE= \
+ OF_CONSUMED= \
+ OF_DESIGNATED_INITIALIZER= \
+ OF_FILE_MANAGER_SUPPORTS_EXTENDED_ATTRIBUTES \
+ OF_FILE_MANAGER_SUPPORTS_LINKS \
+ OF_FILE_MANAGER_SUPPORTS_OWNER \
+ OF_FILE_MANAGER_SUPPORTS_PERMISSIONS \
+ OF_FILE_MANAGER_SUPPORTS_SYMLINKS \
+ OF_GENERIC(...)= \
+ OF_HAVE_APPLETALK \
+ OF_HAVE_BLOCKS \
+ OF_HAVE_FILES \
+ OF_HAVE_IPV6 \
+ OF_HAVE_IPX \
+ OF_HAVE_PLUGINS \
+ OF_HAVE_SANDBOX \
+ OF_HAVE_SOCKETS \
+ OF_HAVE_THREADS \
+ OF_HAVE_UNICODE_TABLES \
+ OF_KINDOF(...)= \
+ OF_NO_RETURN= \
+ OF_NO_RETURN_FUNC= \
+ OF_NULLABLE_PROPERTY(...)= \
+ OF_NULL_RESETTABLE_PROPERTY(...)= \
+ OF_REQUIRES_SUPER= \
+ OF_RETURNS_INNER_POINTER= \
+ OF_RETURNS_NOT_RETAINED= \
+ OF_RETURNS_RETAINED= \
+ OF_ROOT_CLASS= \
+ OF_SENTINEL= \
+ OF_WARN_UNUSED_RESULT= \
+ OF_WEAK_UNAVAILABLE= \
+ SIGHUP \
+ SIGUSR1 \
SIGUSR2
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
IGNORE_PREFIX = OF of_
Index: Makefile
==================================================================
--- Makefile
+++ Makefile
@@ -10,11 +10,11 @@
config.status \
extra.mk
include buildsys.mk
-.PHONY: docs release
+.PHONY: check docs release
utils tests: src
check: tests
cd tests && ${MAKE} -s run
@@ -33,13 +33,10 @@
ofarc -cq objfw-${PACKAGE_VERSION}.tar objfw-${PACKAGE_VERSION}
rm -fr objfw-${PACKAGE_VERSION}
gzip -9 objfw-${PACKAGE_VERSION}.tar
rm -f objfw-${PACKAGE_VERSION}.tar
gpg -b objfw-${PACKAGE_VERSION}.tar.gz || true
- echo "Generating documentation..."
- rm -fr docs
- doxygen >/dev/null
rm -fr objfw-docs-${PACKAGE_VERSION} objfw-docs-${PACKAGE_VERSION}.tar \
objfw-docs-${PACKAGE_VERSION}.tar.gz
mv docs objfw-docs-${PACKAGE_VERSION}
echo "Generating docs tarball for version ${PACKAGE_VERSION}..."
ofarc -cq objfw-docs-${PACKAGE_VERSION}.tar \
Index: PLATFORMS.md
==================================================================
--- PLATFORMS.md
+++ PLATFORMS.md
@@ -43,23 +43,32 @@
DragonFlyBSD
------------
* OS Versions: 3.0, 3.3-DEVELOPMENT
- * Architectures: x86, x86_64
+ * Architectures: AMD64, x86
* Compilers: GCC 4.4.7
* Runtimes: ObjFW
FreeBSD
-------
* OS Versions: 9.1-rc3, 10.0
- * Architectures: x86_64
+ * Architectures: AMD64
* Compilers: Clang 3.1, Clang 3.3
* Runtimes: ObjFW
+
+GNU/Hurd
+--------
+
+ * OS Versions: 0.9
+ * Architectures: i686
+ * Compilers: Clang 14.0.6
+ * Runtimes: ObjFW
+
Haiku
-----
* OS version: r1-alpha4
@@ -69,11 +78,11 @@
HP-UX
-----
- * OS versions: 11i v1 (PA-RISC 2.0), 11i v3 (Itanium)
+ * OS versions: 11i v1, 11i v3
* Architectures: Itanium, PA-RISC 2.0
* Compilers: GCC 4.7.2, GCC 7.5.0
* Runtimes: ObjFW
* Notes: Exception handling on Itanium in 32 bit mode is broken, you need to
use 64 bit mode by passing `OBJC="gcc -mlp64"` to `configure`.
@@ -88,22 +97,22 @@
Linux
-----
- * Architectures: Alpha, ARMv6, ARMv7, ARM64, Itanium, m68k, MIPS (O32),
- MIPS64 (N64), RISC-V 64, PowerPC, S390x, SuperH-4, x86,
- x86_64
+ * Architectures: Alpha, AMD64, ARMv6, ARMv7, ARM64, Itanium, m68k, MIPS (O32),
+ MIPS64 (N64), RISC-V 64, PowerPC, S390x, SuperH-4, x86
* Compilers: Clang 3.0-10.0, GCC 4.6-10.0
+ * C libraries: glibc, musl
* Runtimes: ObjFW
macOS
-----
* OS Versions: 10.5, 10.7-10.15, Darling
- * Architectures: PowerPC, PowerPC64, x86, x86_64
+ * Architectures: AMD64, PowerPC, PowerPC64, x86
* Compilers: Clang 3.1-10.0, Apple GCC 4.0.1 & 4.2.1
* Runtimes: Apple, ObjFW
MiNT
@@ -127,12 +136,12 @@
NetBSD
------
* OS Versions: 5.1-9.0
- * Architectures: ARM, ARM (big endian, BE8 mode), MIPS (O32), PowerPC, SPARC,
- SPARC64, x86, x86_64
+ * Architectures: AMD64, ARM, ARM (big endian, BE8 mode), MIPS (O32), PowerPC,
+ SPARC, SPARC64, x86
* Compilers: Clang 3.0-3.2, GCC 4.1.3 & 4.5.3 & 7.4.0
* Runtimes: ObjFW
Nintendo 3DS
@@ -167,11 +176,11 @@
OpenBSD
-------
* OS Versions: 5.2-6.7
- * Architectures: MIPS64, PA-RISC, PowerPC, SPARC64, x86_64
+ * Architectures: AMD64, MIPS64, PA-RISC, PowerPC, SPARC64
* Compilers: GCC 6.3.0, Clang 4.0
* Runtimes: ObjFW
PlayStation Portable
@@ -194,13 +203,13 @@
Solaris
-------
- * OS Versions: OpenIndiana 2015.03
- * Architectures: x86, x86_64
- * Compilers: Clang 3.4.2, GCC 4.8.3
+ * OS Versions: OpenIndiana 2015.03, OpenIndiana 2023.04, Oracle Solaris 11.4
+ * Architectures: AMD64, x86
+ * Compilers: Clang 3.4.2, Clang 11.0.0, Clang 13.0.1, GCC 4.8.3, GCC 10.4.0
* Runtimes: ObjFW
Wii
---
@@ -224,16 +233,15 @@
Windows
-------
- * OS Versions: 98 SE, NT 4.0, XP (x86), 7 (x64), 8 (x64), 8.1 (x64), 10, 11,
- Wine (x86 & x64)
- * Architectures: x86, x86_64, AArch64
- * Compilers: GCC 5.3.0 & 6.2.0 from msys2 (x86 & x64),
+ * OS Versions: 98 SE, NT 4.0, XP, 7, 8, 8.1, 10, 11, Wine
+ * Architectures: AArch64, AMD64, x86
+ * Compilers: GCC 5.3.0 & 6.2.0 from msys2 (AMD64 & x86),
Clang 3.9.0 from msys2 (x86),
- Clang 10.0 from msys2 (x86 & x86_64),
+ Clang 10.0 from msys2 (AMD64 & x86),
Clang 14.0.4 from msys2 (AArch64)
* Runtimes: ObjFW
Others
@@ -254,16 +262,16 @@
As forwarding needs hand-written assembly for each combination of CPU
architecture, executable format and calling convention, it is only available
for the following platforms (except resolveClassMethod: and
resolveInstanceMethod:, which are always available):
+ * AMD64 (SysV/ELF, Apple/Mach-O, Mach-O, Win64/PE)
* ARM (EABI/ELF, Apple/Mach-O)
* 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)
Apple/Mach-O means both, the Apple ABI and runtime, while Mach-O means the
ObjFW runtime on Mach-O.
Index: README.md
==================================================================
--- README.md
+++ README.md
@@ -9,14 +9,15 @@
Table of Contents
* [What is ObjFW?](#what)
+ * [Installation](#installation)
* [License](#license)
* [Releases](#releases)
* [Cloning the repository](#cloning)
- * [Installation](#installation)
+ * [Building from source](#building-from-source)
* [macOS and iOS](#macos-and-ios)
* [Building as a framework](#building-framework)
* [Using the macOS or iOS framework in Xcode](#framework-in-xcode)
* [Broken Xcode versions](#broken-xcode-versions)
* [Windows](#windows)
@@ -52,11 +53,11 @@
* GNUstep already provides a reimplementation of Foundation, which is only
compatible to a certain degree. This means that a developer still needs to
care about differences between frameworks if they want to be portable. The
idea behind ObjFW is that a developer does not need to concern themselves
- with portablility and making sure their code works with multiple
+ with portability and making sure their code works with multiple
frameworks: Instead, if it works it ObjFW on one platform, they can
reasonably expect it to also work with ObjFW on another platform. ObjFW
behaving differently on different operating systems (unless inevitable
because it is a platform-specific part, like the Windows Registry) is
considered a bug and will be fixed.
@@ -72,10 +73,36 @@
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.
+
+Installation
+
+ ObjFW packages are available for various operating systems and can be
+ installed as following:
+
+ Operating System | Command
+ ---------------------------|---------------------------------------------
+ Alpine Linux | `doas apk add objfw`
+ CRUX | `sudo prt-get depinst objfw`
+ Fedora | `sudo dnf install objfw`
+ FreeBSD | `sudo pkg install objfw`
+ Haiku | `pkgman install objfw`
+ Haiku (gcc2h) | `pkgman install objfw_x86`
+ macOS (Homebrew) | `brew install objfw`
+ macOS (pkgsrc) | `cd $PKGSRCDIR/devel/objfw && make install`
+ NetBSD | `cd /usr/pkgsrc/devel/objfw && make install`
+ OpenBSD | `doas pkg_add objfw`
+ OpenIndiana | `sudo pkg install developer/objfw`
+ Windows (MSYS2/MINGW32) | `pacman -S mingw-w64-i686-objfw`
+ Windows (MSYS2/CLANG64) | `pacman -S mingw-w64-clang-x86_64-objfw`
+ Windows (MSYS2/CLANGARM64) | `pacman -S mingw-w64-clang-aarch64-objfw`
+
+ If your operating system is not listed, you can
+ build ObjFW from source.
+
License
ObjFW is released under three licenses:
@@ -91,11 +118,11 @@
none of them work for you, contact me and we can find a solution.
Releases
- Releases of ObjFW, as well as changelogs and the accompanying documentation
+ Releases of ObjFW, as well as change logs and the accompanying documentation,
can be found [here](https://objfw.nil.im/wiki?name=Releases).
Cloning the repository
@@ -115,14 +142,10 @@
wiki pages, etc.:
$ cd objfw
$ 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.
-
In order to verify the signature of the currently checked out checkin, you
can use:
$ fossil artifact current | gpg --verify
@@ -139,13 +162,13 @@
$ git clone https://github.com/ObjFW/ObjFW
Git commits are not signed, so if you want to check the signature of an
individual commit, branch head or tag, please use Fossil.
-Installation
+Building from source
- To install ObjFW, just run the following commands:
+ To build ObjFW from source and install it, just run the following commands:
$ ./configure
$ make
$ make check
$ sudo make install
@@ -162,29 +185,28 @@
When building for macOS or iOS, everything is built as a `.framework` by
default if `--disable-shared` has not been specified to `./configure`. The
frameworks will end up in `$PREFIX/Library/Frameworks`.
To build for macOS, just follow the
- regular instructions above.
+ regular instructions above.
To build for iOS, follow the regular instructions, but instead of
`./configure` do something like this:
- $ clang="clang -isysroot $(xcrun --sdk iphoneos --show-sdk-path)"
- $ export OBJC="$clang -arch armv7 -arch arm64"
- $ export OBJCPP="$clang -arch armv7 -E"
- $ export IPHONEOS_DEPLOYMENT_TARGET="9.0"
+ $ clang="xcrun --sdk iphoneos clang"
+ $ export OBJC="$clang -arch arm64e -arch arm64"
+ $ export OBJCPP="$clang -arch arm64e -E"
+ $ export IPHONEOS_DEPLOYMENT_TARGET="10.0"
$ ./configure --prefix=/usr/local/ios --host=arm64-apple-darwin
To build for the iOS simulator, follow the regular instructions, but instead
of `./configure` use something like this:
- $ clang="clang -isysroot $(xcrun --sdk iphonesimulator --show-sdk-path)"
- $ export OBJC="$clang -arch arm64 -arch x86_64"
- $ export OBJCPP="$clang -arch arm64 -E"
- $ export IPHONEOS_DEPLOYMENT_TARGET="9.0"
- $ ./configure --prefix=/usr/local/iossim --host=arm64-apple-darwin
+ $ clang="xcrun --sdk iphonesimulator clang"
+ $ export OBJC="$clang -arch $(uname -m)"
+ $ export IPHONEOS_DEPLOYMENT_TARGET="10.0"
+ $ ./configure --prefix=/usr/local/iossim --host=$(uname -m)-apple-darwin
Using the macOS or iOS framework in Xcode
To use the macOS framework in Xcode, you need to add the `.framework`s to
your project and add the following flags to `Other C Flags`:
@@ -321,11 +343,11 @@
To create your first, empty application, you can use `objfw-new`:
$ objfw-new --app MyFirstApp
- This creates a file `MyFirstApp.m`. The `-[applicationDidFinishLaunching]`
+ This creates a file `MyFirstApp.m`. The `-[applicationDidFinishLaunching:]`
method is called as soon as ObjFW finished all initialization. Use this as
the entry point to your own code. For example, you could add the following
line there to create a "Hello World":
[OFStdOut writeLine: @"Hello World!"];
@@ -366,20 +388,18 @@
If you have any questions about ObjFW or would like to talk to other ObjFW
users, the following venues are available:
* The [forum](https://objfw.nil.im/forum)
* A [Matrix room](https://matrix.to/#/%23objfw:nil.im)
+ * A [Discord room](https://objfw.nil.im/discord), bridged to the Matrix
+ room above
+ * A [Telegram room](https://t.me/objfw), bridged to the Matrix room above
+ * A [Slack room](https://objfw.nil.im/slack), bridged to the Matrix room
+ above
* An IRC channel named `#objfw` on `irc.oftc.net`
([Web chat](https://webchat.oftc.net/?channels=%23objfw)), bridged to the
Matrix room above
- * A [Slack channel](https://objfw.nil.im/slack), bridged to the Matrix room
- above
- * A [Discord channel](https://objfw.nil.im/discord), bridged to the Matrix
- room above
- * A [Telegram room](https://t.me/objfw), bridged to the Matrix room above
- * A [Gitter room](https://gitter.im/ObjFW/ObjFW), bridged to the Matrix room
- above
Please don't hesitate to join any or all of those!
Donating
@@ -392,14 +412,14 @@
* Thank you to [Jonathan Neuschäfer](https://github.com/neuschaefer) for
reviewing the *entirety* (all 84k LoC at the time) of ObjFW's codebase in
2017!
* Thank you to [Hill Ma](https://github.com/mahiuchun) for donating an M1 Mac
- Mini to the project!
+ Mini to the project in 2022!
Commercial use
If for whatever reason neither the terms of the QPL nor those of the GPL work
for you, a proprietary license for ObjFW including support is available upon
request. Just write a mail to js@nil.im and we can find a reasonable solution
for both parties.
Index: autogen.sh
==================================================================
--- autogen.sh
+++ autogen.sh
@@ -1,11 +1,13 @@
#!/bin/sh
set -e
# Set a version for OpenBSD
-: ${AUTOCONF_VERSION:=2.69}
-: ${AUTOMAKE_VERSION:=1.16}
-export AUTOCONF_VERSION AUTOMAKE_VERSION
+if test x"$(uname -s)" = x"OpenBSD"; then
+ : ${AUTOCONF_VERSION:=2.71}
+ : ${AUTOMAKE_VERSION:=1.16}
+ export AUTOCONF_VERSION AUTOMAKE_VERSION
+fi
aclocal -I build-aux/m4
autoconf
autoheader
Index: build-aux/m4/buildsys.m4
==================================================================
--- build-aux/m4/buildsys.m4
+++ build-aux/m4/buildsys.m4
@@ -1,8 +1,8 @@
dnl
dnl Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2016, 2017,
-dnl 2018, 2020, 2021
+dnl 2018, 2020, 2021, 2022, 2023
dnl Jonathan Schleifer
dnl
dnl https://fossil.nil.im/buildsys
dnl
dnl Permission to use, copy, modify, and/or distribute this software for any
@@ -27,10 +27,14 @@
AC_REQUIRE([AC_CANONICAL_HOST])
AC_ARG_ENABLE(rpath,
AS_HELP_STRING([--disable-rpath], [do not use rpath]))
+ AC_ARG_ENABLE(silent-rules,
+ AS_HELP_STRING([--disable-silent-rules],
+ [print executed commands during build]))
+
case "$build_os" in
darwin*)
case "$host_os" in
darwin*)
AC_SUBST(BUILD_AND_HOST_ARE_DARWIN, yes)
@@ -125,10 +129,15 @@
"$($TPUT AF 4 2>/dev/null)")
AC_SUBST(TERM_SETAF6,
"$($TPUT AF 6 2>/dev/null)")
fi
])
+
+ AS_IF([test x"$enable_silent_rules" != x"no"], [
+ AC_SUBST(SILENT, '.SILENT:')
+ AC_SUBST(MAKEFLAGS_SILENT, '-s')
+ ])
])
])
AC_DEFUN([BUILDSYS_CHECK_IOS], [
case "$host_os" in
@@ -142,14 +151,16 @@
TARGET_OS_SIMULATOR)
yes
#endif
], [
host_is_ios="yes"
+ AC_SUBST(HOST_IS_IOS, yes)
], [
host_is_ios="no"
])
AC_MSG_RESULT($host_is_ios)
+ AC_CHECK_TOOL(CODESIGN, codesign)
;;
esac
])
AC_DEFUN([BUILDSYS_PROG_IMPLIB], [
@@ -173,11 +184,11 @@
])
AC_DEFUN([BUILDSYS_SHARED_LIB], [
AC_REQUIRE([AC_CANONICAL_HOST])
AC_REQUIRE([BUILDSYS_CHECK_IOS])
- AC_MSG_CHECKING(for shared library system)
+ AC_MSG_CHECKING(for shared library type)
case "$host" in
*-*-darwin*)
AC_MSG_RESULT(Darwin)
LIB_CFLAGS='-fPIC -DPIC'
@@ -186,22 +197,12 @@
LIB_PREFIX='lib'
LIB_SUFFIX='.dylib'
AS_IF([test x"$enable_rpath" != x"no"], [
LDFLAGS_RPATH='-Wl,-rpath,${libdir}'
])
- PLUGIN_CFLAGS='-fPIC -DPIC'
- PLUGIN_LDFLAGS='-bundle ${PLUGIN_LDFLAGS_BUNDLE_LOADER}'
- PLUGIN_SUFFIX='.bundle'
- AS_IF([test x"$host_is_ios" = x"yes"], [
- LINK_PLUGIN='rm -fr $$out && ${MKDIR_P} $$out && if test -f Info.plist; then ${INSTALL} -m 644 Info.plist $$out/Info.plist; fi && ${LD} -o $$out/$${out%${PLUGIN_SUFFIX}} ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS} && ${CODESIGN} -fs ${CODESIGN_IDENTITY} --timestamp=none $$out'
- ], [
- LINK_PLUGIN='rm -fr $$out && ${MKDIR_P} $$out/Contents/MacOS && if test -f Info.plist; then ${INSTALL} -m 644 Info.plist $$out/Contents/Info.plist; fi && ${LD} -o $$out/Contents/MacOS/$${out%${PLUGIN_SUFFIX}} ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS} && ${CODESIGN} -fs ${CODESIGN_IDENTITY} --timestamp=none $$out'
- ])
INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib && ${LN_S} -f $${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.dylib && ${LN_S} -f $${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib ${DESTDIR}${libdir}/$$i'
UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.dylib ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib'
- INSTALL_PLUGIN='&& rm -fr ${DESTDIR}${plugindir}/$$i && cp -R $$i ${DESTDIR}${plugindir}/'
- UNINSTALL_PLUGIN='&& rm -fr ${DESTDIR}${plugindir}/$$i'
CLEAN_LIB=''
;;
*-*-mingw* | *-*-cygwin*)
AC_MSG_RESULT(MinGW / Cygwin)
LIB_CFLAGS=''
@@ -208,18 +209,12 @@
LIB_LDFLAGS='-shared -Wl,--export-all-symbols'
LIB_LDFLAGS_INSTALL_NAME=''
LIB_PREFIX=''
LIB_SUFFIX='${LIB_MAJOR}.dll'
LINK_LIB='&& rm -f lib$${out%${LIB_SUFFIX}}.dll.a && ${LN_S} $$out lib$${out%${LIB_SUFFIX}}.dll.a'
- PLUGIN_CFLAGS=''
- PLUGIN_LDFLAGS='-shared -Wl,--export-all-symbols'
- PLUGIN_SUFFIX='.dll'
- LINK_PLUGIN='${LD} -o $$out ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS}'
INSTALL_LIB='&& ${MKDIR_P} ${DESTDIR}${bindir} && ${INSTALL} -m 755 $$i ${DESTDIR}${bindir}/$$i && ${INSTALL} -m 755 lib$${i%${LIB_SUFFIX}}.dll.a ${DESTDIR}${libdir}/lib$${i%${LIB_SUFFIX}}.dll.a'
UNINSTALL_LIB='&& rm -f ${DESTDIR}${bindir}/$$i ${DESTDIR}${libdir}/lib$${i%${LIB_SUFFIX}}.dll.a'
- INSTALL_PLUGIN='&& ${INSTALL} -m 755 $$i ${DESTDIR}${plugindir}/$$i'
- UNINSTALL_PLUGIN='&& rm -f ${DESTDIR}${plugindir}/$$i'
CLEAN_LIB='${SHARED_LIB}.a ${SHARED_LIB_NOINST}.a'
;;
*-*-openbsd* | *-*-mirbsd*)
AC_MSG_RESULT(OpenBSD)
LIB_CFLAGS='-fPIC -DPIC'
@@ -228,18 +223,12 @@
LIB_PREFIX='lib'
LIB_SUFFIX='.so.${LIB_MAJOR}.${LIB_MINOR}'
AS_IF([test x"$enable_rpath" != x"no"], [
LDFLAGS_RPATH='-Wl,-rpath,${libdir}'
])
- PLUGIN_CFLAGS='-fPIC -DPIC'
- PLUGIN_LDFLAGS='-shared'
- PLUGIN_SUFFIX='.so'
- LINK_PLUGIN='${LD} -o $$out ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS}'
INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i'
UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i'
- INSTALL_PLUGIN='&& ${INSTALL} -m 755 $$i ${DESTDIR}${plugindir}/$$i'
- UNINSTALL_PLUGIN='&& rm -f ${DESTDIR}${plugindir}/$$i'
CLEAN_LIB=''
;;
*-*-solaris*)
AC_MSG_RESULT(Solaris)
LIB_CFLAGS='-fPIC -DPIC'
@@ -248,35 +237,23 @@
LIB_PREFIX='lib'
LIB_SUFFIX='.so'
AS_IF([test x"$enable_rpath" != x"no"], [
LDFLAGS_RPATH='-Wl,-rpath,${libdir}'
])
- PLUGIN_CFLAGS='-fPIC -DPIC'
- PLUGIN_LDFLAGS='-shared'
- PLUGIN_SUFFIX='.so'
- LINK_PLUGIN='${LD} -o $$out ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS}'
INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR} && rm -f ${DESTDIR}${libdir}/$$i && ${LN_S} $$i.${LIB_MAJOR}.${LIB_MINOR} ${DESTDIR}${libdir}/$$i'
UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}'
- INSTALL_PLUGIN='&& ${INSTALL} -m 755 $$i ${DESTDIR}${plugindir}/$$i'
- UNINSTALL_PLUGIN='&& rm -f ${DESTDIR}${plugindir}/$$i'
CLEAN_LIB=''
;;
*-*-android*)
AC_MSG_RESULT(Android)
LIB_CFLAGS='-fPIC -DPIC'
LIB_LDFLAGS='-shared -Wl,-soname=$$out.${LIB_MAJOR}'
LIB_LDFLAGS_INSTALL_NAME=''
LIB_PREFIX='lib'
LIB_SUFFIX='.so'
- PLUGIN_CFLAGS='-fPIC -DPIC'
- PLUGIN_LDFLAGS='-shared'
- PLUGIN_SUFFIX='.so'
- LINK_PLUGIN='${LD} -o $$out ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS}'
- INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.0 && ${LN_S} -f $$i.${LIB_MAJOR}.${LIB_MINOR}.0 ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} && ${LN_S} -f $$i.${LIB_MAJOR}.${LIB_MINOR}.0 ${DESTDIR}${libdir}/$$i'
- UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.0'
- INSTALL_PLUGIN='&& ${INSTALL} -m 755 $$i ${DESTDIR}${plugindir}/$$i'
- UNINSTALL_PLUGIN='&& rm -f ${DESTDIR}${plugindir}/$$i'
+ INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.${LIB_PATCH} && ${LN_S} -f $$i.${LIB_MAJOR}.${LIB_MINOR}.${LIB_PATCH} ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} && ${LN_S} -f $$i.${LIB_MAJOR}.${LIB_MINOR}.${LIB_PATCH} ${DESTDIR}${libdir}/$$i'
+ UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.${LIB_PATCH}'
CLEAN_LIB=''
;;
hppa*-*-hpux*)
AC_MSG_RESULT([HP-UX (PA-RISC)])
LIB_CFLAGS='-fPIC -DPIC'
@@ -286,18 +263,12 @@
LIB_SUFFIX='.${LIB_MAJOR}'
LINK_LIB='&& rm -f $${out%%.*}.sl && ${LN_S} $$out $${out%%.*}.sl'
AS_IF([test x"$enable_rpath" != x"no"], [
LDFLAGS_RPATH='-Wl,+b,${libdir}'
])
- PLUGIN_CFLAGS='-fPIC -DPIC'
- PLUGIN_LDFLAGS='-shared'
- PLUGIN_SUFFIX='.sl'
- LINK_PLUGIN='${LD} -o $$out ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS}'
INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i && ${LN_S} -f $$i ${DESTDIR}${libdir}/$${i%%.*}.sl'
UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$${i%%.*}.sl'
- INSTALL_PLUGIN='&& ${INSTALL} -m 755 $$i ${DESTDIR}${plugindir}/$$i'
- UNINSTALL_PLUGIN='&& rm -f ${DESTDIR}${plugindir}/$$i'
CLEAN_LIB=''
;;
ia64*-*-hpux*)
AC_MSG_RESULT([HP-UX (Itanium)])
LIB_CFLAGS='-fPIC -DPIC'
@@ -307,18 +278,12 @@
LIB_SUFFIX='.${LIB_MAJOR}'
LINK_LIB='&& rm -f $${out%%.*}.so && ${LN_S} $$out $${out%%.*}.so'
AS_IF([test x"$enable_rpath" != x"no"], [
LDFLAGS_RPATH='-Wl,+b,${libdir}'
])
- PLUGIN_CFLAGS='-fPIC -DPIC'
- PLUGIN_LDFLAGS='-shared'
- PLUGIN_SUFFIX='.so'
- LINK_PLUGIN='${LD} -o $$out ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS}'
INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i && ${LN_S} -f $$i ${DESTDIR}${libdir}/$${i%%.*}.so'
UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$${i%%.*}.so'
- INSTALL_PLUGIN='&& ${INSTALL} -m 755 $$i ${DESTDIR}${plugindir}/$$i'
- UNINSTALL_PLUGIN='&& rm -f ${DESTDIR}${plugindir}/$$i'
CLEAN_LIB=''
;;
*)
AC_MSG_RESULT(ELF)
LIB_CFLAGS='-fPIC -DPIC'
@@ -327,18 +292,12 @@
LIB_PREFIX='lib'
LIB_SUFFIX='.so'
AS_IF([test x"$enable_rpath" != x"no"], [
LDFLAGS_RPATH='-Wl,-rpath,${libdir}'
])
- PLUGIN_CFLAGS='-fPIC -DPIC'
- PLUGIN_LDFLAGS='-shared'
- PLUGIN_SUFFIX='.so'
- LINK_PLUGIN='${LD} -o $$out ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS}'
- INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.0 && ${LN_S} -f $$i.${LIB_MAJOR}.${LIB_MINOR}.0 ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} && ${LN_S} -f $$i.${LIB_MAJOR}.${LIB_MINOR}.0 ${DESTDIR}${libdir}/$$i'
- UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.0'
- INSTALL_PLUGIN='&& ${INSTALL} -m 755 $$i ${DESTDIR}${plugindir}/$$i'
- UNINSTALL_PLUGIN='&& rm -f ${DESTDIR}${plugindir}/$$i'
+ INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.${LIB_PATCH} && ${LN_S} -f $$i.${LIB_MAJOR}.${LIB_MINOR}.${LIB_PATCH} ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} && ${LN_S} -f $$i.${LIB_MAJOR}.${LIB_MINOR}.${LIB_PATCH} ${DESTDIR}${libdir}/$$i'
+ UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.${LIB_PATCH}'
CLEAN_LIB=''
;;
esac
AC_SUBST(LIB_CFLAGS)
@@ -346,35 +305,26 @@
AC_SUBST(LIB_LDFLAGS_INSTALL_NAME)
AC_SUBST(LIB_PREFIX)
AC_SUBST(LIB_SUFFIX)
AC_SUBST(LINK_LIB)
AC_SUBST(LDFLAGS_RPATH)
- AC_SUBST(PLUGIN_CFLAGS)
- AC_SUBST(PLUGIN_LDFLAGS)
- AC_SUBST(PLUGIN_SUFFIX)
- AC_SUBST(LINK_PLUGIN)
AC_SUBST(INSTALL_LIB)
AC_SUBST(UNINSTALL_LIB)
- AC_SUBST(INSTALL_PLUGIN)
- AC_SUBST(UNINSTALL_PLUGIN)
AC_SUBST(CLEAN_LIB)
])
AC_DEFUN([BUILDSYS_FRAMEWORK], [
AC_REQUIRE([AC_CANONICAL_HOST])
AC_REQUIRE([BUILDSYS_CHECK_IOS])
AC_REQUIRE([BUILDSYS_SHARED_LIB])
- AC_CHECK_TOOL(CODESIGN, codesign)
-
case "$host_os" in
darwin*)
+ FRAMEWORK_LDFLAGS='-dynamiclib -current_version ${LIB_MAJOR}.${LIB_MINOR} -compatibility_version ${LIB_MAJOR}'
AS_IF([test x"$host_is_ios" = x"yes"], [
- FRAMEWORK_LDFLAGS='-dynamiclib -current_version ${LIB_MAJOR}.${LIB_MINOR} -compatibility_version ${LIB_MAJOR}'
FRAMEWORK_LDFLAGS_INSTALL_NAME='-Wl,-install_name,@executable_path/Frameworks/$$out/$${out%.framework}'
], [
- FRAMEWORK_LDFLAGS='-dynamiclib -current_version ${LIB_MAJOR}.${LIB_MINOR} -compatibility_version ${LIB_MAJOR}'
FRAMEWORK_LDFLAGS_INSTALL_NAME='-Wl,-install_name,@executable_path/../Frameworks/$$out/$${out%.framework}'
])
AC_SUBST(FRAMEWORK_LDFLAGS)
AC_SUBST(FRAMEWORK_LDFLAGS_INSTALL_NAME)
@@ -382,5 +332,61 @@
$1
;;
esac
])
+
+AC_DEFUN([BUILDSYS_PLUGIN], [
+ AC_REQUIRE([AC_CANONICAL_HOST])
+ AC_REQUIRE([BUILDSYS_CHECK_IOS])
+ AC_MSG_CHECKING(for plugin type)
+
+ case "$host" in
+ *-*-darwin*)
+ AC_MSG_RESULT(Darwin)
+ PLUGIN_CFLAGS='-fPIC -DPIC'
+ PLUGIN_LDFLAGS='-bundle ${PLUGIN_LDFLAGS_BUNDLE_LOADER}'
+ PLUGIN_SUFFIX='.bundle'
+ AS_IF([test x"$host_is_ios" = x"yes"], [
+ LINK_PLUGIN='rm -fr $$out && ${MKDIR_P} $$out && if test -f Info.plist; then ${INSTALL} -m 644 Info.plist $$out/Info.plist; fi && ${LD} -o $$out/$${out%${PLUGIN_SUFFIX}} ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS} && ${CODESIGN} -fs ${CODESIGN_IDENTITY} $$out'
+ ], [
+ LINK_PLUGIN='rm -fr $$out && ${MKDIR_P} $$out/Contents/MacOS && if test -f Info.plist; then ${INSTALL} -m 644 Info.plist $$out/Contents/Info.plist; fi && ${LD} -o $$out/Contents/MacOS/$${out%${PLUGIN_SUFFIX}} ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS} && ${CODESIGN} -fs ${CODESIGN_IDENTITY} $$out'
+ ])
+ INSTALL_PLUGIN='&& rm -fr ${DESTDIR}${plugindir}/$$i && cp -R $$i ${DESTDIR}${plugindir}/'
+ UNINSTALL_PLUGIN='&& rm -fr ${DESTDIR}${plugindir}/$$i'
+ ;;
+ *-*-mingw* | *-*-cygwin*)
+ AC_MSG_RESULT(MinGW / Cygwin)
+ PLUGIN_CFLAGS=''
+ PLUGIN_LDFLAGS='-shared -Wl,--export-all-symbols'
+ PLUGIN_SUFFIX='.dll'
+ LINK_PLUGIN='${LD} -o $$out ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS}'
+ INSTALL_PLUGIN='&& ${INSTALL} -m 755 $$i ${DESTDIR}${plugindir}/$$i'
+ UNINSTALL_PLUGIN='&& rm -f ${DESTDIR}${plugindir}/$$i'
+ ;;
+ hppa*-*-hpux*)
+ AC_MSG_RESULT([HP-UX (PA-RISC)])
+ PLUGIN_CFLAGS='-fPIC -DPIC'
+ PLUGIN_LDFLAGS='-shared'
+ PLUGIN_SUFFIX='.sl'
+ LINK_PLUGIN='${LD} -o $$out ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS}'
+ INSTALL_PLUGIN='&& ${INSTALL} -m 755 $$i ${DESTDIR}${plugindir}/$$i'
+ UNINSTALL_PLUGIN='&& rm -f ${DESTDIR}${plugindir}/$$i'
+ ;;
+ *)
+ AC_MSG_RESULT(ELF)
+ PLUGIN_CFLAGS='-fPIC -DPIC'
+ PLUGIN_LDFLAGS='-shared'
+ PLUGIN_SUFFIX='.so'
+ LINK_PLUGIN='${LD} -o $$out ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS}'
+ INSTALL_PLUGIN='&& ${INSTALL} -m 755 $$i ${DESTDIR}${plugindir}/$$i'
+ UNINSTALL_PLUGIN='&& rm -f ${DESTDIR}${plugindir}/$$i'
+ ;;
+ esac
+
+ AC_SUBST(PLUGIN_CFLAGS)
+ AC_SUBST(PLUGIN_LDFLAGS)
+ AC_SUBST(PLUGIN_SUFFIX)
+ AC_SUBST(LINK_PLUGIN)
+ AC_SUBST(INSTALL_PLUGIN)
+ AC_SUBST(UNINSTALL_PLUGIN)
+])
Index: buildsys.mk.in
==================================================================
--- buildsys.mk.in
+++ buildsys.mk.in
@@ -1,8 +1,8 @@
#
# Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016,
-# 2017, 2018, 2020, 2021
+# 2017, 2018, 2020, 2021, 2022, 2023
# Jonathan Schleifer
#
# https://fossil.nil.im/buildsys
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -121,32 +121,44 @@
${AMIGA_LIB_OBJS:.o=.dep} \
${PLUGIN_OBJS:.o=.dep}
MO_FILES = ${LOCALES:.po=.mo}
-.SILENT:
+@SILENT@
.SUFFIXES:
-.SUFFIXES: .amigalib.o .beam .c .cc .class .cxx .d .erl .lib.o .java .mo .m .mm .o .plugin.o .po .py .pyc .rc .S .xpm
-.PHONY: all subdirs subdirs-after pre-depend depend install install-extra uninstall uninstall-extra clean distclean locales copy-headers-into-framework ${SUBDIRS} ${SUBDIRS_AFTER}
+.SUFFIXES: .amigalib.o .beam .c .cc .class .cxx .d .erl .lib.o .java \
+ .mo .m .mm .o .plugin.o .po .py .pyc .rc .S .xpm
+.PHONY: all subdirs subdirs-after pre-depend depend install \
+ install-extra uninstall uninstall-extra clean distclean locales \
+ copy-headers-into-framework ${SUBDIRS} ${SUBDIRS_AFTER}
all:
- ${MAKE} -s pre-all
- ${MAKE} -s subdirs
- ${MAKE} -s depend
- ${MAKE} -s ${STATIC_LIB} ${STATIC_LIB_NOINST} ${STATIC_PIC_LIB} ${STATIC_PIC_LIB_NOINST} ${STATIC_AMIGA_LIB} ${STATIC_AMIGA_LIB_NOINST} ${SHARED_LIB} ${SHARED_LIB_NOINST} ${FRAMEWORK} ${FRAMEWORK_NOINST} ${AMIGA_LIB} ${AMIGA_LIB_NOINST} ${PLUGIN} ${PLUGIN_NOINST} ${PROG} ${PROG_NOINST} ${JARFILE} locales
- ${MAKE} -s subdirs-after
- ${MAKE} -s post-all
+ ${MAKE} @MAKEFLAGS_SILENT@ pre-all
+ ${MAKE} @MAKEFLAGS_SILENT@ subdirs
+ ${MAKE} @MAKEFLAGS_SILENT@ depend
+ ${MAKE} @MAKEFLAGS_SILENT@ \
+ ${STATIC_LIB} ${STATIC_LIB_NOINST} \
+ ${STATIC_PIC_LIB} ${STATIC_PIC_LIB_NOINST} \
+ ${STATIC_AMIGA_LIB}${STATIC_AMIGA_LIB_NOINST} \
+ ${SHARED_LIB} ${SHARED_LIB_NOINST} \
+ ${FRAMEWORK} ${FRAMEWORK_NOINST} \
+ ${AMIGA_LIB} ${AMIGA_LIB_NOINST} \
+ ${PLUGIN} ${PLUGIN_NOINST} \
+ ${PROG} ${PROG_NOINST} \
+ ${JARFILE} locales
+ ${MAKE} @MAKEFLAGS_SILENT@ subdirs-after
+ ${MAKE} @MAKEFLAGS_SILENT@ post-all
pre-all post-all:
subdirs: ${SUBDIRS}
subdirs-after: ${SUBDIRS_AFTER}
${SUBDIRS} ${SUBDIRS_AFTER}:
for i in $@; do \
${DIR_ENTER}; \
- ${MAKE} -s || exit $$?; \
+ ${MAKE} @MAKEFLAGS_SILENT@ || exit $$?; \
${DIR_LEAVE}; \
done
depend: pre-depend
: >.deps
@@ -167,11 +179,12 @@
fi
${JARFILE}: ${EXT_DEPS} ${JAR_MANIFEST} ${OBJS} ${OBJS_EXTRA}
${LINK_STATUS}
if test x"${JAR_MANIFEST}" != x""; then \
- if ${JAR} cfm ${JARFILE} ${JAR_MANIFEST} ${OBJS} ${OBJS_EXTRA}; then \
+ if ${JAR} cfm ${JARFILE} ${JAR_MANIFEST} ${OBJS} \
+ ${OBJS_EXTRA}; then \
${LINK_OK}; \
else \
${LINK_FAILED}; \
fi \
else \
@@ -183,45 +196,106 @@
fi
${SHARED_LIB} ${SHARED_LIB_NOINST}: ${EXT_DEPS} ${LIB_OBJS} ${LIB_OBJS_EXTRA}
${LINK_STATUS}
out="$@"; \
- if ${LD} -o $@ ${LIB_OBJS} ${LIB_OBJS_EXTRA} ${LIB_LDFLAGS} ${LIB_LDFLAGS_INSTALL_NAME} ${LDFLAGS} ${LIBS} ${LINK_LIB}; then \
+ if ${LD} -o $@ ${LIB_OBJS} ${LIB_OBJS_EXTRA} ${LIB_LDFLAGS} \
+ ${LIB_LDFLAGS_INSTALL_NAME} ${LDFLAGS} ${LIBS} ${LINK_LIB}; then \
${LINK_OK}; \
else \
${LINK_FAILED}; \
fi
${FRAMEWORK} ${FRAMEWORK_NOINST}: ${EXT_DEPS} ${LIB_OBJS} ${LIB_OBJS_EXTRA}
${LINK_STATUS}
out="$@"; \
- if rm -fr $$out && ${MKDIR_P} $$out && ${MAKE} -s COPY_HEADERS_IF_SUBDIR=${includesubdir} COPY_HEADERS_DESTINATION=$$PWD/$@/Headers copy-headers-into-framework && if test -f Info.plist; then ${INSTALL} -m 644 Info.plist $$out/Info.plist; fi && if test -f module.modulemap; then ${MKDIR_P} $$out/Modules && ${INSTALL} -m 644 module.modulemap $$out/Modules/module.modulemap; fi && ${LD} -o $$out/$${out%.framework} ${LIB_OBJS} ${LIB_OBJS_EXTRA} ${FRAMEWORK_LDFLAGS} ${FRAMEWORK_LDFLAGS_INSTALL_NAME} ${LDFLAGS} ${FRAMEWORK_LIBS} && ${CODESIGN} -fs ${CODESIGN_IDENTITY} $$out; then \
- ${LINK_OK}; \
+ if test x"@HOST_IS_IOS@" = x"yes"; then \
+ if rm -fr $@ && \
+ ${MAKE} @MAKEFLAGS_SILENT@ \
+ COPY_HEADERS_IF_SUBDIR=${includesubdir} \
+ COPY_HEADERS_DESTINATION=$$PWD/$@/Headers \
+ copy-headers-into-framework && \
+ if test -f Info.plist; then \
+ ${INSTALL} -m 644 Info.plist $@/Info.plist; \
+ fi && \
+ if test -f module.modulemap; then \
+ ${MKDIR_P} $@/Modules && \
+ ${INSTALL} -m 644 module.modulemap \
+ $@/Modules/module.modulemap; \
+ fi && \
+ ${LD} -o $@/$${out%.framework} \
+ ${LIB_OBJS} ${LIB_OBJS_EXTRA} ${FRAMEWORK_LDFLAGS} \
+ ${FRAMEWORK_LDFLAGS_INSTALL_NAME} ${LDFLAGS} \
+ ${FRAMEWORK_LIBS} && \
+ ${CODESIGN} -fs ${CODESIGN_IDENTITY} $@; then \
+ ${LINK_OK}; \
+ else \
+ rm -fr $$out; false; \
+ ${LINK_FAILED}; \
+ fi; \
else \
- rm -fr $$out; false; \
- ${LINK_FAILED}; \
+ versiondir="$@/Versions/${LIB_MAJOR}"; \
+ if rm -fr $@ && \
+ ${MKDIR_P} $$versiondir && \
+ ${LN_S} ${LIB_MAJOR} $@/Versions/Current && \
+ ${MAKE} @MAKEFLAGS_SILENT@ \
+ COPY_HEADERS_IF_SUBDIR=${includesubdir} \
+ COPY_HEADERS_DESTINATION=$$PWD/$$versiondir/Headers \
+ copy-headers-into-framework && \
+ ${LN_S} Versions/Current/Headers $@/Headers && \
+ if test -f Info.plist; then \
+ ${MKDIR_P} $$versiondir/Resources && \
+ ${INSTALL} -m 644 Info.plist \
+ $$versiondir/Resources/Info.plist && \
+ ${LN_S} Versions/Current/Resources $@/Resources; \
+ fi && \
+ if test -f module.modulemap; then \
+ ${MKDIR_P} $$versiondir/Modules && \
+ ${INSTALL} -m 644 module.modulemap \
+ $$versiondir/Modules/module.modulemap && \
+ ${LN_S} Versions/Current/Modules $@/Modules; \
+ fi && \
+ ${LD} -o $$versiondir/$${out%.framework} \
+ ${LIB_OBJS} ${LIB_OBJS_EXTRA} ${FRAMEWORK_LDFLAGS} \
+ ${FRAMEWORK_LDFLAGS_INSTALL_NAME} ${LDFLAGS} \
+ ${FRAMEWORK_LIBS} && \
+ ${LN_S} Versions/Current/$${out%.framework} \
+ $@/$${out%.framework} && \
+ ${CODESIGN} -fs ${CODESIGN_IDENTITY} $@; then \
+ ${LINK_OK}; \
+ else \
+ rm -fr $$out; false; \
+ ${LINK_FAILED}; \
+ fi; \
fi
copy-headers-into-framework:
for i in "" ${SUBDIRS} ${SUBDIRS_AFTER}; do \
test x"$$i" = x"" && continue; \
cd $$i || exit 1; \
- ${MAKE} -s copy-headers-into-framework || exit $$?; \
+ ${MAKE} @MAKEFLAGS_SILENT@ copy-headers-into-framework || \
+ exit $$?; \
cd .. || exit 1; \
done
if test x"${includesubdir}" = x"${COPY_HEADERS_IF_SUBDIR}"; then \
for i in "" ${INCLUDES}; do \
test x"$$i" = x"" && continue; \
- ${MKDIR_P} $$(dirname ${COPY_HEADERS_DESTINATION}/$$i) || exit $$?; \
- ${INSTALL} -m 644 $$i ${COPY_HEADERS_DESTINATION}/$$i || exit $$?; \
+ ${MKDIR_P} \
+ $$(dirname ${COPY_HEADERS_DESTINATION}/$$i) || \
+ exit $$?; \
+ ${INSTALL} -m 644 $$i \
+ ${COPY_HEADERS_DESTINATION}/$$i || exit $$?; \
done \
fi
-${AMIGA_LIB} ${AMIGA_LIB_NOINST}: ${EXT_DEPS} ${AMIGA_LIB_OBJS_START} ${AMIGA_LIB_OBJS} ${AMIGA_LIB_OBJS_EXTRA}
+${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} ${AMIGA_LIB_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}; \
fi
@@ -280,15 +354,17 @@
dir=".$$(echo $$i | sed 's/\//_/g').objs"; \
rm -fr $$dir; \
done; \
fi
-${STATIC_PIC_LIB} ${STATIC_PIC_LIB_NOINST}: ${EXT_DEPS} ${LIB_OBJS} ${LIB_OBJS_EXTRA}
+${STATIC_PIC_LIB} ${STATIC_PIC_LIB_NOINST}: ${EXT_DEPS} ${LIB_OBJS} \
+ ${LIB_OBJS_EXTRA}
${LINK_STATUS}
rm -f $@
if test x"${BUILD_AND_HOST_ARE_DARWIN}" = x"yes"; then \
- if /usr/bin/libtool -static -o $@ ${LIB_OBJS} ${LIB_OBJS_EXTRA}; then \
+ if /usr/bin/libtool -static -o $@ ${LIB_OBJS} \
+ ${LIB_OBJS_EXTRA}; then \
${LINK_OK}; \
else \
rm -f $@; false; \
${LINK_FAILED}; \
fi; \
@@ -327,11 +403,12 @@
dir=".$$(echo $$i | sed 's/\//_/g').objs"; \
rm -fr $$dir; \
done; \
fi
-${STATIC_AMIGA_LIB} ${STATIC_AMIGA_LIB_NOINST}: ${EXT_DEPS} ${AMIGA_LIB_OBJS} ${AMIGA_LIB_OBJS_EXTRA}
+${STATIC_AMIGA_LIB} ${STATIC_AMIGA_LIB_NOINST}: ${EXT_DEPS} ${AMIGA_LIB_OBJS} \
+ ${AMIGA_LIB_OBJS_EXTRA}
${LINK_STATUS}
rm -f $@
out="$@"; \
objs=""; \
ars=""; \
@@ -371,75 +448,83 @@
.c.o:
${COMPILE_STATUS}
in="$<"; \
out="$@"; \
- if ${CC} ${CFLAGS} ${CPPFLAGS} ${CFLAGS_$<} ${CFLAGS_$@} ${DEP_CFLAGS} -c -o $@ $<; then \
+ if ${CC} ${CFLAGS} ${CPPFLAGS} ${CFLAGS_$<} ${CFLAGS_$@} ${DEP_CFLAGS} \
+ -c -o $@ $<; then \
${COMPILE_OK}; \
else \
${COMPILE_FAILED}; \
fi
.c.lib.o:
${COMPILE_LIB_STATUS}
in="$<"; \
out="$@"; \
- if ${CC} ${LIB_CFLAGS} ${CFLAGS} ${CPPFLAGS} ${CFLAGS_$<} ${CFLAGS_$@} ${DEP_CFLAGS} -c -o $@ $<; then \
+ if ${CC} ${LIB_CFLAGS} ${CFLAGS} ${CPPFLAGS} ${CFLAGS_$<} ${CFLAGS_$@} \
+ ${DEP_CFLAGS} -c -o $@ $<; then \
${COMPILE_LIB_OK}; \
else \
${COMPILE_LIB_FAILED}; \
fi
.c.amigalib.o:
${COMPILE_AMIGA_LIB_STATUS}
in="$<"; \
out="$@"; \
- if ${CC} ${AMIGA_LIB_CFLAGS} ${CFLAGS} ${CPPFLAGS} ${CFLAGS_$<} ${CFLAGS_$@} ${DEP_CFLAGS} -c -o $@ $<; then \
+ if ${CC} ${AMIGA_LIB_CFLAGS} ${CFLAGS} ${CPPFLAGS} ${CFLAGS_$<} \
+ ${CFLAGS_$@} ${DEP_CFLAGS} -c -o $@ $<; then \
${COMPILE_AMIGA_LIB_OK}; \
else \
${COMPILE_AMIGA_LIB_FAILED}; \
fi
.c.plugin.o:
${COMPILE_PLUGIN_STATUS}
in="$<"; \
out="$@"; \
- if ${CC} ${PLUGIN_CFLAGS} ${CFLAGS} ${CPPFLAGS} ${CFLAGS_$<} ${CFLAGS_$@} ${DEP_CFLAGS} -c -o $@ $<; then \
+ if ${CC} ${PLUGIN_CFLAGS} ${CFLAGS} ${CPPFLAGS} ${CFLAGS_$<} \
+ ${CFLAGS_$@} ${DEP_CFLAGS} -c -o $@ $<; then \
${COMPILE_PLUGIN_OK}; \
else \
${COMPILE_PLUGIN_FAILED}; \
fi
.cc.o .cxx.o:
${COMPILE_STATUS}
in="$<"; \
out="$@"; \
- if ${CXX} ${CXXFLAGS} ${CPPFLAGS} ${CXXFLAGS_$<} ${CXXFLAGS_$@} ${DEP_CXXFLAGS} -c -o $@ $<; then \
+ if ${CXX} ${CXXFLAGS} ${CPPFLAGS} ${CXXFLAGS_$<} ${CXXFLAGS_$@} \
+ ${DEP_CXXFLAGS} -c -o $@ $<; then \
${COMPILE_OK}; \
else \
${COMPILE_FAILED}; \
fi
.cc.lib.o .cxx.lib.o:
${COMPILE_LIB_STATUS}
in="$<"; \
out="$@"; \
- if ${CXX} ${LIB_CFLAGS} ${CXXFLAGS} ${CPPFLAGS} ${CXXFLAGS_$<} ${CXXFLAGS_$@} ${DEP_CXXFLAGS} -c -o $@ $<; then \
+ if ${CXX} ${LIB_CFLAGS} ${CXXFLAGS} ${CPPFLAGS} ${CXXFLAGS_$<} \
+ ${CXXFLAGS_$@} ${DEP_CXXFLAGS} -c -o $@ $<; then \
${COMPILE_LIB_OK}; \
else \
${COMPILE_LIB_FAILED}; \
fi
.cc.amigalib.o .cxx.amigalib.o:
${COMPILE_AMIGA_LIB_STATUS}
in="$<"; \
out="$@"; \
- if ${CXX} ${AMIGA_LIB_CFLAGS} ${CXXFLAGS} ${CPPFLAGS} ${CXXFLAGS_$<} ${CXXFLAGS_$@} ${DEP_CXXFLAGS} -c -o $@ $<; then \
+ if ${CXX} ${AMIGA_LIB_CFLAGS} ${CXXFLAGS} ${CPPFLAGS} ${CXXFLAGS_$<} \
+ ${CXXFLAGS_$@} ${DEP_CXXFLAGS} -c -o $@ $<; then \
${COMPILE_AMIGA_LIB_OK}; \
else \
${COMPILE_AMIGA_LIB_FAILED}; \
fi
.cc.plugin.o .cxx.plugin.o:
${COMPILE_PLUGIN_STATUS}
in="$<"; \
out="$@"; \
- if ${CXX} ${PLUGIN_CFLAGS} ${CXXFLAGS} ${CPPFLAGS} ${CXXFLAGS_$<} ${CXXFLAGS_$@} ${DEP_CXXFLAGS} -c -o $@ $<; then \
+ if ${CXX} ${PLUGIN_CFLAGS} ${CXXFLAGS} ${CPPFLAGS} ${CXXFLAGS_$<} \
+ ${CXXFLAGS_$@} ${DEP_CXXFLAGS} -c -o $@ $<; then \
${COMPILE_PLUGIN_OK}; \
else \
${COMPILE_PLUGIN_FAILED}; \
fi
@@ -483,75 +568,86 @@
.m.o:
${COMPILE_STATUS}
in="$<"; \
out="$@"; \
- if ${OBJC} ${OBJCFLAGS} ${CPPFLAGS} ${OBJCFLAGS_$<} ${OBJCFLAGS_$@} ${DEP_OBJCFLAGS} -c -o $@ $<; then \
+ if ${OBJC} ${OBJCFLAGS} ${CPPFLAGS} ${OBJCFLAGS_$<} ${OBJCFLAGS_$@} \
+ ${DEP_OBJCFLAGS} -c -o $@ $<; then \
${COMPILE_OK}; \
else \
${COMPILE_FAILED}; \
fi
.m.lib.o:
${COMPILE_LIB_STATUS}
in="$<"; \
out="$@"; \
- if ${OBJC} ${LIB_CFLAGS} ${OBJCFLAGS} ${CPPFLAGS} ${OBJCFLAGS_$<} ${OBJCFLAGS_$@} ${DEP_OBJCFLAGS} -c -o $@ $<; then \
+ if ${OBJC} ${LIB_CFLAGS} ${OBJCFLAGS} ${CPPFLAGS} ${OBJCFLAGS_$<} \
+ ${OBJCFLAGS_$@} ${DEP_OBJCFLAGS} -c -o $@ $<; then \
${COMPILE_LIB_OK}; \
else \
${COMPILE_LIB_FAILED}; \
fi
.m.amigalib.o:
${COMPILE_AMIGA_LIB_STATUS}
in="$<"; \
out="$@"; \
- if ${OBJC} ${AMIGA_LIB_CFLAGS} ${OBJCFLAGS} ${CPPFLAGS} ${OBJCFLAGS_$<} ${OBJCFLAGS_$@} ${DEP_OBJCFLAGS} -c -o $@ $<; then \
+ if ${OBJC} ${AMIGA_LIB_CFLAGS} ${OBJCFLAGS} ${CPPFLAGS} \
+ ${OBJCFLAGS_$<} ${OBJCFLAGS_$@} ${DEP_OBJCFLAGS} -c -o $@ $<; then \
${COMPILE_AMIGA_LIB_OK}; \
else \
${COMPILE_AMIGA_LIB_FAILED}; \
fi
.m.plugin.o:
${COMPILE_PLUGIN_STATUS}
in="$<"; \
out="$@"; \
- if ${OBJC} ${PLUGIN_CFLAGS} ${OBJCFLAGS} ${CPPFLAGS} ${OBJCFLAGS_$<} ${OBJCFLAGS_$@} ${DEP_OBJCFLAGS} -c -o $@ $<; then \
+ if ${OBJC} ${PLUGIN_CFLAGS} ${OBJCFLAGS} ${CPPFLAGS} ${OBJCFLAGS_$<} \
+ ${OBJCFLAGS_$@} ${DEP_OBJCFLAGS} -c -o $@ $<; then \
${COMPILE_PLUGIN_OK}; \
else \
${COMPILE_PLUGIN_FAILED}; \
fi
.mm.o:
${COMPILE_STATUS}
in="$<"; \
out="$@"; \
- if ${OBJCXX} ${OBJCXXFLAGS} ${CPPFLAGS} ${OBJCXXFLAGS_$<} ${OBJCXXFLAGS_$@} ${DEP_OBJCXXFLAGS} -c -o $@ $<; then \
+ if ${OBJCXX} ${OBJCXXFLAGS} ${CPPFLAGS} ${OBJCXXFLAGS_$<} \
+ ${OBJCXXFLAGS_$@} ${DEP_OBJCXXFLAGS} -c -o $@ $<; then \
${COMPILE_OK}; \
else \
${COMPILE_FAILED}; \
fi
.mm.lib.o:
${COMPILE_LIB_STATUS}
in="$<"; \
out="$@"; \
- if ${OBJCXX} ${LIB_CFLAGS} ${OBJCXXFLAGS} ${CPPFLAGS} ${OBJCXXFLAGS_$<} ${OBJCXXFLAGS_$@} ${DEP_OBJCXXFLAGS} -c -o $@ $<; then \
+ if ${OBJCXX} ${LIB_CFLAGS} ${OBJCXXFLAGS} ${CPPFLAGS} \
+ ${OBJCXXFLAGS_$<} ${OBJCXXFLAGS_$@} ${DEP_OBJCXXFLAGS} -c -o $@ \
+ $<; then \
${COMPILE_LIB_OK}; \
else \
${COMPILE_LIB_FAILED}; \
fi
.mm.amigalib.o:
${COMPILE_AMIGA_LIB_STATUS}
in="$<"; \
out="$@"; \
- if ${OBJCXX} ${AMIGA_LIB_CFLAGS} ${OBJCXXFLAGS} ${CPPFLAGS} ${OBJCXXFLAGS_$<} ${OBJCXXFLAGS_$@} ${DEP_OBJCXXFLAGS} -c -o $@ $<; then \
+ if ${OBJCXX} ${AMIGA_LIB_CFLAGS} ${OBJCXXFLAGS} ${CPPFLAGS} \
+ ${OBJCXXFLAGS_$<} ${OBJCXXFLAGS_$@} ${DEP_OBJCXXFLAGS} -c -o $@ \
+ $<; then \
${COMPILE_AMIGA_LIB_OK}; \
else \
${COMPILE_AMIGA_LIB_FAILED}; \
fi
.mm.plugin.o:
${COMPILE_PLUGIN_STATUS}
in="$<"; \
out="$@"; \
- if ${OBJCXX} ${PLUGIN_CFLAGS} ${OBJCXXFLAGS} ${CPPFLAGS} ${OBJCXXFLAGS_$<} ${OBJCXXFLAGS_$@} ${DEP_OBJCXXFLAGS} -c -o $@ $<; then \
+ if ${OBJCXX} ${PLUGIN_CFLAGS} ${OBJCXXFLAGS} ${CPPFLAGS} \
+ ${OBJCXXFLAGS_$<} ${OBJCXXFLAGS_$@} ${DEP_OBJCXXFLAGS} -c -o $@ \
+ $<; then \
${COMPILE_PLUGIN_OK}; \
else \
${COMPILE_PLUGIN_FAILED}; \
fi
@@ -567,11 +663,12 @@
.py.pyc:
${COMPILE_STATUS}
in="$<"; \
out="$@"; \
- if ${PYTHON} ${PYTHON_FLAGS} -c "import py_compile; py_compile.compile('$<')"; then \
+ if ${PYTHON} ${PYTHON_FLAGS} -c \
+ "import py_compile; py_compile.compile('$<')"; then \
${COMPILE_OK}; \
else \
${COMPILE_FAILED}; \
fi
@@ -587,76 +684,83 @@
.S.o .S.amigalib.o:
${COMPILE_STATUS}
in="$<"; \
out="$@"; \
- if ${AS} ${ASFLAGS} ${CPPFLAGS} ${ASFLAGS_$<} ${ASFLAGS_$@} ${DEP_ASFLAGS} -c -o $@ $<; then \
+ if ${AS} ${ASFLAGS} ${CPPFLAGS} ${ASFLAGS_$<} ${ASFLAGS_$@} \
+ ${DEP_ASFLAGS} -c -o $@ $<; then \
${COMPILE_OK}; \
else \
${COMPILE_FAILED}; \
fi
.S.lib.o:
${COMPILE_LIB_STATUS}
in="$<"; \
out="$@"; \
- if ${AS} ${LIB_CFLAGS} ${ASFLAGS} ${CPPFLAGS} ${ASFLAGS_$<} ${ASFLAGS_$@} ${DEP_ASFLAGS} -c -o $@ $<; then \
+ if ${AS} ${LIB_CFLAGS} ${ASFLAGS} ${CPPFLAGS} ${ASFLAGS_$<} \
+ ${ASFLAGS_$@} ${DEP_ASFLAGS} -c -o $@ $<; then \
${COMPILE_LIB_OK}; \
else \
${COMPILE_LIB_FAILED}; \
fi
.S.plugin.o:
${COMPILE_PLUGIN_STATUS}
in="$<"; \
out="$@"; \
- if ${AS} ${PLUGIN_CFLAGS} ${ASFLAGS} ${CPPFLAGS} ${ASFLAGS_$<} ${ASFLAGS_$@} ${DEP_ASFLAGS} -c -o $@ $<; then \
+ if ${AS} ${PLUGIN_CFLAGS} ${ASFLAGS} ${CPPFLAGS} ${ASFLAGS_$<} \
+ ${ASFLAGS_$@} ${DEP_ASFLAGS} -c -o $@ $<; then \
${COMPILE_PLUGIN_OK}; \
else \
${COMPILE_PLUGIN_FAILED}; \
fi
.xpm.o:
${COMPILE_STATUS}
in="$<"; \
out="$@"; \
- if ${CC} ${CFLAGS} ${CPPFLAGS} ${CFLAGS_$<} ${CFLAGS_$@} -x c -c -o $@ $<; then \
+ if ${CC} ${CFLAGS} ${CPPFLAGS} ${CFLAGS_$<} ${CFLAGS_$@} -x c -c -o $@ \
+ $<; then \
${COMPILE_OK}; \
else \
${COMPILE_FAILED}; \
fi
.xpm.lib.o:
${COMPILE_LIB_STATUS}
in="$<"; \
out="$@"; \
- if ${CC} ${LIB_CFLAGS} ${CFLAGS} ${CPPFLAGS} ${CFLAGS_$<} ${CFLAGS_$@} -x c -c -o $@ $<; then \
+ if ${CC} ${LIB_CFLAGS} ${CFLAGS} ${CPPFLAGS} ${CFLAGS_$<} ${CFLAGS_$@} \
+ -x c -c -o $@ $<; then \
${COMPILE_LIB_OK}; \
else \
${COMPILE_LIB_FAILED}; \
fi
.xpm.amigalib.o:
${COMPILE_AMIGA_LIB_STATUS}
in="$<"; \
out="$@"; \
- if ${CC} ${AMIGA_LIB_CFLAGS} ${CFLAGS} ${CPPFLAGS} ${CFLAGS_$<} ${CFLAGS_$@} -x c -c -o $@ $<; then \
+ if ${CC} ${AMIGA_LIB_CFLAGS} ${CFLAGS} ${CPPFLAGS} ${CFLAGS_$<} \
+ ${CFLAGS_$@} -x c -c -o $@ $<; then \
${COMPILE_AMIGA_LIB_OK}; \
else \
${COMPILE_AMIGA_LIB_FAILED}; \
fi
.xpm.plugin.o:
${COMPILE_PLUGIN_STATUS}
in="$<"; \
out="$@"; \
- if ${CC} ${PLUGIN_CFLAGS} ${CFLAGS} ${CPPFLAGS} ${CFLAGS_$<} ${CFLAGS_$@} -x c -c -o $@ $<; then \
+ if ${CC} ${PLUGIN_CFLAGS} ${CFLAGS} ${CPPFLAGS} ${CFLAGS_$<} \
+ ${CFLAGS_$@} -x c -c -o $@ $<; then \
${COMPILE_PLUGIN_OK}; \
else \
${COMPILE_PLUGIN_FAILED}; \
fi
install: all install-extra
for i in "" ${SUBDIRS} ${SUBDIRS_AFTER}; do \
test x"$$i" = x"" && continue; \
${DIR_ENTER}; \
- ${MAKE} -s install || exit $$?; \
+ ${MAKE} @MAKEFLAGS_SILENT@ install || exit $$?; \
${DIR_LEAVE}; \
done
for i in "" ${SHARED_LIB}; do \
test x"$$i" = x"" && continue; \
@@ -670,31 +774,34 @@
for i in "" ${FRAMEWORK}; do \
test x"$$i" = x"" && continue; \
${INSTALL_STATUS}; \
rm -fr ${DESTDIR}${prefix}/Library/Frameworks/$$i; \
- if ${MKDIR_P} ${DESTDIR}${prefix}/Library/Frameworks && cp -R $$i ${DESTDIR}${prefix}/Library/Frameworks/; then \
+ if ${MKDIR_P} ${DESTDIR}${prefix}/Library/Frameworks && \
+ cp -R $$i ${DESTDIR}${prefix}/Library/Frameworks/; then \
${INSTALL_OK}; \
else \
${INSTALL_FAILED}; \
fi \
done
for i in "" ${AMIGA_LIB}; do \
test x"$$i" = x"" && continue; \
${INSTALL_STATUS}; \
- if ${MKDIR_P} ${DESTDIR}${amigalibdir} && ${INSTALL} -m 755 $$i ${DESTDIR}${amigalibdir}/$$i; then \
+ if ${MKDIR_P} ${DESTDIR}${amigalibdir} && \
+ ${INSTALL} -m 755 $$i ${DESTDIR}${amigalibdir}/$$i; then \
${INSTALL_OK}; \
else \
${INSTALL_FAILED}; \
fi \
done
for i in "" ${STATIC_LIB} ${STATIC_PIC_LIB} ${STATIC_AMIGA_LIB}; do \
test x"$$i" = x"" && continue; \
${INSTALL_STATUS}; \
- if ${MKDIR_P} ${DESTDIR}${libdir} && ${INSTALL} -m 644 $$i ${DESTDIR}${libdir}/$$i; then \
+ if ${MKDIR_P} ${DESTDIR}${libdir} && \
+ ${INSTALL} -m 644 $$i ${DESTDIR}${libdir}/$$i; then \
${INSTALL_OK}; \
else \
${INSTALL_FAILED}; \
fi \
done
@@ -710,21 +817,25 @@
done
for i in "" ${DATA}; do \
test x"$$i" = x"" && continue; \
${INSTALL_STATUS}; \
- if ${MKDIR_P} $$(dirname ${DESTDIR}${datadir}/${PACKAGE_NAME}/$$i) && ${INSTALL} -m 644 $$i ${DESTDIR}${datadir}/${PACKAGE_NAME}/$$i; then \
+ if ${MKDIR_P} $$(dirname \
+ ${DESTDIR}${datadir}/${PACKAGE_NAME}/$$i) && \
+ ${INSTALL} -m 644 $$i \
+ ${DESTDIR}${datadir}/${PACKAGE_NAME}/$$i; then \
${INSTALL_OK}; \
else \
${INSTALL_FAILED}; \
fi \
done
for i in "" ${PROG}; do \
test x"$$i" = x"" && continue; \
${INSTALL_STATUS}; \
- if ${MKDIR_P} ${DESTDIR}${bindir} && ${INSTALL} -m 755 $$i ${DESTDIR}${bindir}/$$i; then \
+ if ${MKDIR_P} ${DESTDIR}${bindir} && \
+ ${INSTALL} -m 755 $$i ${DESTDIR}${bindir}/$$i; then \
${INSTALL_OK}; \
else \
${INSTALL_FAILED}; \
fi \
done
@@ -731,11 +842,14 @@
if test x"${INSTALL_INCLUDES}" = x"yes"; then \
for i in "" ${INCLUDES}; do \
test x"$$i" = x"" && continue; \
${INSTALL_STATUS}; \
- if ${MKDIR_P} $$(dirname ${DESTDIR}${includedir}/${includesubdir}/$$i) && ${INSTALL} -m 644 $$i ${DESTDIR}${includedir}/${includesubdir}/$$i; then \
+ if ${MKDIR_P} $$(dirname \
+ ${DESTDIR}${includedir}/${includesubdir}/$$i) && \
+ ${INSTALL} -m 644 $$i \
+ ${DESTDIR}${includedir}/${includesubdir}/$$i; then \
${INSTALL_OK}; \
else \
${INSTALL_FAILED}; \
fi \
done \
@@ -742,40 +856,46 @@
fi
for i in "" ${MO_FILES}; do \
test x"$$i" = x"" && continue; \
${INSTALL_STATUS}; \
- if ${MKDIR_P} ${DESTDIR}${localedir}/$${i%.mo}/LC_MESSAGES && ${INSTALL} -m 644 $$i ${DESTDIR}${localedir}/$${i%.mo}/LC_MESSAGES/${localename}.mo; then \
+ dest="${localedir}/$${i%.mo}/LC_MESSAGES/${localename}.mo"; \
+ dest="${DESTDIR}$$dest"; \
+ if ${MKDIR_P} ${DESTDIR}${localedir}/$${i%.mo}/LC_MESSAGES && \
+ ${INSTALL} -m 644 $$i $$dest; then \
${INSTALL_OK}; \
else \
${INSTALL_FAILED}; \
fi \
done
for i in "" ${MAN}; do \
test x"$$i" = x"" && continue; \
${INSTALL_STATUS}; \
- if ${MKDIR_P} ${DESTDIR}${mandir}/${mansubdir} && ${INSTALL} -m 644 $$i ${DESTDIR}${mandir}/${mansubdir}/$$i; then \
+ dest="${DESTDIR}${mandir}/${mansubdir}/$$i"; \
+ if ${MKDIR_P} ${DESTDIR}${mandir}/${mansubdir} && \
+ ${INSTALL} -m 644 $$i $$dest; then \
${INSTALL_OK}; \
else \
${INSTALL_FAILED}; \
fi \
done
install-extra:
-uninstall: uninstall-extra
+uninstall:
for i in "" ${SUBDIRS} ${SUBDIRS_AFTER}; do \
test x"$$i" = x"" && continue; \
${DIR_ENTER}; \
- ${MAKE} -s uninstall || exit $$?; \
+ ${MAKE} @MAKEFLAGS_SILENT@ uninstall || exit $$?; \
${DIR_LEAVE}; \
done
for i in "" ${SHARED_LIB}; do \
test x"$$i" = x"" && continue; \
- if test -f ${DESTDIR}${libdir}/$$i -o -f ${DESTDIR}${bindir}/$$i; then \
+ if test -f ${DESTDIR}${libdir}/$$i \
+ -o -f ${DESTDIR}${bindir}/$$i; then \
if : @UNINSTALL_LIB@; then \
${DELETE_OK}; \
else \
${DELETE_FAILED}; \
fi \
@@ -783,11 +903,12 @@
done
for i in "" ${FRAMEWORK}; do \
test x"$$i" = x"" && continue; \
if test -d ${DESTDIR}${prefix}/Library/Frameworks/$$i; then \
- if rm -fr ${DESTDIR}${prefix}/Library/Frameworks/$$i; then \
+ if rm -fr ${DESTDIR}${prefix}/Library/Frameworks/$$i; \
+ then \
${DELETE_OK}; \
else \
${DELETE_FAILED}; \
fi \
fi \
@@ -819,17 +940,19 @@
rmdir ${DESTDIR}${plugindir} >/dev/null 2>&1 || true
for i in "" ${DATA}; do \
test x"$$i" = x"" && continue; \
if test -f ${DESTDIR}${datadir}/${PACKAGE_NAME}/$$i; then \
- if rm -f ${DESTDIR}${datadir}/${PACKAGE_NAME}/$$i; then \
+ if rm -f ${DESTDIR}${datadir}/${PACKAGE_NAME}/$$i; \
+ then \
${DELETE_OK}; \
else \
${DELETE_FAILED}; \
fi \
fi; \
- rmdir "$$(dirname ${DESTDIR}${datadir}/${PACKAGE_NAME}/$$i)" >/dev/null 2>&1 || true; \
+ rmdir "$$(dirname ${DESTDIR}${datadir}/${PACKAGE_NAME}/$$i)" \
+ >/dev/null 2>&1 || true; \
done
rmdir ${DESTDIR}${datadir}/${PACKAGE_NAME} >/dev/null 2>&1 || true
for i in "" ${PROG}; do \
test x"$$i" = x"" && continue; \
@@ -843,11 +966,12 @@
done
for i in "" ${INCLUDES}; do \
test x"$$i" = x"" && continue; \
if test -f ${DESTDIR}${includedir}/${includesubdir}/$$i; then \
- if rm -f ${DESTDIR}${includedir}/${includesubdir}/$$i; then \
+ if rm -f ${DESTDIR}${includedir}/${includesubdir}/$$i; \
+ then \
${DELETE_OK}; \
else \
${DELETE_FAILED}; \
fi \
fi \
@@ -854,12 +978,14 @@
done
rmdir ${DESTDIR}${includedir}/${includesubdir} >/dev/null 2>&1 || true
for i in "" ${MO_FILES}; do \
test x"$$i" = x"" && continue; \
- if test -f ${DESTDIR}${localedir}/$${i%.mo}/LC_MESSAGES/${localename}.mo; then \
- if rm -f ${DESTDIR}${localedir}/$${i%.mo}/LC_MESSAGES/${localename}.mo; then \
+ mo="${localedir}/$${i%.mo}/LC_MESSAGES/${localename}.mo"; \
+ mo="${DESTDIR}$$mo"; \
+ if test -f $$mo; then \
+ if rm -f $$mo; then \
${DELETE_OK}; \
else \
${DELETE_FAILED}; \
fi \
fi \
@@ -874,23 +1000,32 @@
${DELETE_FAILED}; \
fi \
fi \
done
+ ${MAKE} @MAKEFLAGS_SILENT@ uninstall-extra
+
uninstall-extra:
clean:
for i in "" ${SUBDIRS} ${SUBDIRS_AFTER}; do \
test x"$$i" = x"" && continue; \
${DIR_ENTER}; \
- ${MAKE} -s clean || exit $$?; \
+ ${MAKE} @MAKEFLAGS_SILENT@ clean || exit $$?; \
${DIR_LEAVE}; \
done
: >.deps
- for i in "" ${DEPS} ${OBJS} ${OBJS_EXTRA} ${LIB_OBJS} ${LIB_OBJS_EXTRA} ${AMIGA_LIB_OBJS} ${AMIGA_LIB_OBJS_START} ${AMIGA_LIB_OBJS_EXTRA} ${PLUGIN_OBJS} ${PROG} ${PROG_NOINST} ${SHARED_LIB} ${SHARED_LIB_NOINST} ${AMIGA_LIB} ${AMIGA_LIB_NOINST} ${STATIC_LIB} ${STATIC_LIB_NOINST} ${STATIC_PIC_LIB} ${STATIC_PIC_LIB_NOINST} ${STATIC_AMIGA_LIB} ${STATIC_AMIGA_LIB_NOINST} ${FRAMEWORK} ${PLUGIN} ${PLUGIN_NOINST} ${CLEAN_LIB} ${MO_FILES} ${CLEAN}; do \
+ for i in "" ${DEPS} ${OBJS} ${OBJS_EXTRA} ${LIB_OBJS} \
+ ${LIB_OBJS_EXTRA} ${AMIGA_LIB_OBJS} ${AMIGA_LIB_OBJS_START} \
+ ${AMIGA_LIB_OBJS_EXTRA} ${PLUGIN_OBJS} ${PROG} ${PROG_NOINST} \
+ ${SHARED_LIB} ${SHARED_LIB_NOINST} ${AMIGA_LIB} \
+ ${AMIGA_LIB_NOINST} ${STATIC_LIB} ${STATIC_LIB_NOINST} \
+ ${STATIC_PIC_LIB} ${STATIC_PIC_LIB_NOINST} ${STATIC_AMIGA_LIB} \
+ ${STATIC_AMIGA_LIB_NOINST} ${FRAMEWORK} ${PLUGIN} ${PLUGIN_NOINST} \
+ ${CLEAN_LIB} ${MO_FILES} ${CLEAN}; do \
test x"$$i" = x"" && continue; \
if test -f $$i -o -d $$i; then \
if rm -fr $$i; then \
${DELETE_OK}; \
else \
@@ -901,11 +1036,11 @@
distclean: clean
for i in "" ${SUBDIRS} ${SUBDIRS_AFTER}; do \
test x"$$i" = x"" && continue; \
${DIR_ENTER}; \
- ${MAKE} -s distclean || exit $$?; \
+ ${MAKE} @MAKEFLAGS_SILENT@ distclean || exit $$?; \
${DIR_LEAVE}; \
done
for i in "" ${DISTCLEAN} .deps *~; do \
test x"$$i" = x"" && continue; \
@@ -921,11 +1056,12 @@
print-hierarchy:
for i in "" ${SUBDIRS} ${SUBDIRS_AFTER}; do \
test x"$$i" = x"" && continue; \
echo ${PRINT_HIERARCHY_PREFIX}$$i; \
cd $$i || exit $$?; \
- ${MAKE} -s PRINT_HIERARCHY_PREFIX=$$i/ print-hierarchy || exit $$?; \
+ ${MAKE} @MAKEFLAGS_SILENT@ PRINT_HIERARCHY_PREFIX=$$i/ \
+ print-hierarchy || exit $$?; \
cd .. || exit $$?; \
done
print-var:
printf '%s\n' '${${VAR}}'
Index: configure.ac
==================================================================
--- configure.ac
+++ configure.ac
@@ -1,6 +1,6 @@
-AC_INIT(ObjFW, 1.1dev, js@nil.im)
+AC_INIT(ObjFW, 1.1dev, js@nil.im, objfw, https://objfw.nil.im/)
AC_CONFIG_SRCDIR(src)
AC_CONFIG_AUX_DIR(build-aux)
AC_CONFIG_MACRO_DIR(build-aux/m4)
AC_DEFINE(OBJFW_VERSION_MAJOR, 1, [The major version of ObjFW])
@@ -35,32 +35,20 @@
enable_threads="no"
enable_sockets="no"
enable_files="no"
;;
m68k-*-amigaos*)
- AS_IF([test x"$OBJCFLAGS" = x""], [OBJCFLAGS="-O0"])
+ AS_IF([test x"$OBJCFLAGS" = x""], [OBJCFLAGS="-O0 -g"])
OBJCFLAGS="$OBJCFLAGS -noixemul"
OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS -noixemul"
CPPFLAGS="$CPPFLAGS -D__NO_NET_API"
LDFLAGS="$LDFLAGS -noixemul"
LIBS="$LIBS -ldebug"
enable_files="yes" # Required for reading ENV:
enable_shared="no"
with_tls="no"
- supports_amiga_lib="yes"
-
- AS_IF([test x"$enable_amiga_lib" != x"no"], [
- AC_SUBST(OBJFWRT_AMIGA_LIB,
- ['objfwrt${OBJFWRT_LIB_MAJOR}.library'])
- dnl For 68000, GCC emits calls to helper functions that
- dnl do not work properly in a library.
- t="-mcpu=68020 -fbaserel -noixemul -ffreestanding"
- AC_SUBST(AMIGA_LIB_CFLAGS, $t)
- t="$t -resident -nostartfiles -nodefaultlibs -ldebug -lc"
- AC_SUBST(AMIGA_LIB_LDFLAGS, $t)
- ])
AC_SUBST(LIBBASES_M, libbases.m)
;;
powerpc-*-amigaos*)
CPPFLAGS="$CPPFLAGS -D__USE_INLINE__"
@@ -78,30 +66,20 @@
LDFLAGS="$LDFLAGS -noixemul"
LIBS="$LIBS -ldebug"
enable_files="yes" # Required for reading ENV:
enable_shared="no"
- supports_amiga_lib="yes"
-
- AS_IF([test x"$enable_amiga_lib" != x"no"], [
- AC_SUBST(OBJFWRT_AMIGA_LIB,
- ['objfwrt${OBJFW_LIB_MAJOR}ppc.library'])
- t="-mresident32 -ffreestanding -noixemul"
- AC_SUBST(AMIGA_LIB_CFLAGS, $t)
- t="-mresident32 -nostartfiles -nodefaultlibs -noixemul -ldebug"
- AC_SUBST(AMIGA_LIB_LDFLAGS, "$t -lc")
- ])
AC_SUBST(LIBBASES_M, libbases.m)
;;
*-msdosdjgpp*)
enable_shared="no"
enable_threads="no"
enable_sockets="no"
;;
*-*-mingw*)
- LDFLAGS="$LDFLAGS -Wl,--allow-multiple-definition -static-libgcc"
+ LDFLAGS="$LDFLAGS -Wl,--allow-multiple-definition"
LIBS="$LIBS -lversion"
AC_SUBST(USE_SRCS_WINDOWS, '${SRCS_WINDOWS}')
;;
*-psp-*)
@@ -142,10 +120,18 @@
*-*-mint*)
enable_shared="no"
enable_threads="no" # TODO
with_tls="no"
;;
+*-apple-macos*)
+ enable_shared="no"
+ enable_threads="no" # TODO
+ enable_sockets="no" # TODO
+
+ AC_DEFINE(OF_CLASSIC_MACOS, 1,
+ [Whether we are compiling for classic macOS])
+ ;;
esac
AS_IF([test x"$host_os" = x"msdosdjgpp" -a x"$build_os" = x"msdosdjgpp"], [
dnl Hack to make configure find these on DOS.
: ${AR:=ar.exe}
@@ -164,12 +150,12 @@
potential_compilers="clang egcc gcc"
;;
esac
AC_PROG_OBJC($potential_compilers)
AC_PROG_OBJCPP
-AC_PROG_LN_S
AC_PROG_EGREP
+AC_PROG_LN_S
BUILDSYS_CHECK_IOS
AC_ARG_WITH(wii,
AS_HELP_STRING([--with-wii], [build for Wii]))
@@ -346,10 +332,11 @@
AX_CHECK_COMPILER_FLAGS(-Xclang -fno-constant-cfstrings, [
flag="-Xclang -fno-constant-cfstrings"
OBJCFLAGS="$OBJCFLAGS $flag"
OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS $flag"
])
+
AX_CHECK_COMPILER_FLAGS([-Wsign-compare -Werror],
[OBJCFLAGS="$OBJCFLAGS -Wsign-compare"])
AS_IF([test x"$with_nds" != x"yes"], [
AX_CHECK_COMPILER_FLAGS([-Wshadow -Werror],
[OBJCFLAGS="$OBJCFLAGS -Wshadow"])
@@ -410,11 +397,13 @@
AC_ARG_ENABLE(shared,
AS_HELP_STRING([--disable-shared], [do not build shared library]))
AS_IF([test x"$enable_shared" != x"no"], [
BUILDSYS_SHARED_LIB
- AC_SUBST(OBJFW_SHARED_LIB, "${LIB_PREFIX}objfw${LIB_SUFFIX}")
+ BUILDSYS_PLUGIN
+
+ AC_SUBST(OBJFW_SHARED_LIB, '${LIB_PREFIX}objfw${LIB_SUFFIX}')
AC_SUBST(EXCEPTIONS_LIB_A, "exceptions.lib.a")
AC_SUBST(FORWARDING_LIB_A, "forwarding.lib.a")
AC_SUBST(LOOKUP_ASM_LIB_A, "lookup-asm.lib.a")
BUILDSYS_FRAMEWORK([
@@ -430,26 +419,16 @@
AS_IF([test x"$build_framework" = x"yes"], [
TESTS_LIBS="-framework ObjFW \${RUNTIME_FRAMEWORK_LIBS} $TESTS_LIBS"
TESTS_LIBS="-F../src -F../src/runtime $TESTS_LIBS"
], [
TESTS_LIBS="\${RUNTIME_LIBS} $TESTS_LIBS"
- TESTS_LIBS="-L../src/runtime -L../src/runtime/linklib $TESTS_LIBS"
+ TESTS_LIBS="-L../src/runtime $TESTS_LIBS"
TESTS_LIBS="-L../src -lobjfw $TESTS_LIBS"
])
-AC_ARG_ENABLE(amiga-lib,
- AS_HELP_STRING([--disable-amiga-lib], [do not build Amiga library]))
-AS_IF([test x"$supports_amiga_lib" != x"yes"], [enable_amiga_lib="no"])
-AS_IF([test x"$enable_amiga_lib" != x"no"], [
- AC_SUBST(OBJFW_STATIC_LIB, "libobjfw.a")
- AC_SUBST(EXCEPTIONS_A, "exceptions.a")
- AC_SUBST(FORWARDING_A, "forwarding.a")
- AC_SUBST(LOOKUP_ASM_AMIGALIB_A, "lookup-asm.amigalib.a")
-])
-
AC_ARG_ENABLE(static, AS_HELP_STRING([--enable-static], [build static library]))
-AS_IF([test x"$enable_shared" = x"no" -a x"$enable_amiga_lib" = x"no"], [
+AS_IF([test x"$enable_shared" = x"no"], [
enable_static="yes"
])
AS_IF([test x"$enable_static" = x"yes"], [
AC_SUBST(OBJFW_STATIC_LIB, "libobjfw.a")
AC_SUBST(EXCEPTIONS_A, "exceptions.a")
@@ -525,10 +504,11 @@
AC_MSG_RESULT($objc_runtime)
case "$objc_runtime" in
"ObjFW runtime")
AC_DEFINE(OF_OBJFW_RUNTIME, 1, [Whether we use the ObjFW runtime])
+ AC_SUBST(USE_SRCS_TAGGED_POINTERS, '${SRCS_TAGGED_POINTERS}')
AC_MSG_CHECKING([whether -fobjc-runtime=objfw is supported])
old_OBJCFLAGS="$OBJCFLAGS"
OBJCFLAGS="$OBJCFLAGS -Xclang -fobjc-runtime=objfw"
@@ -575,11 +555,11 @@
AC_SUBST(RUNTIME, "runtime")
AC_CONFIG_FILES(src/runtime/Info.plist)
AS_IF([test x"$enable_shared" != x"no"], [
AC_SUBST(OBJFWRT_SHARED_LIB,
- "${LIB_PREFIX}objfwrt${LIB_SUFFIX}")
+ '${LIB_PREFIX}objfwrt${LIB_SUFFIX}')
])
AS_IF([test x"$enable_static" = x"yes"], [
AC_SUBST(OBJFWRT_STATIC_LIB, "libobjfwrt.a")
])
@@ -587,22 +567,13 @@
AS_IF([test x"$build_framework" = x"yes"], [
AC_SUBST(OBJFWRT_FRAMEWORK, "ObjFWRT.framework")
AC_SUBST(RUNTIME_FRAMEWORK_LIBS, "-framework ObjFWRT")
])
- AS_IF([test x"$enable_amiga_lib" != x"no"], [
- AC_SUBST(RUNTIME_LIBS, "-lobjfwrt.library")
- AC_SUBST(LINKLIB, linklib)
- tmp="../src/runtime/linklib/libobjfwrt.library.a"
- AC_SUBST(LIBOBJFWRT_DEP, "$tmp")
- AC_SUBST(LIBOBJFWRT_DEP_LVL2, "../$tmp")
- ], [
- AC_SUBST(RUNTIME_LIBS, "-lobjfwrt")
- ])
-
- AS_IF([test x"$enable_shared" = x"no" \
- -a x"$enable_amiga_lib" = x"no"], [
+ AC_SUBST(RUNTIME_LIBS, "-lobjfwrt")
+
+ AS_IF([test x"$enable_shared" = x"no"], [
AC_SUBST(LIBOBJFWRT_DEP, "../src/runtime/libobjfwrt.a")
AC_SUBST(LIBOBJFWRT_DEP_LVL2, "../../src/runtime/libobjfwrt.a")
])
AS_IF([test x"$enable_seluid24" = x"yes"], [
@@ -1032,11 +1003,29 @@
AC_DEFINE(OF_HAVE_SCHED_YIELD, 1,
[Whether we have sched_yield()])
])
AC_CHECK_FUNCS(pthread_attr_getschedpolicy)
- AC_CHECK_FUNCS(pthread_attr_setinheritsched)
+
+ old_OBJCFLAGS="$OBJCFLAGS"
+ OBJCFLAGS="$OBJCFLAGS -Werror"
+ AC_MSG_CHECKING(for pthread_attr_setinheritsched)
+ AC_COMPILE_IFELSE([
+ AC_LANG_PROGRAM([
+ #include
+ ], [
+ pthread_attr_setinheritsched(
+ (pthread_attr_t *)-1, 0);
+ ])
+ ], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_PTHREAD_ATTR_SETINHERITSCHED, 1,
+ [Whether we have pthread_attr_setinheritsched])
+ ], [
+ AC_MSG_RESULT(no)
+ ])
+ OBJCFLAGS="$old_OBJCFLAGS"
AC_CHECK_HEADERS(pthread_np.h, [], [], [#include ])
AC_CHECK_FUNCS(pthread_set_name_np pthread_setname_np, break)
;;
esac
@@ -1308,11 +1297,11 @@
AC_CHECK_FUNCS([fcntl nanosleep])
;;
esac
AC_CHECK_HEADERS(xlocale.h)
-AC_CHECK_FUNCS([strtod_l strtof_l asprintf_l])
+AC_CHECK_FUNCS([strtod_l strtof_l asprintf_l uselocale])
AS_IF([test x"$gnu_source" != x"yes" -a \( \
x"$ac_cv_func_strtod_l" = x"yes" -o x"$ac_cv_func_strtof_l" = x"yes" -o \
x"$ac_cv_func_asprintf_l" = x"yes" \)], [
AC_MSG_CHECKING(whether *_l functions need _GNU_SOURCE)
AC_COMPILE_IFELSE([
@@ -1394,21 +1383,70 @@
AC_CHECK_HEADER(sys/socket.h, [
AC_DEFINE(OF_HAVE_SYS_SOCKET_H, 1,
[Whether we have sys/socket.h])
])
+ AC_CHECK_MEMBERS([struct sockaddr.sa_len], [], [], [
+ #ifdef OF_HAVE_SYS_TYPES_H
+ # include
+ #endif
+ #ifdef OF_HAVE_SYS_SOCKET_H
+ # include
+ #endif
+ #ifdef _WIN32
+ # include
+ #endif
+ ])
+ AC_CHECK_TYPE([struct sockaddr_storage], [
+ AC_DEFINE(OF_HAVE_SOCKADDR_STORAGE, 1,
+ [Whether we have struct sockaddr_storage])
+ ], [], [
+ #ifdef OF_HAVE_SYS_TYPES_H
+ # include
+ #endif
+ #ifdef OF_HAVE_SYS_SOCKET_H
+ # include
+ #endif
+ #ifdef _WIN32
+ # include
+ #endif
+ ])
AC_CHECK_HEADER(netinet/in.h, [
AC_DEFINE(OF_HAVE_NETINET_IN_H, 1,
[Whether we have netinet/in.h])
])
AC_CHECK_HEADER(netinet/tcp.h, [
AC_DEFINE(OF_HAVE_NETINET_TCP_H, 1,
[Whether we have netinet/tcp.h])
])
- AC_CHECK_HEADERS([arpa/inet.h netdb.h net/if.h])
- AC_CHECK_FUNCS([if_indextoname if_nametoindex])
+ AC_CHECK_HEADERS([arpa/inet.h netdb.h sys/sockio.h])
+ AC_CHECK_HEADERS([net/if.h], [], [], [
+ #ifdef OF_HAVE_SYS_SOCKET_H
+ # include
+ #endif
+ ])
+ AC_CHECK_HEADERS([net/if_arp.h net/if_dl.h net/if_types.h])
+ AC_CHECK_FUNCS([if_indextoname if_nametoindex if_nameindex])
+ AC_CHECK_TYPES([struct sockaddr_dl], [], [], [
+ #ifdef HAVE_SYS_TYPES_H
+ # include
+ #endif
+ #ifdef HAVE_NET_IF_DL_H
+ # include
+ #endif
+ ])
+ AC_CHECK_TYPES([struct lifconf], [], [], [
+ #ifdef HAVE_NET_IF_H
+ # include
+ #endif
+ ])
+ AC_CHECK_MEMBERS([struct ifreq.ifr_hwaddr], [], [], [
+ #ifdef HAVE_NET_IF_H
+ # include
+ #endif
+ ])
AC_CHECK_HEADER(sys/un.h, [
AC_DEFINE(OF_HAVE_SYS_UN_H, 1, [Whether we have sys/un.h])
])
AC_CHECK_MEMBER([struct sockaddr_in6.sin6_addr], [
AC_EGREP_CPP(egrep_cpp_yes, [
@@ -1471,10 +1509,25 @@
])
AC_CHECK_MEMBER(struct sockaddr_un.sun_path, [
AC_DEFINE(OF_HAVE_UNIX_SOCKETS, 1,
[Whether we have UNIX sockets])
AC_SUBST(USE_SRCS_UNIX_SOCKETS, '${SRCS_UNIX_SOCKETS}')
+
+ AC_CHECK_MEMBERS(struct sockaddr_un.sun_len, [], [], [
+ #ifdef OF_HAVE_SYS_TYPES_H
+ # include
+ #endif
+ #ifdef OF_HAVE_SYS_UN_H
+ # include
+ #endif
+ #ifdef _WIN32
+ # include
+ #endif
+ #ifdef HAVE_AFUNIX_H
+ # include
+ #endif
+ ])
], [], [
#ifdef OF_HAVE_SYS_TYPES_H
# include
#endif
#ifdef OF_HAVE_SYS_UN_H
@@ -1499,14 +1552,29 @@
AC_CHECK_HEADER(netipx/ipx.h, [
AC_DEFINE(OF_HAVE_NETIPX_IPX_H, 1,
[Whether we have netipx/ipx.h])
])
AC_CHECK_MEMBER(struct sockaddr_ipx.sipx_network, [], [
- AC_CHECK_MEMBER(struct sockaddr_ipx.sa_netnum, [], [], [
+ AC_CHECK_MEMBER(struct sockaddr_ipx.sa_netnum, [], [
+ AC_CHECK_MEMBER(struct sockaddr_ipx.sipx_addr.x_port,
+ [], [], [
+ #ifdef HAVE_SYS_TYPES_H
+ # include
+ #endif
+
+ #ifdef OF_HAVE_NETIPX_IPX_H
+ # include
+ #endif
+ ])
+ ], [
#ifdef _WIN32
typedef int BOOL;
#endif
+
+ #ifdef HAVE_SYS_TYPES_H
+ # include
+ #endif
#ifdef OF_HAVE_NETIPX_IPX_H
# include
#endif
@@ -1523,10 +1591,14 @@
])
], [
#ifdef _WIN32
typedef int BOOL;
#endif
+
+ #ifdef HAVE_SYS_TYPES_H
+ # include
+ #endif
#ifdef OF_HAVE_NETIPX_IPX_H
# include
#endif
@@ -1540,11 +1612,12 @@
# include
# include
#endif
])
AS_IF([test x"$ac_cv_member_struct_sockaddr_ipx_sipx_network" = x"yes" \
- -o x"$ac_cv_member_struct_sockaddr_ipx_sa_netnum" = x"yes"], [
+ -o x"$ac_cv_member_struct_sockaddr_ipx_sa_netnum" = x"yes" -o \
+ x"$ac_cv_member_struct_sockaddr_ipx_sipx_addr_x_port" = x"yes"], [
AC_EGREP_CPP(egrep_cpp_yes, [
#ifdef _WIN32
typedef int BOOL;
#endif
@@ -1709,24 +1782,22 @@
esac
AC_ARG_WITH(tls,
AS_HELP_STRING([--with-tls], [
enable TLS support using the specified library
- (yes, openssl, gnutls, securetransport or no)]))
+ (yes, openssl, gnutls, securetransport, mbedtls or
+ no)]))
AS_IF([test x"$with_tls" = x""], [with_tls="yes"])
tls_support="no"
AS_IF([test x"$with_tls" = x"securetransport" \
- -o x"$with_tls" = x"yes"], [
+ -o x"$with_tls" = x"yes"], [
AC_CHECK_HEADERS(Security/SecureTransport.h, [
old_LIBS="$LIBS"
LIBS="-framework Security -framework Foundation $LIBS"
AC_CHECK_FUNC(SSLHandshake, [
- AC_DEFINE(HAVE_SECURE_TRANSPORT, 1,
- [Whether we have Secure Transport])
-
tls_support="Secure Transport"
TLS_LIBS="-framework Foundation $TLS_LIBS"
TLS_LIBS="-framework Security $TLS_LIBS"
AC_SUBST(OF_SECURE_TRANSPORT_TLS_STREAM_M,
@@ -1737,29 +1808,12 @@
LIBS="$old_LIBS"
])
])
- AS_IF([test x"$with_tls" = x"gnutls" \
- -o \( x"$with_tls" = x"yes" -a x"$tls_support" = x"no" \)], [
- PKG_CHECK_MODULES(gnutls, [gnutls >= 3.5.0], [
- AC_DEFINE(HAVE_GNUTLS, 1, [Whether we have GnuTLS])
-
- tls_support="GnuTLS"
- TLS_CPPFLAGS="$gnutls_CFLAGS $TLS_CPPFLAGS"
- TLS_LIBS="$gnutls_LIBS $TLS_LIBS"
-
- AC_SUBST(OF_GNUTLS_TLS_STREAM_M, "OFGnuTLSTLSStream.m")
- ], [
- dnl Disable default action-if-not-found, which exits
- dnl configure with an error.
- :
- ])
- ])
-
AS_IF([test x"$with_tls" = x"openssl" \
- -o \( x"$with_tls" = x"yes" -a x"$tls_support" = x"no" \)], [
+ -o \( x"$with_tls" = x"yes" -a x"$tls_support" = x"no" \)], [
case "$host_os" in
morphos*)
ssl="ssl_shared"
crypto="crypto_shared"
;;
@@ -1769,21 +1823,60 @@
;;
esac
AC_CHECK_LIB($ssl, SSL_set1_host, [
AC_CHECK_HEADER(openssl/ssl.h, [
- AC_DEFINE(HAVE_OPENSSL, 1,
- [Whether we have OpenSSL])
-
tls_support="OpenSSL"
TLS_LIBS="-l$ssl -l$crypto $TLS_LIBS"
AC_SUBST(OF_OPENSSL_TLS_STREAM_M,
"OFOpenSSLTLSStream.m")
+
+ old_LIBS="$LIBS"
+ LIBS="$TLS_LIBS $LIBS"
+ AC_CHECK_FUNCS(SSL_has_pending)
+ LIBS="$old_LIBS"
])
], [], [-l$crypto])
])
+
+ AS_IF([test x"$with_tls" = x"gnutls" \
+ -o \( x"$with_tls" = x"yes" -a x"$tls_support" = x"no" \)], [
+ PKG_CHECK_MODULES(gnutls, [gnutls >= 3.5.0], [
+ tls_support="GnuTLS"
+ TLS_CPPFLAGS="$gnutls_CFLAGS $TLS_CPPFLAGS"
+ TLS_LIBS="$gnutls_LIBS $TLS_LIBS"
+
+ AC_SUBST(OF_GNUTLS_TLS_STREAM_M, "OFGnuTLSTLSStream.m")
+ ], [
+ dnl Disable default action-if-not-found, which exits
+ dnl configure with an error.
+ :
+ ])
+ ])
+
+ AS_IF([test x"$with_tls" = x"mbedtls"], [
+ AC_ARG_WITH(mbedtls-ca-path,
+ AS_HELP_STRING([path to CA file for Mbed TLS]))
+
+ AS_IF([test x"$with_mbedtls_ca_path" = x""], [
+ AC_MSG_ERROR([--mbedtls-ca-path needs to be specified!])
+ ])
+ AC_DEFINE_UNQUOTED(OF_MBEDTLS_CA_PATH, "$with_mbedtls_ca_path",
+ [Path to CA file for Mbed TLS])
+
+ AC_CHECK_LIB(mbedtls, mbedtls_net_init, [
+ AC_CHECK_HEADER(mbedtls/ssl.h, [
+ tls_support="Mbed TLS"
+ TLS_LIBS="-lmbedx509 -lmbedcrypto $TLS_LIBS"
+ TLS_LIBS="-lmbedtls $TLS_LIBS"
+
+ AC_SUBST(OF_MBEDTLS_TLS_STREAM_M,
+ "OFMbedTLSTLSStream.m")
+ ])
+ ], [], [-lmbedx509 -lmbedcrypto])
+ ])
AS_IF([test x"$tls_support" != x"no"], [
AC_SUBST(TLS, "tls")
AC_SUBST(TLS_CPPFLAGS)
AC_SUBST(TLS_LIBS)
@@ -1793,11 +1886,11 @@
OFHTTP_LIBS="-lobjfwtls $TLS_LIBS $OFHTTP_LIBS"
AS_IF([test x"$enable_shared" != x"no"], [
AC_SUBST(OBJFWTLS_SHARED_LIB,
- "${LIB_PREFIX}objfwtls${LIB_SUFFIX}")
+ '${LIB_PREFIX}objfwtls${LIB_SUFFIX}')
])
AS_IF([test x"$enable_static" = x"yes" \
-o x"$enable_shared" = x"no"], [
AC_SUBST(OBJFWTLS_STATIC_LIB, "libobjfwtls.a")
])
@@ -1857,14 +1950,10 @@
(!defined(TARGET_OS_SIMULATOR) || !TARGET_OS_SIMULATOR)
egrep_cpp_yes
#endif
], [
AC_MSG_RESULT(yes)
- have_subprocesses="yes"
-
- AC_CHECK_FUNCS(posix_spawnp)
- AC_CHECK_HEADERS(spawn.h)
], [
AC_MSG_RESULT(no)
have_subprocesses="no"
])
;;
@@ -1872,21 +1961,22 @@
have_subprocesses="yes"
;;
msdosdjgpp*)
have_subprocesses="no"
;;
-*)
+esac
+AS_IF([test x"$have_subprocesses" = x""], [
AC_HEADER_SYS_WAIT
AC_CHECK_FUNCS(kill)
AC_CHECK_FUNCS(posix_spawnp, [
AS_IF([test x"$ac_cv_func_kill" = x"yes"], [
- have_subprocesses="yes"
-
- AC_CHECK_HEADERS(spawn.h)
+ AC_CHECK_HEADERS(spawn.h, [have_subprocesses="yes"])
])
- ], [
+ ])
+
+ AS_IF([test x"$have_subprocesses" = x""], [
AC_CHECK_FUNCS([vfork dup2 execvp _exit], [
AS_IF([test x"$ac_cv_func_vfork" = x"yes" \
-a x"$ac_cv_func_pipe" = x"yes" \
-a x"$ac_cv_func_dup2" = x"yes" \
-a x"$ac_cv_func_execvp" = x"yes" \
@@ -1896,19 +1986,18 @@
])
], [
break
])
])
- ;;
-esac
+])
AS_IF([test x"$have_subprocesses" = x"yes"], [
AC_SUBST(OF_SUBPROCESS_M, "OFSubprocess.m")
AC_DEFINE(OF_HAVE_SUBPROCESSES, 1, [Whether we have subprocesses])
])
AC_CHECK_HEADERS_ONCE([complex.h sys/ioctl.h sys/ttycom.h])
-AC_CHECK_FUNCS(isatty)
+AC_CHECK_FUNCS(ioctl isatty)
AC_CHECK_FUNC(pledge, [
AC_DEFINE(OF_HAVE_PLEDGE, 1, [Whether we have pledge()])
])
@@ -1917,11 +2006,11 @@
AC_SUBST(BRIDGE, "bridge")
AC_CONFIG_FILES(src/bridge/Info.plist)
AS_IF([test x"$enable_shared" != x"no"], [
AC_SUBST(OBJFWBRIDGE_SHARED_LIB,
- "${LIB_PREFIX}objfwbridge${LIB_SUFFIX}")
+ '${LIB_PREFIX}objfwbridge${LIB_SUFFIX}')
])
AS_IF([test x"$enable_static" = x"yes" \
-o x"$enable_shared" = x"no"], [
AC_SUBST(OBJFWBRIDGE_STATIC_LIB, "libobjfwbridge.a")
])
@@ -1951,12 +2040,20 @@
AC_MSG_RESULT(no)
OBJCFLAGS="$old_OBJCFLAGS"
])
AS_IF([test x"$GOBJC" = x"yes"], [
- OBJCFLAGS="$OBJCFLAGS -Wwrite-strings -Wpointer-arith -Werror"
+ OBJCFLAGS="$OBJCFLAGS -Wwrite-strings -Wpointer-arith"
+
+ AC_ARG_ENABLE(werror,
+ AS_HELP_STRING([--disable-werror], [do not build with -Werror]))
+ AS_IF([test x"$enable_werror" != x"no"], [
+ OBJCFLAGS="$OBJCFLAGS -Werror"
+ ])
+ old_OBJCFLAGS="$OBJCFLAGS"
+ OBJCFLAGS="$OBJCFLAGS -Werror"
AC_MSG_CHECKING(whether we need -Wno-strict-aliasing due to GCC bugs)
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([
#ifdef __has_attribute
# if __has_attribute(objc_root_class)
@@ -1976,15 +2073,18 @@
Foo *test = (Foo *)&object;
(void)test; /* Get rid of unused variable warning */
])
], [
AC_MSG_RESULT(no)
+ OBJCFLAGS="$old_OBJCFLAGS"
], [
AC_MSG_RESULT(yes)
- OBJCFLAGS="$OBJCFLAGS -Wno-strict-aliasing"
+ OBJCFLAGS="$old_OBJCFLAGS -Wno-strict-aliasing"
])
+ old_OBJCFLAGS="$OBJCFLAGS"
+ OBJCFLAGS="$OBJCFLAGS -Werror"
AC_MSG_CHECKING(
whether we need -Wno-unused-property-ivar due to Clang bugs)
AC_COMPILE_IFELSE([
AC_LANG_SOURCE([
#ifdef __has_attribute
@@ -2012,17 +2112,18 @@
}
@end
])
], [
AC_MSG_RESULT(no)
+ OBJCFLAGS="$old_OBJCFLAGS"
], [
AC_MSG_RESULT(yes)
- OBJCFLAGS="$OBJCFLAGS -Wno-unused-property-ivar"
+ OBJCFLAGS="$old_OBJCFLAGS -Wno-unused-property-ivar"
])
old_OBJCFLAGS="$OBJCFLAGS"
- OBJCFLAGS="$OBJCFLAGS -Wcast-align"
+ OBJCFLAGS="$OBJCFLAGS -Wcast-align -Werror"
AC_MSG_CHECKING(whether -Wcast-align is buggy)
AC_COMPILE_IFELSE([
AC_LANG_SOURCE([
#ifdef __has_attribute
# if __has_attribute(objc_root_class)
@@ -2043,17 +2144,18 @@
}
@end
])
], [
AC_MSG_RESULT(no)
+ OBJCFLAGS="$old_OBJCFLAGS -Wcast-align"
], [
AC_MSG_RESULT(yes)
OBJCFLAGS="$old_OBJCFLAGS"
])
old_OBJCFLAGS="$OBJCFLAGS"
- OBJCFLAGS="$OBJCFLAGS -Wunreachable-code"
+ OBJCFLAGS="$OBJCFLAGS -Wunreachable-code -Werror"
AC_MSG_CHECKING(whether -Wunreachable-code can be used)
AC_COMPILE_IFELSE([
AC_LANG_SOURCE([[
#include
@@ -2119,17 +2221,18 @@
}
@end
]])
], [
AC_MSG_RESULT(yes)
+ OBJCFLAGS="$old_OBJCFLAGS -Wunreachable-code"
], [
AC_MSG_RESULT(no)
OBJCFLAGS="$old_OBJCFLAGS"
])
old_OBJCFLAGS="$OBJCFLAGS"
- OBJCFLAGS="$OBJCFLAGS -Wdocumentation"
+ OBJCFLAGS="$OBJCFLAGS -Wdocumentation -Werror"
AC_MSG_CHECKING(whether -Wdocumentation works correctly)
AC_COMPILE_IFELSE([
AC_LANG_SOURCE([
/**
* @class Test conftest.m conftest.m
@@ -2147,18 +2250,19 @@
*/
typedef struct {} Foo;
])
], [
AC_MSG_RESULT(yes)
+ OBJCFLAGS="$old_OBJCFLAGS -Wdocumentation"
], [
AC_MSG_RESULT(no)
OBJCFLAGS="$old_OBJCFLAGS"
])
AS_IF([test x"$check_pedantic" = x"yes"], [
old_OBJCFLAGS="$OBJCFLAGS"
- OBJCFLAGS="$OBJCFLAGS -pedantic"
+ OBJCFLAGS="$OBJCFLAGS -pedantic -Werror"
AC_MSG_CHECKING(whether -pedantic is buggy)
AC_COMPILE_IFELSE([
AC_LANG_SOURCE([
#include
@@ -2190,17 +2294,37 @@
}
@end
])
], [
AC_MSG_RESULT(no)
+ OBJCFLAGS="$old_OBJCFLAGS -pedantic"
], [
AC_MSG_RESULT(yes)
OBJCFLAGS="$old_OBJCFLAGS"
])
])
+
+ old_OBJCFLAGS="$OBJCFLAGS"
+ OBJCFLAGS="$OBJCFLAGS -Werror"
+ AC_MSG_CHECKING(whether we need -Wno-strict-prototypes)
+ AC_COMPILE_IFELSE([
+ AC_LANG_PROGRAM([
+ #include
+ ], [
+ signal(SIGINT, SIG_DFL);
+ ])
+ ], [
+ AC_MSG_RESULT(no)
+ OBJCFLAGS="$old_OBJCFLAGS"
+ ], [
+ AC_MSG_RESULT(yes)
+ OBJCFLAGS="$old_OBJCFLAGS -Wno-strict-prototypes"
+ ])
AS_IF([test x"$ac_cv_header_complex_h" = x"yes"], [
+ old_OBJCFLAGS="$OBJCFLAGS"
+ OBJCFLAGS="$OBJCFLAGS -Werror"
AC_MSG_CHECKING(whether we need -Wno-gnu-imaginary-constant)
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([
#include
], [
@@ -2207,13 +2331,14 @@
complex float f = 0.5 + 0.5 * I;
(void)f;
])
], [
AC_MSG_RESULT(no)
+ OBJCFLAGS="$old_OBJCFLAGS"
], [
AC_MSG_RESULT(yes)
- OBJCFLAGS="$OBJCFLAGS -Wno-gnu-imaginary-constant"
+ OBJCFLAGS="$old_OBJCFLAGS -Wno-gnu-imaginary-constant"
])
])
])
AS_IF([test x"$cross_compiling" = x"yes"], [
@@ -2225,14 +2350,11 @@
;;
x86_64-*-mingw*)
AC_CHECK_PROG(WINE, wine64, wine64)
;;
esac
-
- AS_IF([test x"$WINE" != x""], [
- AC_SUBST(WRAPPER, "$WINE")
- ])
+ AS_IF([test x"$WINE" != x""], [AC_SUBST(WRAPPER, "$WINE")])
AS_IF([test x"$with_wii" = x"yes"], [
dnl Keep this lowercase, as WIILOAD is a variable used by
dnl wiiload and thus likely already set by the user to something
dnl that is not the path of the wiiload binary.
@@ -2242,21 +2364,10 @@
AC_SUBST(WRAPPER, "$wiiload")
])
])
])
-AC_ARG_WITH(fish_completions,
- AS_HELP_STRING([--with-fish-completions],
- [install completions for the fish shell]))
-AS_IF([test x"$with_fish_completions" = x""], [
- AC_CHECK_PROG(FISH, fish, fish)
- AS_IF([test x"$FISH" != x""], [with_fish_completions="yes"])
-])
-AS_IF([test x"$with_fish_completions" = x"yes"], [
- AC_SUBST(FISH_COMPLETIONS, fish)
-])
-
dnl We don't call AC_PROG_CPP, but only AC_PROG_OBJCPP and set CPP to OBJCPP
dnl and add OBJCPPFLAGS to CPPFLAGS, thus we need to AC_SUBST these ourself.
AC_SUBST(CPP)
AC_SUBST(CPPFLAGS)
dnl We use the ObjC compiler as our assembler
Index: extra.mk.in
==================================================================
--- extra.mk.in
+++ extra.mk.in
@@ -1,47 +1,51 @@
OBJFW_SHARED_LIB = @OBJFW_SHARED_LIB@
OBJFW_STATIC_LIB = @OBJFW_STATIC_LIB@
OBJFW_FRAMEWORK = @OBJFW_FRAMEWORK@
-OBJFW_LIB_MAJOR = 0
-OBJFW_LIB_MINOR = 0
+OBJFW_LIB_MAJOR = 1
+OBJFW_LIB_MINOR = 1
+OBJFW_LIB_PATCH = 0
OBJFW_LIB_MAJOR_MINOR = ${OBJFW_LIB_MAJOR}.${OBJFW_LIB_MINOR}
OBJFWRT_SHARED_LIB = @OBJFWRT_SHARED_LIB@
OBJFWRT_STATIC_LIB = @OBJFWRT_STATIC_LIB@
OBJFWRT_FRAMEWORK = @OBJFWRT_FRAMEWORK@
-OBJFWRT_AMIGA_LIB = @OBJFWRT_AMIGA_LIB@
-OBJFWRT_LIB_MAJOR = 0
+OBJFWRT_LIB_MAJOR = 1
OBJFWRT_LIB_MINOR = 0
+OBJFWRT_LIB_PATCH = 0
OBJFWRT_LIB_MAJOR_MINOR = ${OBJFWRT_LIB_MAJOR}.${OBJFWRT_LIB_MINOR}
OBJFWBRIDGE_SHARED_LIB = @OBJFWBRIDGE_SHARED_LIB@
OBJFWBRIDGE_STATIC_LIB = @OBJFWBRIDGE_STATIC_LIB@
OBJFWBRIDGE_FRAMEWORK = @OBJFWBRIDGE_FRAMEWORK@
+OBJFWBRIDGE_LIB_MAJOR = 1
+OBJFWBRIDGE_LIB_MINOR = 0
+OBJFWBRIDGE_LIB_PATCH = 0
OBJFWTLS_SHARED_LIB = @OBJFWTLS_SHARED_LIB@
OBJFWTLS_STATIC_LIB = @OBJFWTLS_STATIC_LIB@
OBJFWTLS_FRAMEWORK = @OBJFWTLS_FRAMEWORK@
+OBJFWTLS_LIB_MAJOR = 1
+OBJFWTLS_LIB_MINOR = 0
+OBJFWTLS_LIB_PATCH = 2
BIN_PREFIX = @BIN_PREFIX@
BRIDGE = @BRIDGE@
CVINCLUDE_INLINE_H = @CVINCLUDE_INLINE_H@
ENCODINGS_A = @ENCODINGS_A@
ENCODINGS_LIB_A = @ENCODINGS_LIB_A@
ENCODINGS_SRCS = @ENCODINGS_SRCS@
EXCEPTIONS_A = @EXCEPTIONS_A@
EXCEPTIONS_LIB_A = @EXCEPTIONS_LIB_A@
-FISH_COMPLETIONS = @FISH_COMPLETIONS@
FORWARDING_A = @FORWARDING_A@
FORWARDING_LIB_A = @FORWARDING_LIB_A@
LIBBASES_M = @LIBBASES_M@
LIBOBJFWRT_DEP = @LIBOBJFWRT_DEP@
LIBOBJFWRT_DEP_LVL2 = @LIBOBJFWRT_DEP_LVL2@
LIBOBJFW_DEP = @LIBOBJFW_DEP@
LIBOBJFW_DEP_LVL2 = @LIBOBJFW_DEP_LVL2@
-LINKLIB = @LINKLIB@
LOOKUP_ASM_A = @LOOKUP_ASM_A@
-LOOKUP_ASM_AMIGALIB_A = @LOOKUP_ASM_AMIGALIB_A@
LOOKUP_ASM_LIB_A = @LOOKUP_ASM_LIB_A@
MAP_LDFLAGS = @MAP_LDFLAGS@
OBJC_SYNC = @OBJC_SYNC@
OBJFW_NEW = @OBJFW_NEW@
OFARC = @OFARC@
@@ -52,10 +56,11 @@
OF_BLOCK_TESTS_M = @OF_BLOCK_TESTS_M@
OF_EPOLL_KERNEL_EVENT_OBSERVER_M = @OF_EPOLL_KERNEL_EVENT_OBSERVER_M@
OF_GNUTLS_TLS_STREAM_M = @OF_GNUTLS_TLS_STREAM_M@
OF_HTTP_CLIENT_TESTS_M = @OF_HTTP_CLIENT_TESTS_M@
OF_KQUEUE_KERNEL_EVENT_OBSERVER_M = @OF_KQUEUE_KERNEL_EVENT_OBSERVER_M@
+OF_MBEDTLS_TLS_STREAM_M = @OF_MBEDTLS_TLS_STREAM_M@
OF_OPENSSL_TLS_STREAM_M = @OF_OPENSSL_TLS_STREAM_M@
OF_POLL_KERNEL_EVENT_OBSERVER_M = @OF_POLL_KERNEL_EVENT_OBSERVER_M@
OF_SECURE_TRANSPORT_TLS_STREAM_M = @OF_SECURE_TRANSPORT_TLS_STREAM_M@
OF_SELECT_KERNEL_EVENT_OBSERVER_M = @OF_SELECT_KERNEL_EVENT_OBSERVER_M@
OF_SUBPROCESS_M = @OF_SUBPROCESS_M@
@@ -82,9 +87,10 @@
USE_SRCS_APPLETALK = @USE_SRCS_APPLETALK@
USE_SRCS_FILES = @USE_SRCS_FILES@
USE_SRCS_IPX = @USE_SRCS_IPX@
USE_SRCS_PLUGINS = @USE_SRCS_PLUGINS@
USE_SRCS_SOCKETS = @USE_SRCS_SOCKETS@
+USE_SRCS_TAGGED_POINTERS = @USE_SRCS_TAGGED_POINTERS@
USE_SRCS_THREADS = @USE_SRCS_THREADS@
USE_SRCS_UNIX_SOCKETS = @USE_SRCS_UNIX_SOCKETS@
USE_SRCS_WINDOWS = @USE_SRCS_WINDOWS@
WRAPPER = @WRAPPER@
DELETED generators/library/FuncArrayGenerator.h
Index: generators/library/FuncArrayGenerator.h
==================================================================
--- generators/library/FuncArrayGenerator.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
- *
- * All rights reserved.
- *
- * This file is part of ObjFW. It may be distributed under the terms of the
- * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
- * the packaging of this file.
- *
- * Alternatively, it may be distributed under the terms of the GNU General
- * Public License, either version 2 or 3, which can be found in the file
- * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
- * file.
- */
-
-#import "OFObject.h"
-
-#import "OFStream.h"
-#import "OFXMLElement.h"
-
-@interface FuncArrayGenerator: OFObject
-{
- OFXMLElement *_library;
- OFStream *_include;
-}
-
-- (instancetype)initWithLibrary: (OFXMLElement *)library
- include: (OFStream *)include;
-- (void)generate;
-@end
DELETED generators/library/FuncArrayGenerator.m
Index: generators/library/FuncArrayGenerator.m
==================================================================
--- generators/library/FuncArrayGenerator.m
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
- *
- * All rights reserved.
- *
- * This file is part of ObjFW. It may be distributed under the terms of the
- * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
- * the packaging of this file.
- *
- * Alternatively, it may be distributed under the terms of the GNU General
- * Public License, either version 2 or 3, which can be found in the file
- * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
- * file.
- */
-
-#include "config.h"
-
-#import "OFArray.h"
-#import "OFXMLAttribute.h"
-
-#import "FuncArrayGenerator.h"
-
-#import "OFInvalidFormatException.h"
-#import "OFUnsupportedVersionException.h"
-
-#import "copyright.h"
-
-@implementation FuncArrayGenerator
-- (instancetype)initWithLibrary: (OFXMLElement *)library
- include: (OFStream *)include
-{
- self = [super init];
-
- @try {
- OFXMLAttribute *version;
-
- if (![library.name isEqual: @"amiga-library"] ||
- library.namespace != nil)
- @throw [OFInvalidFormatException exception];
-
- if ((version = [library attributeForName: @"version"]) == nil)
- @throw [OFInvalidFormatException exception];
-
- if (![version.stringValue isEqual: @"1.0"])
- @throw [OFUnsupportedVersionException
- exceptionWithVersion: version.stringValue];
-
- _library = [library retain];
- _include = [include retain];
- } @catch (id e) {
- [self release];
- @throw e;
- }
-
- return self;
-}
-
-- (void)dealloc
-{
- [_library release];
- [_include release];
-
- [super dealloc];
-}
-
-- (void)generate
-{
- [_include writeString: COPYRIGHT];
- [_include writeString:
- @"/* This file is automatically generated from amiga-library.xml */"
- @"\n\n"];
-
- for (OFXMLElement *function in [_library elementsForName: @"function"])
- [_include writeFormat:
- @"(CONST_APTR)glue_%@,\n",
- [function attributeForName: @"name"].stringValue];
-}
-@end
DELETED generators/library/GlueGenerator.h
Index: generators/library/GlueGenerator.h
==================================================================
--- generators/library/GlueGenerator.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
- *
- * All rights reserved.
- *
- * This file is part of ObjFW. It may be distributed under the terms of the
- * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
- * the packaging of this file.
- *
- * Alternatively, it may be distributed under the terms of the GNU General
- * Public License, either version 2 or 3, which can be found in the file
- * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
- * file.
- */
-
-#import "OFObject.h"
-
-#import "OFStream.h"
-#import "OFXMLElement.h"
-
-@interface GlueGenerator: OFObject
-{
- OFXMLElement *_library;
- OFStream *_header, *_impl;
-}
-
-- (instancetype)initWithLibrary: (OFXMLElement *)library
- header: (OFStream *)header
- implementation: (OFStream *)implementation;
-- (void)generate;
-@end
DELETED generators/library/GlueGenerator.m
Index: generators/library/GlueGenerator.m
==================================================================
--- generators/library/GlueGenerator.m
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
- *
- * All rights reserved.
- *
- * This file is part of ObjFW. It may be distributed under the terms of the
- * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
- * the packaging of this file.
- *
- * Alternatively, it may be distributed under the terms of the GNU General
- * Public License, either version 2 or 3, which can be found in the file
- * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
- * file.
- */
-
-#include "config.h"
-
-#import "OFArray.h"
-#import "OFXMLAttribute.h"
-
-#import "GlueGenerator.h"
-
-#import "OFInvalidFormatException.h"
-#import "OFUnsupportedVersionException.h"
-
-#import "copyright.h"
-
-@implementation GlueGenerator
-- (instancetype)initWithLibrary: (OFXMLElement *)library
- header: (OFStream *)header
- implementation: (OFStream *)impl
-{
- self = [super init];
-
- @try {
- OFXMLAttribute *version;
-
- if (![library.name isEqual: @"amiga-library"] ||
- library.namespace != nil)
- @throw [OFInvalidFormatException exception];
-
- if ((version = [library attributeForName: @"version"]) == nil)
- @throw [OFInvalidFormatException exception];
-
- if (![version.stringValue isEqual: @"1.0"])
- @throw [OFUnsupportedVersionException
- exceptionWithVersion: version.stringValue];
-
- _library = [library retain];
- _header = [header retain];
- _impl = [impl retain];
- } @catch (id e) {
- [self release];
- @throw e;
- }
-
- return self;
-}
-
-- (void)dealloc
-{
- [_library release];
- [_header release];
- [_impl release];
-
- [super dealloc];
-}
-
-- (void)generate
-{
- [_header writeString: COPYRIGHT];
- [_impl writeString: COPYRIGHT];
-
- [_header writeString:
- @"/* This file is automatically generated from amiga-library.xml */"
- @"\n\n"];
-
- [_impl writeString:
- @"/* This file is automatically generated from amiga-library.xml */"
- @"\n\n"
- @"#include \"config.h\"\n"
- @"\n"
- @"#import \"amiga-glue.h\"\n"
- @"\n"];
-
- for (OFXMLElement *include in [_library elementsForName: @"include"])
- [_header writeFormat: @"#import \"%@\"\n", include.stringValue];
-
- [_header writeString:
- @"\n"
- @"#ifdef OF_AMIGAOS_M68K\n"
- @"# define PPC_PARAMS(...) (void)\n"
- @"# define M68K_ARG(type, name, reg)\t\t\\\n"
- @"\tregister type reg##name __asm__(#reg);\t\\\n"
- @"\ttype name = reg##name;\n"
- @"#else\n"
- @"# define PPC_PARAMS(...) (__VA_ARGS__)\n"
- @"# define M68K_ARG(...)\n"
- @"#endif\n"
- @"\n"];
- [_impl writeString:
- @"#ifdef OF_MORPHOS\n"
- @"/* All __saveds functions in this file need to use the SysV "
- @"ABI */\n"
- @"__asm__ (\n"
- @" \".section .text\\n\"\n"
- @" \".align 2\\n\"\n"
- @" \"__restore_r13:\\n\"\n"
- @" \"\tlwz\t%r13, 44(%r12)\\n\"\n"
- @" \"\tblr\\n\"\n"
- @");\n"
- @"#endif\n"];
-
- for (OFXMLElement *function in
- [_library elementsForName: @"function"]) {
- OFString *name =
- [function attributeForName: @"name"].stringValue;
- OFString *returnType =
- [function attributeForName: @"return-type"].stringValue;
- OFArray OF_GENERIC(OFXMLElement *) *arguments =
- [function elementsForName: @"argument"];
- size_t argumentIndex;
-
- if (returnType == nil)
- returnType = @"void";
-
- [_header writeFormat:
- @"extern %@%@glue_%@",
- returnType,
- (![returnType hasSuffix: @"*"] ? @" " : @""),
- name];
-
- [_impl writeFormat: @"\n"
- @"%@ __saveds\n"
- @"glue_%@",
- returnType, name];
-
- if (arguments.count > 0) {
- [_header writeString: @" PPC_PARAMS("];
- [_impl writeString: @" PPC_PARAMS("];
- } else {
- [_header writeString: @"(void"];
- [_impl writeString: @"(void"];
- }
-
- argumentIndex = 0;
- for (OFXMLElement *argument in arguments) {
- OFString *argName =
- [argument attributeForName: @"name"].stringValue;
- OFString *argType =
- [argument attributeForName: @"type"].stringValue;
-
- if (argumentIndex++ > 0) {
- [_header writeString: @", "];
- [_impl writeString: @", "];
- }
-
- [_header writeString: argType];
- [_impl writeString: argType];
- if (![argType hasSuffix: @"*"]) {
- [_header writeString: @" "];
- [_impl writeString: @" "];
- }
- [_header writeString: argName];
- [_impl writeString: argName];
- }
-
- [_header writeString: @");\n"];
-
- [_impl writeString: @")\n{\n"];
- for (OFXMLElement *argument in arguments) {
- OFString *argName =
- [argument attributeForName: @"name"].stringValue;
- OFString *argType =
- [argument attributeForName: @"type"].stringValue;
- OFString *m68kReg = [argument
- attributeForName: @"m68k-reg"].stringValue;
-
- [_impl writeFormat: @"\tM68K_ARG(%@, %@, %@)\n",
- argType, argName, m68kReg];
- }
-
- if (arguments.count > 0)
- [_impl writeString: @"\n"];
-
- if (![returnType isEqual: @"void"])
- [_impl writeString: @"\treturn "];
- else
- [_impl writeString: @"\t"];
-
- [_impl writeFormat: @"%@(", name];
-
- argumentIndex = 0;
- for (OFXMLElement *argument in arguments) {
- OFString *argName =
- [argument attributeForName: @"name"].stringValue;
-
- if (argumentIndex++ > 0)
- [_impl writeString: @", "];
-
- [_impl writeString: argName];
- }
-
- [_impl writeString: @");\n}\n"];
- }
-}
-@end
DELETED generators/library/LibraryGenerator.m
Index: generators/library/LibraryGenerator.m
==================================================================
--- generators/library/LibraryGenerator.m
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
- *
- * All rights reserved.
- *
- * This file is part of ObjFW. It may be distributed under the terms of the
- * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
- * the packaging of this file.
- *
- * Alternatively, it may be distributed under the terms of the GNU General
- * Public License, either version 2 or 3, which can be found in the file
- * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
- * file.
- */
-
-#include "config.h"
-
-#import "OFApplication.h"
-#import "OFFile.h"
-#import "OFFileManager.h"
-#import "OFURI.h"
-#import "OFXMLElement.h"
-
-#import "FuncArrayGenerator.h"
-#import "GlueGenerator.h"
-#import "LinkLibGenerator.h"
-
-@interface LibraryGenerator: OFObject
-@end
-
-OF_APPLICATION_DELEGATE(LibraryGenerator)
-
-@implementation LibraryGenerator
-- (void)applicationDidFinishLaunching
-{
- OFURI *sourcesURI = [[OFFileManager defaultManager].currentDirectoryURI
- URIByAppendingPathComponent: @"../../src"];
- OFURI *runtimeLibraryURI = [sourcesURI
- URIByAppendingPathComponent: @"runtime/amiga-library.xml"];
- OFURI *runtimeLinkLibURI = [sourcesURI
- URIByAppendingPathComponent: @"runtime/linklib/linklib.m"];
- OFURI *runtimeGlueHeaderURI = [sourcesURI
- URIByAppendingPathComponent: @"runtime/amiga-glue.h"];
- OFURI *runtimeGlueURI = [sourcesURI
- URIByAppendingPathComponent: @"runtime/amiga-glue.m"];
- OFURI *runtimeFuncArrayURI = [sourcesURI
- URIByAppendingPathComponent: @"runtime/amiga-funcarray.inc"];
- OFXMLElement *runtimeLibrary = [OFXMLElement elementWithStream:
- [OFFile fileWithPath: runtimeLibraryURI.fileSystemRepresentation
- mode: @"r"]];
- OFFile *runtimeLinkLib =
- [OFFile fileWithPath: runtimeLinkLibURI.fileSystemRepresentation
- mode: @"w"];
- OFFile *runtimeGlueHeader =
- [OFFile fileWithPath: runtimeGlueHeaderURI.fileSystemRepresentation
- mode: @"w"];
- OFFile *runtimeGlue =
- [OFFile fileWithPath: runtimeGlueURI.fileSystemRepresentation
- mode: @"w"];
- OFFile *runtimeFuncArray =
- [OFFile fileWithPath: runtimeFuncArrayURI.fileSystemRepresentation
- mode: @"w"];
- LinkLibGenerator *runtimeLinkLibGenerator = [[[LinkLibGenerator alloc]
- initWithLibrary: runtimeLibrary
- implementation: runtimeLinkLib] autorelease];
- GlueGenerator *runtimeGlueGenerator = [[[GlueGenerator alloc]
- initWithLibrary: runtimeLibrary
- header: runtimeGlueHeader
- implementation: runtimeGlue] autorelease];
- FuncArrayGenerator *runtimeFuncArrayGenerator;
- runtimeFuncArrayGenerator = [[[FuncArrayGenerator alloc]
- initWithLibrary: runtimeLibrary
- include: runtimeFuncArray] autorelease];
-
- [runtimeLinkLibGenerator generate];
- [runtimeGlueGenerator generate];
- [runtimeFuncArrayGenerator generate];
-
- [OFApplication terminate];
-}
-@end
DELETED generators/library/LinkLibGenerator.h
Index: generators/library/LinkLibGenerator.h
==================================================================
--- generators/library/LinkLibGenerator.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
- *
- * All rights reserved.
- *
- * This file is part of ObjFW. It may be distributed under the terms of the
- * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
- * the packaging of this file.
- *
- * Alternatively, it may be distributed under the terms of the GNU General
- * Public License, either version 2 or 3, which can be found in the file
- * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
- * file.
- */
-
-#import "OFObject.h"
-#import "OFStream.h"
-#import "OFXMLElement.h"
-
-@interface LinkLibGenerator: OFObject
-{
- OFXMLElement *_library;
- OFStream *_impl;
-}
-
-- (instancetype)initWithLibrary: (OFXMLElement *)library
- implementation: (OFStream *)impl;
-- (void)generate;
-@end
DELETED generators/library/LinkLibGenerator.m
Index: generators/library/LinkLibGenerator.m
==================================================================
--- generators/library/LinkLibGenerator.m
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
- *
- * All rights reserved.
- *
- * This file is part of ObjFW. It may be distributed under the terms of the
- * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
- * the packaging of this file.
- *
- * Alternatively, it may be distributed under the terms of the GNU General
- * Public License, either version 2 or 3, which can be found in the file
- * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
- * file.
- */
-
-#include "config.h"
-
-#import "OFArray.h"
-#import "OFXMLAttribute.h"
-
-#import "LinkLibGenerator.h"
-
-#import "OFInvalidFormatException.h"
-#import "OFUnsupportedVersionException.h"
-
-#import "copyright.h"
-
-@implementation LinkLibGenerator
-- (instancetype)initWithLibrary: (OFXMLElement *)library
- implementation: (OFStream *)impl
-{
- self = [super init];
-
- @try {
- OFXMLAttribute *version;
-
- if (![library.name isEqual: @"amiga-library"] ||
- library.namespace != nil)
- @throw [OFInvalidFormatException exception];
-
- if ((version = [library attributeForName: @"version"]) == nil)
- @throw [OFInvalidFormatException exception];
-
- if (![version.stringValue isEqual: @"1.0"])
- @throw [OFUnsupportedVersionException
- exceptionWithVersion: version.stringValue];
-
- _library = [library retain];
- _impl = [impl retain];
- } @catch (id e) {
- [self release];
- @throw e;
- }
-
- return self;
-}
-
-- (void)dealloc
-{
- [_library release];
- [_impl release];
-
- [super dealloc];
-}
-
-- (void)generate
-{
- OFString *libBase = [_library attributeForName: @"base"].stringValue;
- OFArray OF_GENERIC(OFXMLElement *) *functions;
- size_t funcIndex = 0;
-
- [_impl writeString: COPYRIGHT];
- [_impl writeString:
- @"/* This file is automatically generated from amiga-library.xml */"
- @"\n\n"
- @"#include \"config.h\"\n"
- @"\n"];
-
- for (OFXMLElement *include in [_library elementsForName: @"include"])
- [_impl writeFormat: @"#import \"%@\"\n",
- include.stringValue];
-
- [_impl writeFormat: @"\n"
- @"extern struct Library *%@;\n"
- @"\n",
- libBase];
-
- functions = [_library elementsForName: @"function"];
- for (OFXMLElement *function in functions) {
- OFString *name =
- [function attributeForName: @"name"].stringValue;
- OFString *returnType =
- [function attributeForName: @"return-type"].stringValue;
- OFArray OF_GENERIC(OFXMLElement *) *arguments =
- [function elementsForName: @"argument"];
- size_t argumentIndex;
-
- if (returnType == nil)
- returnType = @"void";
-
- [_impl writeFormat: @"%@\n%@(", returnType, name];
-
- argumentIndex = 0;
- for (OFXMLElement *argument in
- [function elementsForName: @"argument"]) {
- OFString *argName =
- [argument attributeForName: @"name"].stringValue;
- OFString *argType =
- [argument attributeForName: @"type"].stringValue;
-
- if (argumentIndex++ > 0)
- [_impl writeString: @", "];
-
- [_impl writeString: argType];
- if (![argType hasSuffix: @"*"])
- [_impl writeString: @" "];
- [_impl writeString: argName];
- }
-
- [_impl writeFormat:
- @")\n"
- @"{\n"
- @"#if defined(OF_AMIGAOS_M68K)\n"
- @"\tregister struct Library *a6 __asm__(\"a6\") = %@;\n"
- @"\t(void)a6;\n"
- @"\t", libBase];
-
- if (![returnType isEqual: @"void"])
- [_impl writeString: @"return "];
-
- [_impl writeString: @"(("];
- [_impl writeString: returnType];
- if (![returnType hasSuffix: @"*"])
- [_impl writeString: @" "];
- [_impl writeString: @"(*)("];
-
- argumentIndex = 0;
- for (OFXMLElement *argument in arguments) {
- OFString *argType =
- [argument attributeForName: @"type"].stringValue;
- OFString *m68kReg = [argument
- attributeForName: @"m68k-reg"].stringValue;
-
- if (argumentIndex++ > 0)
- [_impl writeString: @", "];
-
- [_impl writeString: argType];
- if (![argType hasSuffix: @"*"])
- [_impl writeString: @" "];
- [_impl writeFormat: @"__asm__(\"%@\")",
- m68kReg];
- }
-
- [_impl writeFormat: @"))(((uintptr_t)%@) - %zu))(",
- libBase, 30 + funcIndex * 6];
-
- argumentIndex = 0;
- for (OFXMLElement *argument in
- [function elementsForName: @"argument"]) {
- OFString *argName =
- [argument attributeForName: @"name"].stringValue;
-
- if (argumentIndex++ > 0)
- [_impl writeString: @", "];
-
- [_impl writeString: argName];
- }
-
- [_impl writeFormat: @");\n"
- @"#elif defined(OF_MORPHOS)\n"
- @"\t__asm__ __volatile__ (\n"
- @"\t \"mr\t\t%%%%r12, %%0\"\n"
- @"\t :: \"r\"(%@) : \"r12\"\n"
- @"\t);\n"
- @"\n"
- @"\t",
- libBase, libBase];
-
- if (![returnType isEqual: @"void"])
- [_impl writeString: @"return "];
-
- [_impl writeString: @"__extension__ (("];
- [_impl writeString: returnType];
- if (![returnType hasSuffix: @"*"])
- [_impl writeString: @" "];
- [_impl writeString: @"(*)("];
-
- argumentIndex = 0;
- for (OFXMLElement *argument in arguments) {
- OFString *argType =
- [argument attributeForName: @"type"].stringValue;
-
- if (argumentIndex++ > 0)
- [_impl writeString: @", "];
-
- [_impl writeString: argType];
- }
-
- [_impl writeFormat: @"))*(void **)(((uintptr_t)%@) - %zu))(",
- libBase, 28 + funcIndex * 6];
-
- argumentIndex = 0;
- for (OFXMLElement *argument in
- [function elementsForName: @"argument"]) {
- OFString *argName =
- [argument attributeForName: @"name"].stringValue;
-
- if (argumentIndex++ > 0)
- [_impl writeString: @", "];
-
- [_impl writeString: argName];
- }
-
- [_impl writeString: @");\n"
- @"#endif\n"];
-
- if ([function attributeForName: @"noreturn"] != nil)
- [_impl writeString: @"\n\tOF_UNREACHABLE\n"];
-
- [_impl writeString: @"}\n"];
-
- if (++funcIndex < functions.count)
- [_impl writeString: @"\n"];
- }
-}
-@end
DELETED generators/library/Makefile
Index: generators/library/Makefile
==================================================================
--- generators/library/Makefile
+++ /dev/null
@@ -1,75 +0,0 @@
-include ../../extra.mk
-
-PROG_NOINST = gen_libraries${PROG_SUFFIX}
-SRCS = FuncArrayGenerator.m \
- GlueGenerator.m \
- LibraryGenerator.m \
- LinkLibGenerator.m
-
-include ../../buildsys.mk
-
-.PHONY: run
-run: all
- rm -f libobjfw.so.${OBJFW_LIB_MAJOR}
- rm -f libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}
- rm -f objfw${OBJFW_LIB_MAJOR}.dll libobjfw.${OBJFW_LIB_MAJOR}.dylib
- rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR}
- rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}
- rm -f objfwrt${OBJFWRT_LIB_MAJOR}.dll
- rm -f libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib
- rm -f ${OBJFWRT_AMIGA_LIB}
- if test -f ../../src/libobjfw.so; then \
- ${LN_S} ../../src/libobjfw.so libobjfw.so.${OBJFW_LIB_MAJOR}; \
- ${LN_S} ../../src/libobjfw.so \
- libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \
- elif test -f ../../src/libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; then \
- ${LN_S} ../../src/libobjfw.so.${OBJFW_LIB_MAJOR_MINOR} \
- libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \
- fi
- if test -f ../../src/objfw${OBJFW_LIB_MAJOR}.dll; then \
- ${LN_S} ../../src/objfw${OBJFW_LIB_MAJOR}.dll \
- objfw${OBJFW_LIB_MAJOR}.dll; \
- fi
- if test -f ../../src/libobjfw.dylib; then \
- ${LN_S} ../../src/libobjfw.dylib \
- libobjfw.${OBJFW_LIB_MAJOR}.dylib; \
- fi
- if test -f ../../src/runtime/libobjfwrt.so; then \
- ${LN_S} ../../src/runtime/libobjfwrt.so \
- libobjfwrt.so.${OBJFWRT_LIB_MAJOR}; \
- ${LN_S} ../../src/runtime/libobjfwrt.so \
- libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \
- elif test -f ../../src/runtime/libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; then \
- ${LN_S} ../../src/runtime/libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR} libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \
- fi
- if test -f ../../src/runtime/objfwrt${OBJFWRT_LIB_MAJOR}.dll; then \
- ${LN_S} ../../src/runtime/objfwrt${OBJFWRT_LIB_MAJOR}.dll \
- objfwrt${OBJFWRT_LIB_MAJOR}.dll; \
- fi
- if test -f ../../src/runtime/libobjfwrt.dylib; then \
- ${LN_S} ../../src/runtime/libobjfwrt.dylib \
- libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib; \
- fi
- if test -f ../../src/runtime/${OBJFWRT_AMIGA_LIB}; then \
- ${LN_S} ../../src/runtime/${OBJFWRT_AMIGA_LIB} \
- ${OBJFWRT_AMIGA_LIB}; \
- fi
- LD_LIBRARY_PATH=.$${LD_LIBRARY_PATH+:}$$LD_LIBRARY_PATH \
- DYLD_FRAMEWORK_PATH=../../src:../../src/runtime$${DYLD_FRAMEWORK_PATH+:}$$DYLD_FRAMEWORK_PATH \
- DYLD_LIBRARY_PATH=.$${DYLD_LIBRARY_PATH+:}$$DYLD_LIBRARY_PATH \
- LIBRARY_PATH=.$${LIBRARY_PATH+:}$$LIBRARY_PATH \
- ASAN_OPTIONS=allocator_may_return_null=1 \
- ${WRAPPER} ./${PROG_NOINST}; EXIT=$$?; \
- rm -f libobjfw.so.${OBJFW_LIB_MAJOR}; \
- rm -f libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \
- rm -f objfw${OBJFW_LIB_MAJOR}.dll; \
- rm -f libobjfw.${OBJFW_LIB_MAJOR}.dylib; \
- rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR}; \
- rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \
- rm -f objfwrt${OBJFWRT_LIB_MAJOR}.dll; \
- rm -f libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib; \
- exit $$EXIT
-
-CPPFLAGS += -I../../src -I../../src/exceptions -I../../src/runtime -I../..
-LIBS := -L../../src -lobjfw -L../../src/runtime ${RUNTIME_LIBS} ${LIBS}
-LD = ${OBJC}
DELETED generators/library/copyright.h
Index: generators/library/copyright.h
==================================================================
--- generators/library/copyright.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
- *
- * All rights reserved.
- *
- * This file is part of ObjFW. It may be distributed under the terms of the
- * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
- * the packaging of this file.
- *
- * Alternatively, it may be distributed under the terms of the GNU General
- * Public License, either version 2 or 3, which can be found in the file
- * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
- * file.
- */
-
-#import "OFString.h"
-
-#define COPYRIGHT \
- @"/*\n" \
- @" * Copyright (c) 2008-2022 Jonathan Schleifer \n" \
- @" *\n" \
- @" * All rights reserved.\n" \
- @" *\n" \
- @" * This file is part of ObjFW. It may be distributed under the terms " \
- @"of the\n" \
- @" * Q Public License 1.0, which can be found in the file LICENSE.QPL " \
- @"included in\n" \
- @" * the packaging of this file.\n" \
- @" *\n" \
- @" * Alternatively, it may be distributed under the terms of the GNU " \
- @"General\n" \
- @" * Public License, either version 2 or 3, which can be found in the " \
- @"file\n" \
- @" * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the " \
- @"packaging of this\n" \
- @" * file.\n" \
- @" */\n" \
- @"\n"
Index: generators/unicode/Makefile
==================================================================
--- generators/unicode/Makefile
+++ generators/unicode/Makefile
@@ -12,11 +12,10 @@
rm -f objfw${OBJFW_LIB_MAJOR}.dll libobjfw.${OBJFW_LIB_MAJOR}.dylib
rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR}
rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}
rm -f objfwrt${OBJFWRT_LIB_MAJOR}.dll
rm -f libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib
- rm -f ${OBJFWRT_AMIGA_LIB}
if test -f ../../src/libobjfw.so; then \
${LN_S} ../../src/libobjfw.so libobjfw.so.${OBJFW_LIB_MAJOR}; \
${LN_S} ../../src/libobjfw.so \
libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \
elif test -f ../../src/libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; then \
@@ -45,14 +44,10 @@
fi
if test -f ../../src/runtime/libobjfwrt.dylib; then \
${LN_S} ../../src/runtime/libobjfwrt.dylib \
libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib; \
fi
- if test -f ../../src/runtime/${OBJFWRT_AMIGA_LIB}; then \
- ${LN_S} ../../src/runtime/${OBJFWRT_AMIGA_LIB} \
- ${OBJFWRT_AMIGA_LIB}; \
- fi
LD_LIBRARY_PATH=.$${LD_LIBRARY_PATH+:}$$LD_LIBRARY_PATH \
DYLD_FRAMEWORK_PATH=../../src:../../src/runtime$${DYLD_FRAMEWORK_PATH+:}$$DYLD_FRAMEWORK_PATH \
DYLD_LIBRARY_PATH=.$${DYLD_LIBRARY_PATH+:}$$DYLD_LIBRARY_PATH \
LIBRARY_PATH=.$${LIBRARY_PATH+:}$$LIBRARY_PATH \
ASAN_OPTIONS=allocator_may_return_null=1 \
Index: generators/unicode/TableGenerator.h
==================================================================
--- generators/unicode/TableGenerator.h
+++ generators/unicode/TableGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -24,32 +24,25 @@
OFHTTPClient *_HTTPClient;
OFUnichar _uppercaseTable[0x110000];
OFUnichar _lowercaseTable[0x110000];
OFUnichar _titlecaseTable[0x110000];
OFUnichar _caseFoldingTable[0x110000];
- OFString *_decompositionTable[0x110000];
- OFString *_decompositionCompatTable[0x110000];
char _uppercaseTableUsed[0x1100];
char _lowercaseTableUsed[0x1100];
char _titlecaseTableUsed[0x1100];
char _caseFoldingTableUsed[0x1100];
- char _decompositionTableUsed[0x1100];
- char _decompositionCompatTableUsed[0x1100];
size_t _uppercaseTableSize;
size_t _lowercaseTableSize;
size_t _titlecaseTableSize;
size_t _caseFoldingTableSize;
- size_t _decompositionTableSize;
- size_t _decompositionCompatTableSize;
enum {
stateUnicodeData,
stateCaseFolding
} _state;
}
- (void)parseUnicodeData: (OFHTTPResponse *)response;
- (void)parseCaseFolding: (OFHTTPResponse *)response;
-- (void)applyDecompositionRecursivelyForTable: (OFString *[0x110000])table;
- (void)writeFiles;
- (void)writeTablesToFile: (OFString *)path;
- (void)writeHeaderToFile: (OFString *)path;
@end
Index: generators/unicode/TableGenerator.m
==================================================================
--- generators/unicode/TableGenerator.m
+++ generators/unicode/TableGenerator.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -15,28 +15,28 @@
#include "config.h"
#include
-#import "OFString.h"
+#import "OFApplication.h"
#import "OFArray.h"
-#import "OFApplication.h"
-#import "OFURI.h"
+#import "OFFile.h"
+#import "OFHTTPClient.h"
#import "OFHTTPRequest.h"
#import "OFHTTPResponse.h"
-#import "OFHTTPClient.h"
-#import "OFFile.h"
+#import "OFIRI.h"
#import "OFStdIOStream.h"
+#import "OFString.h"
#import "OFOutOfRangeException.h"
#import "TableGenerator.h"
#import "copyright.h"
-static OFString *const unicodeDataURI =
+static OFString *const unicodeDataIRI =
@"http://www.unicode.org/Public/UNIDATA/UnicodeData.txt";
-static OFString *const caseFoldingURI =
+static OFString *const caseFoldingIRI =
@"http://www.unicode.org/Public/UNIDATA/CaseFolding.txt";
OF_APPLICATION_DELEGATE(TableGenerator)
@implementation TableGenerator
@@ -50,28 +50,26 @@
_uppercaseTableSize = SIZE_MAX;
_lowercaseTableSize = SIZE_MAX;
_titlecaseTableSize = SIZE_MAX;
_caseFoldingTableSize = SIZE_MAX;
- _decompositionTableSize = SIZE_MAX;
- _decompositionCompatTableSize = SIZE_MAX;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
-- (void)applicationDidFinishLaunching
+- (void)applicationDidFinishLaunching: (OFNotification *)notification
{
OFHTTPRequest *request;
[OFStdOut writeString: @"Downloading UnicodeData.txt…"];
_state = stateUnicodeData;
- request = [OFHTTPRequest requestWithURI:
- [OFURI URIWithString: unicodeDataURI]];
+ request = [OFHTTPRequest requestWithIRI:
+ [OFIRI IRIWithString: unicodeDataIRI]];
[_HTTPClient asyncPerformRequest: request];
}
- (void)client: (OFHTTPClient *)client
didPerformRequest: (OFHTTPRequest *)request
@@ -127,51 +125,19 @@
_lowercaseTable[codePoint] = (OFUnichar)[[components
objectAtIndex: 13] unsignedLongLongValueWithBase: 16];
_titlecaseTable[codePoint] = (OFUnichar)[[components
objectAtIndex: 14] unsignedLongLongValueWithBase: 16];
- if ([[components objectAtIndex: 5] length] > 0) {
- OFArray *decomposed = [[components objectAtIndex: 5]
- componentsSeparatedByString: @" "];
- bool compat = false;
- OFMutableString *string;
-
- if ([decomposed.firstObject hasPrefix: @"<"]) {
- decomposed = [decomposed objectsInRange:
- OFMakeRange(1, decomposed.count - 1)];
- compat = true;
- }
-
- string = [OFMutableString string];
-
- for (OFString *character in decomposed) {
- OFUnichar unichar = (OFUnichar)[character
- unsignedLongLongValueWithBase: 16];
-
- [string appendCharacters: &unichar
- length: 1];
- }
-
- [string makeImmutable];
-
- if (!compat)
- _decompositionTable[codePoint] = [string copy];
- _decompositionCompatTable[codePoint] = [string copy];
- }
-
objc_autoreleasePoolPop(pool2);
}
- [self applyDecompositionRecursivelyForTable: _decompositionTable];
- [self applyDecompositionRecursivelyForTable: _decompositionCompatTable];
-
[OFStdOut writeLine: @" done"];
[OFStdOut writeString: @"Downloading CaseFolding.txt…"];
_state = stateCaseFolding;
- request = [OFHTTPRequest requestWithURI:
- [OFURI URIWithString: caseFoldingURI]];
+ request = [OFHTTPRequest requestWithIRI:
+ [OFIRI IRIWithString: caseFoldingIRI]];
[_HTTPClient asyncPerformRequest: request];
}
- (void)parseCaseFolding: (OFHTTPResponse *)response
{
@@ -214,73 +180,21 @@
[OFStdOut writeLine: @" done"];
[self writeFiles];
}
-- (void)applyDecompositionRecursivelyForTable: (OFString *[0x110000])table
-{
- bool done;
-
- do {
- done = true;
-
- for (OFUnichar i = 0; i < 0x110000; i++) {
- void *pool;
- const OFUnichar *characters;
- size_t length;
- OFMutableString *replacement;
- bool changed = false;
-
- if (table[i] == nil)
- continue;
-
- pool = objc_autoreleasePoolPush();
- characters = table[i].characters;
- length = table[i].length;
- replacement = [OFMutableString string];
-
- for (size_t j = 0; j < length; j++) {
- if (characters[j] > 0x10FFFF)
- @throw [OFOutOfRangeException
- exception];
-
- if (table[characters[j]] == nil)
- [replacement
- appendCharacters: &characters[j]
- length: 1];
- else {
- [replacement
- appendString: table[characters[j]]];
- changed = true;
- }
- }
-
- [replacement makeImmutable];
-
- if (changed) {
- [table[i] release];
- table[i] = [replacement copy];
-
- done = false;
- }
-
- objc_autoreleasePoolPop(pool);
- }
- } while (!done);
-}
-
- (void)writeFiles
{
- OFURI *URI;
+ OFIRI *IRI;
[OFStdOut writeString: @"Writing files…"];
- URI = [OFURI fileURIWithPath: @"../../src/unicode.m"];
- [self writeTablesToFile: URI.fileSystemRepresentation];
+ IRI = [OFIRI fileIRIWithPath: @"../../src/unicode.m"];
+ [self writeTablesToFile: IRI.fileSystemRepresentation];
- URI = [OFURI fileURIWithPath: @"../../src/unicode.h"];
- [self writeHeaderToFile: URI.fileSystemRepresentation];
+ IRI = [OFIRI fileIRIWithPath: @"../../src/unicode.h"];
+ [self writeHeaderToFile: IRI.fileSystemRepresentation];
[OFStdOut writeLine: @" done"];
[OFApplication terminate];
}
@@ -294,11 +208,10 @@
[file writeString: COPYRIGHT
@"#include \"config.h\"\n"
@"\n"
@"#import \"OFString.h\"\n\n"
@"static const OFUnichar emptyPage[0x100] = { 0 };\n"
- @"static const char *emptyDecompositionPage[0x100] = { NULL };\n"
@"\n"];
/* Write uppercasePage%u */
for (OFUnichar i = 0; i < 0x110000; i += 0x100) {
bool isEmpty = true;
@@ -455,139 +368,18 @@
objc_autoreleasePoolPop(pool2);
}
}
- /* Write decompositionPage%u */
- for (OFUnichar i = 0; i < 0x110000; i += 0x100) {
- bool isEmpty = true;
-
- for (OFUnichar j = i; j < i + 0x100; j++) {
- if (_decompositionTable[j] != nil) {
- isEmpty = false;
- _decompositionTableSize = i >> 8;
- _decompositionTableUsed[
- _decompositionTableSize] = 1;
- break;
- }
- }
-
- if (!isEmpty) {
- void *pool2 = objc_autoreleasePoolPush();
-
- [file writeFormat: @"static const char *const "
- @"decompositionPage%u[0x100] = {\n",
- i >> 8];
-
- for (OFUnichar j = i; j < i + 0x100; j++) {
- if ((j - i) % 2 == 0)
- [file writeString: @"\t"];
- else
- [file writeString: @" "];
-
- if (_decompositionTable[j] != nil) {
- const char *UTF8String =
- _decompositionTable[j].UTF8String;
- size_t length = _decompositionTable[j]
- .UTF8StringLength;
-
- [file writeString: @"\""];
-
- for (size_t k = 0; k < length; k++)
- [file writeFormat:
- @"\\x%02X",
- (uint8_t)UTF8String[k]];
-
- [file writeString: @"\","];
- } else
- [file writeString: @"NULL,"];
-
- if ((j - i) % 2 == 1)
- [file writeString: @"\n"];
- }
-
- [file writeString: @"};\n\n"];
-
- objc_autoreleasePoolPop(pool2);
- }
- }
-
- /* Write decompCompatPage%u if it does NOT match decompositionPage%u */
- for (OFUnichar i = 0; i < 0x110000; i += 0x100) {
- bool isEmpty = true;
-
- for (OFUnichar j = i; j < i + 0x100; j++) {
- if (_decompositionCompatTable[j] != 0) {
- /*
- * We bulk-compare pointers via memcmp here.
- * This is safe, as we always set the same
- * pointer in both tables if both are the same.
- */
- isEmpty = !memcmp(_decompositionTable + i,
- _decompositionCompatTable + i,
- 256 * sizeof(const char *));
- _decompositionCompatTableSize = i >> 8;
- _decompositionCompatTableUsed[
- _decompositionCompatTableSize] =
- (isEmpty ? 2 : 1);
-
- break;
- }
- }
-
- if (!isEmpty) {
- void *pool2 = objc_autoreleasePoolPush();
-
- [file writeFormat: @"static const char *const "
- @"decompCompatPage%u[0x100] = {\n",
- i >> 8];
-
- for (OFUnichar j = i; j < i + 0x100; j++) {
- if ((j - i) % 2 == 0)
- [file writeString: @"\t"];
- else
- [file writeString: @" "];
-
- if (_decompositionCompatTable[j] != nil) {
- const char *UTF8String =
- _decompositionCompatTable[j]
- .UTF8String;
- size_t length =
- _decompositionCompatTable[j]
- .UTF8StringLength;
-
- [file writeString: @"\""];
-
- for (size_t k = 0; k < length; k++)
- [file writeFormat:
- @"\\x%02X",
- (uint8_t)UTF8String[k]];
-
- [file writeString: @"\","];
- } else
- [file writeString: @"NULL,"];
-
- if ((j - i) % 2 == 1)
- [file writeString: @"\n"];
- }
-
- [file writeString: @"};\n\n"];
-
- objc_autoreleasePoolPop(pool2);
- }
- }
-
/*
* Those are currently set to the last index.
* But from now on, we need the size.
*/
_uppercaseTableSize++;
_lowercaseTableSize++;
_titlecaseTableSize++;
_caseFoldingTableSize++;
- _decompositionTableSize++;
- _decompositionCompatTableSize++;
/* Write OFUnicodeUppercaseTable */
[file writeFormat: @"const OFUnichar *const "
@"OFUnicodeUppercaseTable[0x%X] = {\n\t",
_uppercaseTableSize];
@@ -673,55 +465,10 @@
}
}
[file writeString: @"\n};\n\n"];
- /* Write OFUnicodeDecompositionTable */
- [file writeFormat: @"const char *const "
- @"*OFUnicodeDecompositionTable[0x%X] = {\n\t",
- _decompositionTableSize];
-
- for (OFUnichar i = 0; i < _decompositionTableSize; i++) {
- if (_decompositionTableUsed[i])
- [file writeFormat: @"decompositionPage%u", i];
- else
- [file writeString: @"emptyDecompositionPage"];
-
- if (i + 1 < _decompositionTableSize) {
- if ((i + 1) % 3 == 0)
- [file writeString: @",\n\t"];
- else
- [file writeString: @", "];
- }
- }
-
- [file writeString: @"\n};\n\n"];
-
- /* Write OFUnicodeDecompositionCompatTable */
- [file writeFormat: @"const char *const "
- @"*OFUnicodeDecompositionCompatTable[0x%X] = {"
- @"\n\t",
- _decompositionCompatTableSize];
-
- for (OFUnichar i = 0; i < _decompositionCompatTableSize; i++) {
- if (_decompositionCompatTableUsed[i] == 1)
- [file writeFormat: @"decompCompatPage%u", i];
- else if (_decompositionCompatTableUsed[i] == 2)
- [file writeFormat: @"decompositionPage%u", i];
- else
- [file writeString: @"emptyDecompositionPage"];
-
- if (i + 1 < _decompositionCompatTableSize) {
- if ((i + 1) % 3 == 0)
- [file writeString: @",\n\t"];
- else
- [file writeString: @", "];
- }
- }
-
- [file writeString: @"\n};\n"];
-
objc_autoreleasePoolPop(pool);
}
- (void)writeHeaderToFile: (OFString *)path
{
@@ -734,16 +481,13 @@
[file writeFormat:
@"#define OFUnicodeUppercaseTableSize 0x%X\n"
@"#define OFUnicodeLowercaseTableSize 0x%X\n"
@"#define OFUnicodeTitlecaseTableSize 0x%X\n"
- @"#define OFUnicodeCaseFoldingTableSize 0x%X\n"
- @"#define OFUnicodeDecompositionTableSize 0x%X\n"
- @"#define OFUnicodeDecompositionCompatTableSize 0x%X\n\n",
+ @"#define OFUnicodeCaseFoldingTableSize 0x%X\n\n",
_uppercaseTableSize, _lowercaseTableSize, _titlecaseTableSize,
- _caseFoldingTableSize, _decompositionTableSize,
- _decompositionCompatTableSize];
+ _caseFoldingTableSize];
[file writeString:
@"#ifdef __cplusplus\n"
@"extern \"C\" {\n"
@"#endif\n"
@@ -753,18 +497,12 @@
@" OFUnicodeLowercaseTable[OFUnicodeLowercaseTableSize];\n"
@"extern const OFUnichar *const _Nonnull\n"
@" OFUnicodeTitlecaseTable[OFUnicodeTitlecaseTableSize];\n"
@"extern const OFUnichar *const _Nonnull\n"
@" OFUnicodeCaseFoldingTable[OFUnicodeCaseFoldingTableSize];\n"
- @"extern const char *const _Nullable *const _Nonnull\n"
- @" OFUnicodeDecompositionTable["
- @"OFUnicodeDecompositionTableSize];\n"
- @"extern const char *const _Nullable *const _Nonnull\n"
- @" OFUnicodeDecompositionCompatTable["
- @"OFUnicodeDecompositionCompatTableSize];\n"
@"#ifdef __cplusplus\n"
@"}\n"
@"#endif\n"];
objc_autoreleasePoolPop(pool);
}
@end
Index: generators/unicode/copyright.h
==================================================================
--- generators/unicode/copyright.h
+++ generators/unicode/copyright.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -15,11 +15,11 @@
#import "OFString.h"
#define COPYRIGHT \
@"/*\n" \
- @" * Copyright (c) 2008-2022 Jonathan Schleifer \n" \
+ @" * Copyright (c) 2008-2024 Jonathan Schleifer \n" \
@" *\n" \
@" * All rights reserved.\n" \
@" *\n" \
@" * This file is part of ObjFW. It may be distributed under the terms " \
@"of the\n" \
ADDED misc/keys.asc
Index: misc/keys.asc
==================================================================
--- /dev/null
+++ misc/keys.asc
@@ -0,0 +1,196 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mDMEWtyz7hYJKwYBBAHaRw8BAQdAsw2r74WiB54Nr73sY2sxBLu0RUges2iPeBor
+1Wc6Cre0O0pvbmF0aGFuIFNjaGxlaWZlciAoQ29tbWl0IFNpZ25pbmcgS2V5IDIw
+MTgpIDxqc0BoZWFwLnpvbmU+iJkEExYKAEECGwMHCwoNDAgLBwYVCgkICwMFFgMC
+AQACHgECF4AWIQTGxY7C74kJHg4TzVjYOna/43Y0XgUCXESzpAUJAWlRNgAKCRDY
+Ona/43Y0XhA1AP4nIiBUL2nMtkDJSbSb0/kbyIoTNhRXtlI4crYIqfs07gD+NMdH
+HzMnGtHkpaX7GAqVTeTiThZUnTGNMwnV9aerQQe0OkpvbmF0aGFuIFNjaGxlaWZl
+ciAoT2JqRlcgU2lnbmluZyBLZXkgMjAxOCkgPGpzQGhlYXAuem9uZT6ImQQTFgoA
+QQIbAwcLCg0MCAsHBhUKCQgLAwUWAwIBAAIeAQIXgBYhBMbFjsLviQkeDhPNWNg6
+dr/jdjReBQJcRLOoBQkBaVE2AAoJENg6dr/jdjReDVoBANvkIYUTLemog3UhjZYh
+Zdvq9Axd63L2lnpzm+For3tNAP9GmJwbq/oi8E0mAwesbvQYY/R4NOOKIdV7rkVj
+JzoeCJgzBFxA+ccWCSsGAQQB2kcPAQEHQIe0NK4nnagyINx6Z2DJt4lUzv7a7e6x
+PLifEvo1iQVptDpKb25hdGhhbiBTY2hsZWlmZXIgKE9iakZXIFNpZ25pbmcgS2V5
+IDIwMTkpIDxqc0BoZWFwLnpvbmU+iJkEExYKAEEWIQQtKx7sQXauZ6pvl2B50hGJ
+otRwjQUCXED55wIbAwUJAeEzgAcLCg0MCAsHBhUKCQgLAwUWAwIBAAIeAQIXgAAK
+CRB50hGJotRwjeuIAP9wQ8r+13S0ZHPmOkeVQNqpVdvszisfszQKNRrkKrS7fgEA
+AF4eI4IXb13x5hHvzYn2DMMe2ugx6LoCdzYcVlvFFQ60O0pvbmF0aGFuIFNjaGxl
+aWZlciAoQ29tbWl0IFNpZ25pbmcgS2V5IDIwMTkpIDxqc0BoZWFwLnpvbmU+iJkE
+ExYKAEEWIQQtKx7sQXauZ6pvl2B50hGJotRwjQUCXED5xwIbAwUJAeEzgAcLCg0M
+CAsHBhUKCQgLAwUWAwIBAAIeAQIXgAAKCRB50hGJotRwjXTdAP4oYHIg5+LBhfO+
+SNSQl008KH35KmyO4xtZPKfcbWjXcgD/dWVqZDjUYkCs/0oprdJDZPRBIB5QQhjc
+1un38+eCiAeYMwReJFsBFgkrBgEEAdpHDwEBB0CjTf7buaAeNxgLpbv9/j4UgcjJ
+Z97STkAaM7Xac+Dg1rQ3Sm9uYXRoYW4gU2NobGVpZmVyIChPYmpGVyBTaWduaW5n
+IEtleSAyMDIwKSA8anNAbmlsLmltPoiZBBMWCgBBFiEEMOaUj6yAQrWMtKlu4rzO
+azXhr4sFAl4kWykCGwMFCQHhM4AHCwoNDAgLBwYVCgkICwMFFgMCAQACHgECF4AA
+CgkQ4rzOazXhr4tQAgD+P45Nx/YGk2Q/JzBz+cbsdtcha7IehgXulltd3xLjdwsB
+AMoefVWwHOJa7q10ZRxDN48kDGD+kiqvSdIvKRGuLmMAiQIzBBMBCgAdFiEEbR7C
+JpvAtUWci6kgz9q0H4KSzu4FAl6KMHcACgkQz9q0H4KSzu7HLBAAo2it0ci2HuJT
+1+x1n74dBI5nwKak15OoABW37vxt10gMdm1wo9hq0cJorXdQmE07pMWpMmz883Yg
+ayqTXyEJJydVqq3rgR1zcEKOGpiJT6azRfGxcvsNh8bMto9dC6cVVmknydyvNTg7
+3TpofPmRlH8W8gt8w55EiO3Lk4RJODzGhCOrDxbR1o9rF39fUHj+g3NB7grK/TTt
+dZvomOS+mcM+pANYivOTmMc5mn0mEVua3F6wRvUck8ij2JFTvJ5GV3xie6JIDa2h
+l/hM2BLx2XRrwjnD+kig/CjpoFEP8bzc+epHb6ODAt2SQ5i4Zx30TFWiVeeljX1Q
+zFq5pfJr3nbHQNhkzsu3uWXfqUu1M6mBadzYmLYLDgVFLFKdwhBgbvInr39UAtwE
+Yl70NoqgVswPzWSkAyrLWs0+2XUXZlyhFxNaOqheWE7VQv/DPYDBPXrim3f5Alv2
+PtQJ2BXDvl1PyDg6Ckg6Pe6XoVKPJwMYsiWZOrsnRRJzeQWa1zFsVWX+CYINPiEY
+v4Ls2OFGZj67tzNU8Wf2EFbNmm/V82sXrPeu0iqcJ99aaxZw+tk+h5WS0BiXceZ9
+J6dRKo2qHJJAq0FJnAt+6NRam1KYAknd9y6g5S2bRqiI1wJminmksbSLQ5wmeunl
+EynylSIJx+UbXBYVbvmpLWZFFRUKBM60OEpvbmF0aGFuIFNjaGxlaWZlciAoQ29t
+bWl0IFNpZ25pbmcgS2V5IDIwMjApIDxqc0BuaWwuaW0+iJkEExYKAEEWIQQw5pSP
+rIBCtYy0qW7ivM5rNeGviwUCXiRbAQIbAwUJAeEzgAcLCg0MCAsHBhUKCQgLAwUW
+AwIBAAIeAQIXgAAKCRDivM5rNeGvi4HuAPsEi38R7E8716m2ua2KvFB3CClSCsVT
+tZjbIQBEHzQ/iAD/UEZtjaNUW/Mf8vFExbnqFes0dwF0p6PzQ0GLix12JQKJAjME
+EwEKAB0WIQRtHsImm8C1RZyLqSDP2rQfgpLO7gUCXoowgQAKCRDP2rQfgpLO7jtA
+D/403WskqoPnw+woWaeCPZcTU1LQ/o5baUUxbQDWTAUNav3hzDxBDQ1yPacZhwBu
+ea6SNnrEZwc5wd5TPozh9sXday3vqDe6R9/AT+MokxJT3EWptTXmcawRSyDdFNZr
+V8KJqfDjRNkv9Iqxsjjp9fD5Vw8zVC/KIr0JOq2oxzjU+Wukk94NhSOU2LDRaQLV
+8vMpXZRpVJh30+7rq46sTzhZqB5AsTdBykFOsTl9LRmRJXnLjdK/4U7uhoj5ntfR
+QzPUG3mmbHf5RlGoQIFq2Byop0MiGVWjHI93C5OU7fyjfnARnENOqCgUxs+yXauY
+J+wngqdJroGEo/5kgbJxpTksuK9zQ3DDtE1p5y48qct0gvw3hYz1UGvpEQ2/Prcy
+1q0Nc4hzQ2zrG9jO5971KW2alUT5lrILos17ZJlN5pI8NHhat7T9RX82ziB1fQKG
+OzbSjxT8gXasy9gbMh8w9zm1prZ1+VRQT8JGLYPHM6mZID20F1q5cRLT41UyTjSe
+zzStci/zo/dQKFKaTX9KesTSwVS9Zlo7yldUgH+lWyaSjF9VCrjyNI3YbEJ+/Fqt
+rwxAp8kzFviOd7R5F4zAJBRwgfQNI46v9F3X9KpaTeuuJhm4KvyqPRE/0G0ond8G
+yJYePoL3jMhfl50163cO69TGXyJmvKwATEa1xRU8n9lE9bg4BF4kWwESCisGAQQB
+l1UBBQEBB0Cc6UB0PD0kppdYyeJV3uXSuXk7stS6si393JPKFX2wMgMBCAeIfgQY
+FgoAJhYhBDDmlI+sgEK1jLSpbuK8zms14a+LBQJeJFsBAhsMBQkB4TOAAAoJEOK8
+zms14a+L7UoBAJkNXZsY3zHeiSQ23YeaABQUTtpjWb0o6xljq3PXR/hEAP44Rvf3
+hTkPPDuMCJelOxzkvr83upYCIyIpP5HpzqFWBpkCDQReih1/ARAAuXxV9zzoO2UY
+YlXdNlNSxu9iJKH/RySUzIPtCWVxUfsI1NOo2ByhxxGWpATRye61Lm6cAU+tvEXj
+saKpTi4i9WSy6m6xuLLqQrpDrbVOlazzM1MRQcqGK2wFPtNKV9qz+oOdPXK9a2Rl
+gI2iwQh6AjCjq8oa3T1MtDF4D3uGBE+Fn9g+gryAf/TZ8gKWyYd8UZwtrlFLC7nq
+8gSj2hFiRYTAPGy8GhcdyKvD0cP2xiFlpJmzCn5B+i9a5i3EJDcbfcc0BSyqxkz2
+BY8bymw4kTt5e8Bmf4KdzK5OE4w3PFPiMq+Z3LVohQCI2CRh1wGw6lzntU5nqJ0c
+eD2YV9C8dHwVEN1Vu2M5mXkoe9q4iLWETppxchrQWVAWZWCOeElNxdOrW/uhxpdX
+RmzTMuCIHolB4VhszS+Wr3Uj98DWa9n/cPZpvRdVdXmy95G9ocp+uBozQEjdmLOm
+rqPUUbE/WLUO/tRFqp6w6QVfh81G5omLo5VWlxCODK8OjOR4/rfCH28I75bjrm9H
+pIYtSasVG1/XSV+ilv3PCwadftz8BR5iE0JJtk8NtI1jOvPrIe5d9hJ9109xk/r9
+one51VLFFQDsNJexCswjD25xgpqnhZBd0yOtcE9+6hiENLZ0DFrKZSJjNC7xY/ts
+K9usWwm3CBx2VFi+GpjL04Apo9ooPA0AEQEAAbQeSm9uYXRoYW4gU2NobGVpZmVy
+IDxqc0BuaWwuaW0+iQJbBBMBCgBFAhsDAh4BAheACAsJCg0MCAsHBhUKCQgLAwUW
+AwIBAAIZARYhBG0ewiabwLVFnIupIM/atB+Cks7uBQJj6WbtBQkJIbBuAAoJEM/a
+tB+Cks7u1qUP+gLBceY67YURSNLLCO+L537Xukf2eYlzJzUvBI1nYv8C94dQcmSa
+sBcAsg2ELfKE6GD1/7VwHQHwclpa3kSX55V6+Ep3VUSR7+2fqz4Ahr10FeOpjS5C
+Ir51C44mAjeTkkmPIqhOWSoZyg2RxUZOAUZyFqpLDPFGrRTGmuEFnP1tXOAn3TR2
+xllK9iAbB9ZcJ+MHEz+rVW5yj3XY8/QW1kcsWIA6qV7eHPP4Y8tEIoefvsU5g188
+uHIhxWhB0Xd52VMxd32yiKRgPp9z+6e4PQ+XULv5oGiqR17XKMtMIfAe6kiDYXWT
+HpqOHnOekVPuqTsjAFttgKeCEzbyit6HIFlqoXjoj23eTFQEi2qiSLCRDm2uGZJI
+hAL5YeHPaNa82dg6YNCGD8FFSwP+hhXMaQ7zB2jB8smX9A9C+nHCKCFF4ba1RRNq
+sFRziE2YuY+KX6bQKz6AZ7OxB16YAx75e4J/H/Si8bqm+1EKc6Xpg7uVjYYNH+dr
+j4qvNsTf4tLr3FAm5tSRCdZkSlilS+565J4PInBVjcLnlRAxh1X1RJGVuFuueVdM
+6joGmsPDnwdv8NOvy+4LvBHWkPLm3FVZE9fyDem+0SDooTpvFEuSRfna8agJB5kH
+zA532hu1dEX/XJMCCJT4RBYy7KOVXqcjrLn/TqRiBZKPK4QbmC/JjdKJiQEiBBAB
+CAAMBQJj6WgVBQMAEnUAAAoJEJcQuJvKV618c0IIAKLZVwWsgQWBjtjaIsXKUhoo
+5HBwNpsNCnWAyUj0ayspkvM+hh5fa70s4Mj4oRdCd44X1iDHQw2bV6PVA+TvqkY2
+NV7iL30Vqpyt50qreUz9qCdEittaFIkRNk2qkQB89cKTrrLDu2k80NZdV4sAAJKu
+XFUOEecZVv5D3gYSKDQJ0lTUzSyS4cC5wdSpeEFRTVXpOQOI32mRM9BxmjtDSBct
+fnHSWYoE+IoC+OPqDvbbP4TRz3UYjAz5lbLSL5BnlHxZDG2NryH9tUn+/wnJd41m
+weKZidDO/AUQ9eKKaIsgzCXAjrLjKcgBBANn1yXl+YAr7J8GFdiGkVznYhGjmAW0
+IkpvbmF0aGFuIFNjaGxlaWZlciA8anNATmV0QlNELm9yZz6JAlgEEwEKAEICGwMI
+CwkKDQwICwcGFQoJCAsDBRYDAgEAAh4BAheAFiEEbR7CJpvAtUWci6kgz9q0H4KS
+zu4FAmPpZvIFCQkhsG4ACgkQz9q0H4KSzu4/nRAAk5+6zavoleNtZ0/l9xs0lwwq
+sENTfdWqp19YvkiQTWz0gDvRoxKbXHI4HK25th0rBu77ryQYjKrRjXhEZrNq2k6f
+hTBwJ1sbsDceksaHRlUlVgn112gf6B/iKG3JpLxuFxuMS4ndN9z7H67t2RWDY/+M
+qSgaNFWXQtfmtC3tfV8e5etZScVO8w+0Wed6MjGjA76crgVWXm2hGCokEk7+0uNd
+VmFC+cPEBMixgAHqZvM+Gu3pZvHgV50Ybczalx/6KV2W37MsaX6iRUCCpnnoAAxN
+pWo2Z2LIBVaoO9nuzO8pgF8dRdxwq3Px/RpseHtEUY4v1/aylB4z1joI7sWPqXOR
+3QlRmCd2O36kCiLIvm9OQ5tmjmW9T+t/gcCzq5pHDNIx8D50urqnUH+WU/WaT5fp
+uM6VifBpSZslTuRavc6kxa7kuGCrsBtVOzlMCxSVAqSgMMm4vVxJm20pYIItHHTZ
+TXEehnLEst/EdEAmLmHO2Qch/qUh2i0w5+4pwjY1pIOVP8Si3xbxtoN6PIM/UBEP
+fBQGB4NzljQwISdUUSGiWn7pcun350IsCjnC2c+tJQ/lHjhrJjZ+aMAi7OSV6g9P
+pjFrz+z9UmTP0QUeBSNGBqAWgvC4okGgFr4cf9H01FbZPNkWIfZYPZ1Nv3apxNOx
+lpzSHcURnFhXPJDlqNC0IkpvbmF0aGFuIFNjaGxlaWZlciA8anNAcGtnc3JjLm9y
+Zz6JAlgEEwEKAEICGwMICwkKDQwICwcGFQoJCAsDBRYDAgEAAh4BAheAFiEEbR7C
+JpvAtUWci6kgz9q0H4KSzu4FAmPpZvcFCQkhsG4ACgkQz9q0H4KSzu4TrxAAnWBr
+gJnU96KbYRS7KkpUzeLeaLrHK5LIhaJ7rVxVrOo+x5Ey2NjGJKoTxC9UAfITCfO9
+9vsycp3Gb9fJnowieuQ1y1MFCrYLPPLOfNxh4Jc9GZK64DlexrsXvDhx84wgN+el
+rnjuatm9LUJWe5czWKiAnoki/u+SGFVxwOUtND205I4go/8FtY8rZ1P3VEGiXeZq
+hjNOodDoGEGZJwQIycN5YCrweYPwM+p80ZbzkWGB+Ov3lOO+omMf7NQ3LFtueV0J
+Nq7SjmNESYLm1Gg2NFHZp4D12sSUfHTvNVJBr1qCJggQs2mefRB/aKcS4i9Ajmfk
+i7TkEwutDMX6rOCZRppYpS8N6aYoiAOZHQmffk8bdi0RBGVSxR+04IwpYObUbDIZ
+US2exkiaDB0tFeguIlgHU/V+3GWEUDF4AhQLbSYkEwUc65FstULrDCRfegFoUBsY
+9D+qPYnsNOlTRlalR8hZaQlwZLAuZx0kn+YGxs+9z2UhgMExRtCM/3FRpDuiFJGs
+QML2DUArYZeh7JyJy0m9PIt59wg5wnHUyCLop8g1gn6Wh22/R/Le6CEusJsO2qiM
+oE6PSB89g3nhsvUadRpYOP9eZS0aoRgNPLp+qigthgEV9fvSADHtAvsaLYpQ+wjr
+O+Ih57Y2MrU8mPehwqGz17Ur58VcI65qXTkZpni5Ag0EXoodfwEQAPc4JUVqZGxS
+KtipZKGewKuNyqASMq8gNwL7ToSni5cTuQLa9YU+5Zo/BX3OEJkXp+MNN3Y1wFxV
+cPBZsYpBAx3apWhi0Fki+zdPjTmRE7QcFE+UE17OnnFReb93G2ErSiY+BzsfbW/3
+dMjLfLhrVjJktLA9pGMoR483jI6rIVEBa6TikoMo8b790Ulo0xicl6ehFhQVUGN4
+CfovBjCZ9CIX6dmRGaB/FMyOXgXWsx5+UilTgJhRHbJnggw6U1H8lk/WhJzCyLyY
+Tg+YkHx3WwAF37pR6g1XACMQEdumCLxW21ELC5D4aX0QejM8oIDf/xw5mHcgB0xg
+07FmRbyiZheg+CSPgwHWW/K6urw/G04SbYxnk1/kPA66x6Fss3BxTuJOYmEZqklV
+Np2KfJdEiBECftRRWIbZu2zFOMGK1olPIOgsKdJvaATkgeYSxjCu9+o4vY1yGXtz
+BEwBfIUkU2B33QzWLq+I61WeVbqRC6k0SYBKiQK/uQJSVYuEtNJ8pttYxdYkyY+r
+s0yCZHlTlJcYKhAdMi1Gbh2L6WbzsHIHfmdraWqcv7EEuVacjrgerdk3ezOQspC5
+Gfa6pLEmOoF/ctwg/uoGCyhnWBmHiuLdN7F4+z6BHBoqHU1i3z2oUJ3tHDoVnEmh
+jYNOgIs7UgKxXiuczMJT4gpNM35ym32hABEBAAGJAjwEGAEKACYCGwwWIQRtHsIm
+m8C1RZyLqSDP2rQfgpLO7gUCY+lnIwUJCSGwpAAKCRDP2rQfgpLO7oIlD/4oLDMH
+qTzdDIXjM9x5U4ENBeGwUKHEkKeRduXuj0pZTnWTHmdXD3RPbG1EfGJU3PVBudZU
+iEREibNaEYM5VFuDwMw51qw7Ox8j4r+RtP+8AI0zpRdababPP1/A4ap+xwReTWVM
+/CFF3VekqeElgxSjM6luFPNDdwyBNavOLtbrWhmyclw3DLB03ZtS0sPvu0hXTnp4
+nbuWdsPOxGIomb9UF0IplMPm5ChjkZaypKY75P1k5Il+AZFWEi5YB6y8yl1gmOxY
+3pnKCJWcoGsaEoxREqHH/tZAeI299u8aE8Gjl+ZxGunuPDMUd8OSlE8MI3osnWU4
+7rbVueWqJ4CG3OcYJP8Vj1Ygy68R5xBL5ku3ddv5oI2ZIDkqTBFKJQnhWMUX6Trz
+e7US0jSdVFv4fYf3aHDJ0afc9RsKebPgbfN3FWak03zInVqdXRrraa410qz8fKBI
+1CKalErJN7/dpXu3vfJJ2TgYcgAN9N0lY+YFQ834qpDk6KOTYzvIMJASVIJ1gjvl
+iE94hE6FYuHU9DlwYL3/qbOOb6lLIFHxaeQ95ZZR+raPyi1FGVGXV8oZI5f2Uzxo
+LYyioTRjgC0cr9aIK56ZQ5I/npwuEYSL/8oIWdRrYGQT0FFQQAnhhkd61DuPt3GA
+fhsY1fGkPo/YC3yulOJt98FIMg/lRlYfOrxIbLkCDQReiiM/ARAAwIzaby43las5
+ApAWVw4MxCIpdY9S0tKUBgF4koKKkgUQ20KzI395LctZ6TwRSaBp9df/Wi9JtXe3
+bkt46ASjq8CCMggVptq80KyhnVMYDJD8mH+gFjUdlxTgILg1tnYwt01oBIMh8T1c
+EUQ2kcWkDbIRnrrSkVxh+ntu8aqZaF9E9iScPbNO8V5qIGCTfeFti1IUfClQ10Cs
+dANPxVngzttHs7eg+ddwZdiwxb7vxKy1/juqWTNFcHYd4XQ8MIuedXliHpvI5quf
+MbFvOmX6xxxoXTL/efGoA/zCM6/BcM2ul1o/prJTauRuVKawE3mcMpTrubN+usf6
+QEUohxsxCvxVqGcJVAU5286Hv0Kc2jzqcWqEfiyjCJI0vwCzFk3sRbuawlDuC535
+paR23QC/ClSCghMzfRRnN4OpJQjzgc6yOZ3ydqmF5UeqGrgZhrW+O92jBb1XqGFV
+zTOYHvLNJCQ0Cj53fiYpju4Pdf2BWvDo1oSoKbrvSd3DUyXlgN2Ar6t3X2uz7HhL
+2496v3BoIOqzzcdvpCaDZjDdrw8SHpp45u9qrzMPKEIdqy4u5KjsKjuCZKczy4pc
+u44+JjDzNJRik0Ppf2AUJLBCnik6prZIttbCfGsvid7SR5sZZgjbGk/fuQCF/tQt
+aksvsIqb598/sTzNVBGkp6qWttTkPs8AEQEAAYkCPAQYAQoAJgIbIBYhBG0ewiab
+wLVFnIupIM/atB+Cks7uBQJj6WcnBQkJIarkAAoJEM/atB+Cks7uei8QAIa+BrMi
+fmLTSLe09CnGvacepKNao6UqSHwbmf6Tonv9rOU2EquKyCW/0YK53WGO6fnPE7FV
+8JYDWxecBvtLjj+hloEHJ/wliYwd4W3FOuGnb/E9mzQgyKdWcSBIxreZLdD7xZ5B
+iv3VLeKyx+xnJ99dC2+MBuL6CBk+gmzwri7/hkYG9GQW9TJEe7qi8D87iTN1YkXl
+cJXdDcqapEZxv8+nAa5E4gTmLlXnKYNidC6+9gtnGpCRZtSpLwX0pMVY27w9sthU
+Acnx5N3AwS7rCodqnU3ANa5a00wbWOmZ90qbofRX9RC3qkfoisr62bRELY7KFt7M
+VTV0YBTCPHFeP+bubyOOyUe1OJsCvWJfIhJm87qjS37WXxYDUU+KHGN4MX9LDvTS
+xy+h30Ba0XFfU1fgNtIvVR+MrrIGACq5VU2uSyBQLmIkgcusUComEx77mETE92Mw
+ROJfy1O5VGsNDr61xIu72MjKAlukwgwX/qQ7i8Flyf8N++J7fETf/4DHXxNS9imV
+JTVxHfvIWpclRfdUCZB6R1Ihv+n1T+yx/FroTxQ5wuilV7+0r2DhrW6Q0YISoWv5
+L1sfohVZCXF7EQgteax0/86WSboerrWQmfGk0k4SjKhBJK1O8Jhh2tk8OmlUz6Fs
+7MhFJ5NGASlFL7p0W5iB3qWYwn52sEBaI8VpmDMEYBW6BBYJKwYBBAHaRw8BAQdA
+WWTgOvzlX/x5OiYhMLK72aKOMvr0g6KIaynmN2YMp5O0M0pvbmF0aGFuIFNjaGxl
+aWZlciAoQ29tbWl0IFNpZ25pbmcgS2V5KSA8anNAbmlsLmltPoiaBBMWCgBCAhsD
+CAsJCg0MCAsHBhUKCQgLAwUWAwIBAAIeAQIXgBYhBAzGrFQcetxzPGQWEGNnA1dz
+lTEvBQJj6WYYBQkFtN+UAAoJEGNnA1dzlTEvXKQBAPQ4mbtEmbuMbfpeV3pMP8bO
+1OhOB4/Thx4tUrrV7JcjAQCveLdvBrB+cSh+DA7edl6/XWfafCT0qrzRFhaoEZhx
+Dbg4BGAVugQSCisGAQQBl1UBBQEBB0A2sxWorhv9BEE+urAmX5GBUfcCdta9Un6E
+t5wEG5jLVAMBCAeIfgQYFgoAJgIbDBYhBAzGrFQcetxzPGQWEGNnA1dzlTEvBQJj
+6WYtBQkFtN+pAAoJEGNnA1dzlTEvi+8BANiiPjamWJ3iSeMEaaYPoZXNZ7NAHlK0
+UUgQvB/osfQWAP9NKXMO7P5R/K+D2nRE/Ndmk0lqBykzumouPVuR21pYB5gzBGWW
+/sEWCSsGAQQB2kcPAQEHQAujl3ehBqKz3PFMW+rl8/d/1KS7Skx00xYU6xsLout+
+tDhKb25hdGhhbiBTY2hsZWlmZXIgKENvbW1pdCBTaWduaW5nIEtleSAyMDI0KSA8
+anNAbmlsLmltPoiaBBMWCgBCFiEEYy4qTb/j80NaLyG/lClu8uyb5oMFAmWW/sEC
+GwMFCQHhM4AICwkKDQwICwcGFQoJCAsDBRYDAgEAAh4FAheAAAoJEJQpbvLsm+aD
+g10BAP5MpkFbauicEGNTUJnmfbWZsGmmOTov7nG3ylVPp6UpAP4jIbm0Nz5L0+1B
+vA35PeZfJ8z2dIcuKPKkCgxbv55NAIkCNwQTAQoAIRYhBG0ewiabwLVFnIupIM/a
+tB+Cks7uBQJllwC0AwUBeAAKCRDP2rQfgpLO7sktEACdIKHR7vTHKgokw/6j2zwd
+Na3sBt0jC7tsqA7xbfobwMR3yoVnD49T4zHlW5MwKaQBsTkwI9pS4qbaPsX7VoXV
+5I8UpWPbXeDnofO9B+sO55ybVrGf1Fb2PmykZ85dgEe168hL0c5UX+9zCXjfFTHa
+GAxRmTrYKP0h+jYZJns1QK3KZEWh0pkqJz5oOLELqeZS2GMGn1PQjmbzz72/korZ
+sUswS5sDBbMVeusCWuNeY6FJZ6ziv97geu+uWe7ppwv25rebEKJgsuaIqDuAT2Gg
+3NgrubfXFVLlDxjuYdaO+ieBQur5z8UPaSzEYlF2p7/cut24A8WV/d3D5dX3XO/g
+AuEMkyAws9zOeY3NMMfkHEZsuX0AetH7cOQYyAUIlpye30OxeoZgO4Cl3G5q95sk
+Q4i/LpzNERq+JydmniPMbM/TL8p87RYr/bidO+0KeHwRzsesVu2ae1xO/ZRSyqny
+un5RZblS9QY1H3xUgKQWpMLxJGXr6n+9eRThRsrTK/JH6GFpkFnjmMpuxquAw32w
+PdxGWDUUE35pC4f0X/6rL8IBf32spXG+mKbBLTJkSkteSM26Uff4zVFludQU+N06
+c6XFX7eBpbhhHhsCabOskGFXXS0bdi6NcZgazm1I4rhqrT+pQFHDOZg/dgl5cND/
+Q4zqQ9Xrv/iV6ljHHAPYGrg4BGWW/sESCisGAQQBl1UBBQEBB0CTeGWS64rbAwJz
+Sioh6y0Urd5/pGIj5UEdyAFrjhiKDgMBCAeIfgQYFgoAJhYhBGMuKk2/4/NDWi8h
+v5QpbvLsm+aDBQJllv7BAhsMBQkB4TOAAAoJEJQpbvLsm+aDv0sBAIFCR1MA+d7V
+ll+AxWH/k2ghgfJ661e88iaoG7qUyve5APsFQbV5thutm99chCp8Sc+fulHNtrKJ
+WBymwZqetu7HBg==
+=mVJw
+-----END PGP PUBLIC KEY BLOCK-----
DELETED objfw.spec
Index: objfw.spec
==================================================================
--- objfw.spec
+++ /dev/null
@@ -1,248 +0,0 @@
-%global libobjfw_major 0
-%global libobjfw_minor 0
-%global libobjfwrt_major 0
-%global libobjfwrt_minor 0
-%global libobjfwtls_major 0
-%global libobjfwtls_minor 0
-%if 0%{?suse_version}
-%global libobjfw_pkgname libobjfw%{libobjfw_major}
-%global libobjfwrt_pkgname libobjfwrt%{libobjfwrt_major}
-%global libobjfwtls_pkgname libobjfwtls%{libobjfwtls_major}
-%else
-%global libobjfw_pkgname libobjfw
-%global libobjfwrt_pkgname libobjfwrt
-%global libobjfwtls_pkgname libobjfwtls
-%endif
-
-Name: objfw
-Version: 1.1dev
-Release: 1%{?dist}
-Summary: Portable, lightweight framework for the Objective-C language
-
-%if 0%{?suse_version}
-License: QPL-1.0 or GPL-3.0 or GPL-2.0
-Group: Development/Languages/C and C++
-%else
-License: QPL or GPLv3 or GPLv2
-%endif
-URL: https://objfw.nil.im
-Source0: objfw-%{version}.tar.gz
-
-BuildRequires: autoconf
-BuildRequires: automake
-BuildRequires: clang
-BuildRequires: make
-BuildRequires: pkgconfig(gnutls)
-Requires: %{libobjfw_pkgname}%{_isa} = %{version}-%{release}
-Requires: %{libobjfw_pkgname}-devel = %{version}-%{release}
-Requires: %{libobjfwrt_pkgname}%{_isa} = %{version}-%{release}
-Requires: %{libobjfwrt_pkgname}-devel = %{version}-%{release}
-Requires: ofarc%{_isa} = %{version}-%{release}
-Requires: ofdns%{_isa} = %{version}-%{release}
-Requires: ofhash%{_isa} = %{version}-%{release}
-Requires: ofhttp%{_isa} = %{version}-%{release}
-
-%description
-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 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 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.
-
-%package -n %{libobjfw_pkgname}
-Summary: ObjFW library
-Requires: %{libobjfwrt_pkgname}%{_isa} = %{version}-%{release}
-
-%description -n %{libobjfw_pkgname}
-The %{libobjfw_pkgname} package contains the library needed by programs using
-ObjFW.
-
-%package -n %{libobjfw_pkgname}-devel
-Summary: Header files, libraries and tools for %{libobjfw_pkgname}
-Requires: %{libobjfw_pkgname}%{_isa} = %{version}-%{release}
-Requires: %{libobjfwrt_pkgname}-devel = %{version}-%{release}
-
-%description -n %{libobjfw_pkgname}-devel
-The %{libobjfw_pkgname}-devel package contains the header files, libraries and
-tools to develop programs using ObjFW.
-
-%package -n %{libobjfwrt_pkgname}
-Summary: ObjFW Objective-C runtime library
-
-%description -n %{libobjfwrt_pkgname}
-The %{libobjfwrt_pkgname} package contains ObjFW's Objective-C runtime library.
-
-%package -n %{libobjfwrt_pkgname}-devel
-Summary: Header files and libraries for %{libobjfwrt_pkgname}
-Requires: %{libobjfwrt_pkgname}%{_isa} = %{version}-%{release}
-
-%description -n %{libobjfwrt_pkgname}-devel
-The %{libobjfwrt_pkgname}-devel package contains header files and libraries for
-ObjFW's Objective-C runtime library.
-
-%package -n %{libobjfwtls_pkgname}
-Summary: TLS support for ObjFW
-Requires: gnutls%{_isa} >= 3.0.5
-
-%description -n %{libobjfwtls_pkgname}
-The %{libobjfwtls_pkgname} package contains TLS support for ObjFW
-
-%package -n %{libobjfwtls_pkgname}-devel
-Summary: Header files and libraries for %{libobjfwtls_pkgname}
-Requires: %{libobjfwtls_pkgname}%{_isa} = %{version}-%{release}
-
-%description -n %{libobjfwtls_pkgname}-devel
-The %{libobjfwtls_pkgname}-devel package contains header files and libraries
-for TLS support for ObjFW.
-
-%package -n ofarc
-Summary: Utility for handling ZIP, Tar and LHA archives
-Requires: %{libobjfw_pkgname}%{_isa} = %{version}-%{release}
-Requires: %{libobjfwrt_pkgname}%{_isa} = %{version}-%{release}
-
-%description -n ofarc
-ofarc is a multi-format archive utility that allows creating, listing,
-extracting and modifying ZIP, Tar and LHA archives using ObjFW's classes for
-various archive types.
-
-%package -n ofdns
-Summary: Utility for performing DNS requests on the command line
-Requires: %{libobjfw_pkgname}%{_isa} = %{version}-%{release}
-Requires: %{libobjfwrt_pkgname}%{_isa} = %{version}-%{release}
-
-%description -n ofdns
-ofdns is an utility for performing DNS requests on the command line using
-ObjFW's DNS resolver.
-
-%package -n ofhash
-Summary: Utility to hash files with various cryptographic hash functions
-Requires: %{libobjfw_pkgname}%{_isa} = %{version}-%{release}
-Requires: %{libobjfwrt_pkgname}%{_isa} = %{version}-%{release}
-
-%description -n ofhash
-ofhash is an utility to hash files with various cryptographic hash functions
-(even using different algorithms at once) using ObjFW's classes for various
-cryptographic hashes.
-
-%package -n ofhttp
-Summary: Command line downloader for HTTP(S)
-Requires: %{libobjfw_pkgname}%{_isa} = %{version}-%{release}
-Requires: %{libobjfwrt_pkgname}%{_isa} = %{version}-%{release}
-Requires: %{libobjfwtls_pkgname}%{_isa} = %{version}-%{release}
-
-%description -n ofhttp
-ofhttp is a command line downloader for HTTP and HTTPS using ObjFW's
-OFHTTPClient class. It supports all features one would expect from a modern
-command line downloader such as resuming of downloads, using a SOCKS5 proxy, a
-modern terminal-based UI, etc.
-
-%prep
-%autosetup
-./autogen.sh
-
-%build
-%configure OBJC=clang --disable-rpath
-%make_build
-
-%install
-%make_install
-
-%check
-make -C tests run
-
-%if 0%{?suse_version}
-%post -n %{libobjfw_pkgname} -p /sbin/ldconfig
-%postun -n %{libobjfw_pkgname} -p /sbin/ldconfig
-%post -n %{libobjfwrt_pkgname} -p /sbin/ldconfig
-%postun -n %{libobjfwrt_pkgname} -p /sbin/ldconfig
-%endif
-
-%files
-%license LICENSE.QPL
-%license LICENSE.GPLv3
-%license LICENSE.GPLv2
-
-%files -n %{libobjfw_pkgname}
-%{_libdir}/libobjfw.so.%{libobjfw_major}
-%{_libdir}/libobjfw.so.%{libobjfw_major}.%{libobjfw_minor}.0
-%license LICENSE.QPL
-%license LICENSE.GPLv3
-%license LICENSE.GPLv2
-
-%files -n %{libobjfw_pkgname}-devel
-%{_libdir}/libobjfw.so
-%dir %{_includedir}/ObjFW
-%{_includedir}/ObjFW
-%{_bindir}/objfw-compile
-%{_bindir}/objfw-config
-%{_bindir}/objfw-new
-%license LICENSE.QPL
-%license LICENSE.GPLv3
-%license LICENSE.GPLv2
-
-%files -n %{libobjfwrt_pkgname}
-%{_libdir}/libobjfwrt.so.%{libobjfwrt_major}
-%{_libdir}/libobjfwrt.so.%{libobjfwrt_major}.%{libobjfwrt_minor}.0
-%license LICENSE.QPL
-%license LICENSE.GPLv3
-%license LICENSE.GPLv2
-
-%files -n %{libobjfwrt_pkgname}-devel
-%{_libdir}/libobjfwrt.so
-%{_includedir}/ObjFWRT/ObjFWRT.h
-%license LICENSE.QPL
-%license LICENSE.GPLv3
-%license LICENSE.GPLv2
-
-%files -n %{libobjfwtls_pkgname}
-%{_libdir}/libobjfwtls.so.%{libobjfwtls_major}
-%{_libdir}/libobjfwtls.so.%{libobjfwtls_major}.%{libobjfwtls_minor}.0
-%license LICENSE.QPL
-%license LICENSE.GPLv3
-%license LICENSE.GPLv2
-
-%files -n %{libobjfwtls_pkgname}-devel
-%{_libdir}/libobjfwtls.so
-%{_includedir}/ObjFWTLS/ObjFWTLS.h
-%license LICENSE.QPL
-%license LICENSE.GPLv3
-%license LICENSE.GPLv2
-
-%files -n ofarc
-%{_bindir}/ofarc
-%{_datadir}/ofarc/lang/de.json
-%{_datadir}/ofarc/lang/languages.json
-%license LICENSE.QPL
-%license LICENSE.GPLv3
-%license LICENSE.GPLv2
-
-%files -n ofdns
-%{_bindir}/ofdns
-%{_datadir}/ofdns/lang/de.json
-%{_datadir}/ofdns/lang/languages.json
-%license LICENSE.QPL
-%license LICENSE.GPLv3
-%license LICENSE.GPLv2
-
-%files -n ofhash
-%{_bindir}/ofhash
-%{_datadir}/ofhash/lang/de.json
-%{_datadir}/ofhash/lang/languages.json
-%license LICENSE.QPL
-%license LICENSE.GPLv3
-%license LICENSE.GPLv2
-
-%files -n ofhttp
-%{_bindir}/ofhttp
-%{_datadir}/ofhttp/lang/de.json
-%{_datadir}/ofhttp/lang/languages.json
-%license LICENSE.QPL
-%license LICENSE.GPLv3
-%license LICENSE.GPLv2
Index: src/Makefile
==================================================================
--- src/Makefile
+++ src/Makefile
@@ -7,10 +7,11 @@
SHARED_LIB = ${OBJFW_SHARED_LIB}
STATIC_LIB = ${OBJFW_STATIC_LIB}
FRAMEWORK = ${OBJFW_FRAMEWORK}
LIB_MAJOR = ${OBJFW_LIB_MAJOR}
LIB_MINOR = ${OBJFW_LIB_MINOR}
+LIB_PATCH = ${OBJFW_LIB_PATCH}
SRCS = OFASN1BitString.m \
OFASN1Boolean.m \
OFASN1Enumerated.m \
OFASN1IA5String.m \
@@ -38,40 +39,42 @@
OFFileManager.m \
OFGZIPStream.m \
OFHMAC.m \
OFINICategory.m \
OFINIFile.m \
+ OFIRI.m \
+ OFIRIHandler.m \
OFInflate64Stream.m \
OFInflateStream.m \
OFInvocation.m \
OFLHAArchive.m \
OFLHAArchiveEntry.m \
OFList.m \
OFLocale.m \
OFMD5Hash.m \
OFMapTable.m \
+ OFMatrix4x4.m \
OFMemoryStream.m \
OFMessagePackExtension.m \
OFMethodSignature.m \
OFMutableArray.m \
OFMutableData.m \
OFMutableDictionary.m \
+ OFMutableIRI.m \
OFMutableLHAArchiveEntry.m \
OFMutablePair.m \
OFMutableSet.m \
OFMutableString.m \
OFMutableTarArchiveEntry.m \
OFMutableTriple.m \
- OFMutableURI.m \
OFMutableZIPArchiveEntry.m \
OFNotification.m \
OFNotificationCenter.m \
OFNull.m \
OFNumber.m \
OFObject.m \
OFObject+KeyValueCoding.m \
- OFObject+Serialization.m \
OFOnce.m \
OFOptionsParser.m \
OFPBKDF2.m \
OFPair.m \
OFRIPEMD160Hash.m \
@@ -84,41 +87,36 @@
OFSHA384Or512Hash.m \
OFSHA512Hash.m \
OFScrypt.m \
OFSecureData.m \
OFSeekableStream.m \
- OFSerialization.m \
OFSet.m \
+ OFSettings.m \
OFSortedList.m \
OFStdIOStream.m \
OFStream.m \
OFString.m \
OFString+CryptographicHashing.m \
OFString+JSONParsing.m \
OFString+PercentEncoding.m \
OFString+PropertyListParsing.m \
- OFString+Serialization.m \
OFString+XMLEscaping.m \
OFString+XMLUnescaping.m \
${OF_SUBPROCESS_M} \
- OFSettings.m \
OFSystemInfo.m \
OFTarArchive.m \
OFTarArchiveEntry.m \
OFThread.m \
OFTimer.m \
OFTriple.m \
- OFURI.m \
- OFURIHandler.m \
OFUUID.m \
OFValue.m \
OFXMLAttribute.m \
OFXMLCDATA.m \
OFXMLCharacters.m \
OFXMLComment.m \
OFXMLElement.m \
- OFXMLElement+Serialization.m \
OFXMLElementBuilder.m \
OFXMLNode.m \
OFXMLParser.m \
OFXMLProcessingInstruction.m \
OFZIPArchive.m \
@@ -143,10 +141,11 @@
OFHTTPResponse.m \
OFHTTPServer.m \
OFSequencedPacketSocket.m \
OFSocket.m \
OFStreamSocket.m \
+ OFSystemInfo+NetworkInterfaces.m \
OFTCPSocket.m \
OFTLSStream.m \
OFUDPSocket.m \
${USE_SRCS_APPLETALK} \
${USE_SRCS_IPX} \
@@ -188,56 +187,61 @@
objfw-defs.h \
platform.h \
${USE_INCLUDES_ATOMIC}
SRCS += OFASPrintF.m \
- OFAdjacentArray.m \
- OFAdjacentSubarray.m \
- OFArchiveURIHandler.m \
+ OFArchiveIRIHandler.m \
OFBase64.m \
OFBitSetCharacterSet.m \
- OFBytesValue.m \
OFCRC16.m \
OFCRC32.m \
- OFCountedMapTableSet.m \
- OFEmbeddedURIHandler.m \
+ OFConcreteArray.m \
+ OFConcreteColor.m \
+ OFConcreteCountedSet.m \
+ OFConcreteData.m \
+ OFConcreteDate.m \
+ OFConcreteDictionary.m \
+ OFConcreteMutableArray.m \
+ OFConcreteMutableData.m \
+ OFConcreteMutableDictionary.m \
+ OFConcreteMutableSet.m \
+ OFConcreteNumber.m \
+ OFConcreteSet.m \
+ OFConcreteSubarray.m \
+ OFConcreteValue.m \
+ OFEmbeddedIRIHandler.m \
OFHuffmanTree.m \
OFINIFileSettings.m \
OFInvertedCharacterSet.m \
OFLHADecompressingStream.m \
- OFMapTableDictionary.m \
- OFMapTableSet.m \
- OFMutableAdjacentArray.m \
- OFMutableMapTableDictionary.m \
- OFMutableMapTableSet.m \
OFMutableUTF8String.m \
- OFNonretainedObjectValue.m \
- OFPointValue.m \
- OFPointerValue.m \
OFRangeCharacterSet.m \
- OFRangeValue.m \
- OFRectValue.m \
OFSandbox.m \
- OFSizeValue.m \
+ OFStrFTime.m \
OFStrPTime.m \
OFSubarray.m \
+ OFSubdata.m \
OFUTF8String.m \
${LIBBASES_M} \
${RUNTIME_AUTORELEASE_M} \
${RUNTIME_INSTANCE_M} \
- ${UNICODE_M}
-SRCS_FILES += OFFileURIHandler.m
+ ${UNICODE_M} \
+ ${USE_SRCS_TAGGED_POINTERS}
+SRCS_FILES += OFFileIRIHandler.m
SRCS_SOCKETS += OFAsyncIPSocketConnector.m \
OFDNSResolverSettings.m \
${OF_EPOLL_KERNEL_EVENT_OBSERVER_M} \
- OFHTTPURIHandler.m \
+ OFHTTPIRIHandler.m \
OFHostAddressResolver.m \
OFKernelEventObserver.m \
${OF_KQUEUE_KERNEL_EVENT_OBSERVER_M} \
${OF_POLL_KERNEL_EVENT_OBSERVER_M} \
${OF_SELECT_KERNEL_EVENT_OBSERVER_M} \
OFTCPSocketSOCKS5Connector.m
+SRCS_TAGGED_POINTERS = OFTaggedPointerColor.m \
+ OFTaggedPointerDate.m \
+ OFTaggedPointerNumber.m
SRCS_WINDOWS += platform/Windows/OFWin32ConsoleStdIOStream.m \
versioninfo.rc
OBJS_EXTRA = exceptions/exceptions.a \
encodings/encodings.a \
@@ -258,5 +262,13 @@
RCFLAGS = --use-temp-file \
-DOBJFW_LIB_MAJOR=${OBJFW_LIB_MAJOR} \
-DOBJFW_LIB_MINOR=${OBJFW_LIB_MINOR} \
-DOBJFW_LIB_VERSION=\"${OBJFW_LIB_MAJOR}.${OBJFW_LIB_MINOR}\" \
-DOBJFW_SHARED_LIB=\"${OBJFW_SHARED_LIB}\"
+
+uninstall-extra:
+ for i in platform/GCC4 platform/GCC4.7 platform/PowerPC platform/macOS \
+ platform/x86 platform ""; do \
+ if test -d ${DESTDIR}${includedir}/${includesubdir}/$$i; then \
+ rmdir ${DESTDIR}${includedir}/${includesubdir}/$$i; \
+ fi; \
+ done
Index: src/OFASN1BitString.h
==================================================================
--- src/OFASN1BitString.h
+++ src/OFASN1BitString.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFASN1BitString.m
==================================================================
--- src/OFASN1BitString.m
+++ src/OFASN1BitString.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFASN1Boolean.h
==================================================================
--- src/OFASN1Boolean.h
+++ src/OFASN1Boolean.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFASN1Boolean.m
==================================================================
--- src/OFASN1Boolean.m
+++ src/OFASN1Boolean.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFASN1DERRepresentation.h
==================================================================
--- src/OFASN1DERRepresentation.h
+++ src/OFASN1DERRepresentation.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFASN1Enumerated.h
==================================================================
--- src/OFASN1Enumerated.h
+++ src/OFASN1Enumerated.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFASN1Enumerated.m
==================================================================
--- src/OFASN1Enumerated.m
+++ src/OFASN1Enumerated.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFASN1IA5String.h
==================================================================
--- src/OFASN1IA5String.h
+++ src/OFASN1IA5String.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFASN1IA5String.m
==================================================================
--- src/OFASN1IA5String.m
+++ src/OFASN1IA5String.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFASN1Integer.h
==================================================================
--- src/OFASN1Integer.h
+++ src/OFASN1Integer.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFASN1Integer.m
==================================================================
--- src/OFASN1Integer.m
+++ src/OFASN1Integer.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFASN1NumericString.h
==================================================================
--- src/OFASN1NumericString.h
+++ src/OFASN1NumericString.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFASN1NumericString.m
==================================================================
--- src/OFASN1NumericString.m
+++ src/OFASN1NumericString.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFASN1ObjectIdentifier.h
==================================================================
--- src/OFASN1ObjectIdentifier.h
+++ src/OFASN1ObjectIdentifier.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFASN1ObjectIdentifier.m
==================================================================
--- src/OFASN1ObjectIdentifier.m
+++ src/OFASN1ObjectIdentifier.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFASN1OctetString.h
==================================================================
--- src/OFASN1OctetString.h
+++ src/OFASN1OctetString.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFASN1OctetString.m
==================================================================
--- src/OFASN1OctetString.m
+++ src/OFASN1OctetString.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFASN1PrintableString.h
==================================================================
--- src/OFASN1PrintableString.h
+++ src/OFASN1PrintableString.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFASN1PrintableString.m
==================================================================
--- src/OFASN1PrintableString.m
+++ src/OFASN1PrintableString.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFASN1UTF8String.h
==================================================================
--- src/OFASN1UTF8String.h
+++ src/OFASN1UTF8String.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFASN1UTF8String.m
==================================================================
--- src/OFASN1UTF8String.m
+++ src/OFASN1UTF8String.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFASN1Value.h
==================================================================
--- src/OFASN1Value.h
+++ src/OFASN1Value.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFASN1Value.m
==================================================================
--- src/OFASN1Value.m
+++ src/OFASN1Value.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFASPrintF.h
==================================================================
--- src/OFASPrintF.h
+++ src/OFASPrintF.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFASPrintF.m
==================================================================
--- src/OFASPrintF.m
+++ src/OFASPrintF.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -23,11 +23,11 @@
#ifdef HAVE_WCHAR_H
# include
#endif
-#ifdef HAVE_ASPRINTF_L
+#if defined(HAVE_ASPRINTF_L) || defined(HAVE_USELOCALE)
# include
#endif
#ifdef HAVE_XLOCALE_H
# include
#endif
@@ -34,10 +34,11 @@
#ifdef OF_HAVE_SYS_TYPES_H
# include
#endif
+#import "OFASPrintF.h"
#import "OFString.h"
#import "OFLocale.h"
#import "OFInitializationFailedException.h"
@@ -81,11 +82,11 @@
lengthModifierCapitalL
} lengthModifier;
bool useLocale;
};
-#ifdef HAVE_ASPRINTF_L
+#if defined(HAVE_ASPRINTF_L) || defined(HAVE_USELOCALE)
static locale_t cLocale;
OF_CONSTRUCTOR()
{
if ((cLocale = newlocale(LC_ALL_MASK, "C", NULL)) == NULL)
@@ -375,11 +376,11 @@
static bool
formatConversionSpecifierState(struct Context *ctx)
{
char *tmp = NULL;
int tmpLen = 0;
-#ifndef HAVE_ASPRINTF_L
+#if !defined(HAVE_ASPRINTF_L) && !defined(HAVE_USELOCALE)
OFString *point;
#endif
if (!appendSubformat(ctx, ctx->format + ctx->i, 1))
return false;
@@ -546,43 +547,57 @@
case 'a':
case 'A':
switch (ctx->lengthModifier) {
case lengthModifierNone:
case lengthModifierL:
-#ifdef HAVE_ASPRINTF_L
+#if defined(HAVE_ASPRINTF_L)
if (!ctx->useLocale)
tmpLen = asprintf_l(&tmp, cLocale,
ctx->subformat,
va_arg(ctx->arguments, double));
else
+#elif defined(HAVE_USELOCALE)
+ if (!ctx->useLocale) {
+ locale_t previousLocale = uselocale(cLocale);
+ tmpLen = asprintf(&tmp, ctx->subformat,
+ va_arg(ctx->arguments, double));
+ uselocale(previousLocale);
+ } else
#endif
tmpLen = asprintf(&tmp, ctx->subformat,
va_arg(ctx->arguments, double));
break;
case lengthModifierCapitalL:
-#ifdef HAVE_ASPRINTF_L
+#if defined(HAVE_ASPRINTF_L)
if (!ctx->useLocale)
tmpLen = asprintf_l(&tmp, cLocale,
ctx->subformat,
va_arg(ctx->arguments, long double));
else
+#elif defined(HAVE_USELOCALE)
+ if (!ctx->useLocale) {
+ locale_t previousLocale = uselocale(cLocale);
+ tmpLen = asprintf(&tmp, ctx->subformat,
+ va_arg(ctx->arguments, long double));
+ uselocale(previousLocale);
+ } else
#endif
tmpLen = asprintf(&tmp, ctx->subformat,
va_arg(ctx->arguments, long double));
break;
default:
return false;
}
-#ifndef HAVE_ASPRINTF_L
+#if !defined(HAVE_ASPRINTF_L) && !defined(HAVE_USELOCALE)
if (tmpLen == -1)
return false;
/*
- * If there's no asprintf_l, we have no other choice than to
- * use this ugly hack to replace the locale's decimal point
- * back to ".".
+ * If there's no asprintf_l and no uselocale, we have no other
+ * choice than to use this ugly hack to replace the locale's
+ * decimal point back to ".".
*/
point = [OFLocale decimalSeparator];
if (!ctx->useLocale && point != nil && ![point isEqual: @"."]) {
void *pool = objc_autoreleasePoolPush();
DELETED src/OFAdjacentArray.h
Index: src/OFAdjacentArray.h
==================================================================
--- src/OFAdjacentArray.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
- *
- * All rights reserved.
- *
- * This file is part of ObjFW. It may be distributed under the terms of the
- * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
- * the packaging of this file.
- *
- * Alternatively, it may be distributed under the terms of the GNU General
- * Public License, either version 2 or 3, which can be found in the file
- * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
- * file.
- */
-
-#import "OFArray.h"
-
-OF_ASSUME_NONNULL_BEGIN
-
-@class OFMutableData;
-
-@interface OFAdjacentArray: OFArray
-{
- OFMutableData *_array;
-}
-@end
-
-OF_ASSUME_NONNULL_END
DELETED src/OFAdjacentArray.m
Index: src/OFAdjacentArray.m
==================================================================
--- src/OFAdjacentArray.m
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
- *
- * All rights reserved.
- *
- * This file is part of ObjFW. It may be distributed under the terms of the
- * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
- * the packaging of this file.
- *
- * Alternatively, it may be distributed under the terms of the GNU General
- * Public License, either version 2 or 3, which can be found in the file
- * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
- * file.
- */
-
-#include "config.h"
-
-#include
-
-#import "OFAdjacentArray.h"
-#import "OFAdjacentSubarray.h"
-#import "OFData.h"
-#import "OFMutableAdjacentArray.h"
-#import "OFString.h"
-#import "OFXMLElement.h"
-
-#import "OFEnumerationMutationException.h"
-#import "OFInvalidArgumentException.h"
-#import "OFOutOfRangeException.h"
-
-@implementation OFAdjacentArray
-- (instancetype)init
-{
- self = [super init];
-
- @try {
- _array = [[OFMutableData alloc] initWithItemSize: sizeof(id)];
- } @catch (id e) {
- [self release];
- @throw e;
- }
-
- return self;
-}
-
-- (instancetype)initWithObject: (id)object
-{
- self = [self init];
-
- @try {
- if (object == nil)
- @throw [OFInvalidArgumentException exception];
-
- [_array addItem: &object];
- [object retain];
- } @catch (id e) {
- [self release];
- @throw e;
- }
-
- return self;
-}
-
-- (instancetype)initWithObject: (id)firstObject arguments: (va_list)arguments
-{
- self = [self init];
-
- @try {
- id object;
-
- [_array addItem: &firstObject];
- [firstObject retain];
-
- while ((object = va_arg(arguments, id)) != nil) {
- [_array addItem: &object];
- [object retain];
- }
- } @catch (id e) {
- [self release];
- @throw e;
- }
-
- return self;
-}
-
-- (instancetype)initWithArray: (OFArray *)array
-{
- id const *objects;
- size_t count;
-
- self = [super init];
-
- if (array == nil)
- return self;
-
- @try {
- objects = array.objects;
- count = array.count;
-
- _array = [[OFMutableData alloc] initWithItemSize: sizeof(id)
- capacity: count];
- } @catch (id e) {
- [self release];
- @throw e;
- }
-
- @try {
- for (size_t i = 0; i < count; i++)
- [objects[i] retain];
-
- [_array addItems: objects count: count];
- } @catch (id e) {
- for (size_t i = 0; i < count; i++)
- [objects[i] release];
-
- /* Prevent double-release of objects */
- [_array release];
- _array = nil;
-
- [self release];
- @throw e;
- }
-
- return self;
-}
-
-- (instancetype)initWithObjects: (id const *)objects count: (size_t)count
-{
- self = [self init];
-
- @try {
- bool ok = true;
-
- for (size_t i = 0; i < count; i++) {
- if (objects[i] == nil)
- ok = false;
-
- [objects[i] retain];
- }
-
- if (!ok)
- @throw [OFInvalidArgumentException exception];
-
- [_array addItems: objects count: count];
- } @catch (id e) {
- for (size_t i = 0; i < count; i++)
- [objects[i] release];
-
- [self release];
- @throw e;
- }
-
- return self;
-}
-
-- (instancetype)initWithSerialization: (OFXMLElement *)element
-{
- self = [self init];
-
- @try {
- void *pool = objc_autoreleasePoolPush();
-
- if ((![element.name isEqual: @"OFArray"] &&
- ![element.name isEqual: @"OFMutableArray"]) ||
- ![element.namespace isEqual: OFSerializationNS])
- @throw [OFInvalidArgumentException exception];
-
- for (OFXMLElement *child in
- [element elementsForNamespace: OFSerializationNS]) {
- void *pool2 = objc_autoreleasePoolPush();
- id object;
-
- object = child.objectByDeserializing;
- [_array addItem: &object];
- [object retain];
-
- objc_autoreleasePoolPop(pool2);
- }
-
- objc_autoreleasePoolPop(pool);
- } @catch (id e) {
- [self release];
- @throw e;
- }
-
- return self;
-}
-
-- (size_t)count
-{
- return _array.count;
-}
-
-- (id const *)objects
-{
- return _array.items;
-}
-
-- (id)objectAtIndex: (size_t)idx
-{
- return *((id *)[_array itemAtIndex: idx]);
-}
-
-- (id)objectAtIndexedSubscript: (size_t)idx
-{
- return *((id *)[_array itemAtIndex: idx]);
-}
-
-- (void)getObjects: (id *)buffer inRange: (OFRange)range
-{
- id const *objects = _array.items;
- size_t count = _array.count;
-
- if (range.length > SIZE_MAX - range.location ||
- range.location + range.length > count)
- @throw [OFOutOfRangeException exception];
-
- for (size_t i = 0; i < range.length; i++)
- buffer[i] = objects[range.location + i];
-}
-
-- (size_t)indexOfObject: (id)object
-{
- id const *objects;
- size_t count;
-
- if (object == nil)
- return OFNotFound;
-
- objects = _array.items;
- count = _array.count;
-
- for (size_t i = 0; i < count; i++)
- if ([objects[i] isEqual: object])
- return i;
-
- return OFNotFound;
-}
-
-- (size_t)indexOfObjectIdenticalTo: (id)object
-{
- id const *objects;
- size_t count;
-
- if (object == nil)
- return OFNotFound;
-
- objects = _array.items;
- count = _array.count;
-
- for (size_t i = 0; i < count; i++)
- if (objects[i] == object)
- return i;
-
- return OFNotFound;
-}
-
-
-- (OFArray *)objectsInRange: (OFRange)range
-{
- if (range.length > SIZE_MAX - range.location ||
- range.location + range.length > _array.count)
- @throw [OFOutOfRangeException exception];
-
- if ([self isKindOfClass: [OFMutableArray class]])
- return [OFArray
- arrayWithObjects: (id *)_array.items + range.location
- count: range.length];
-
- return [OFAdjacentSubarray arrayWithArray: self range: range];
-}
-
-- (bool)isEqual: (id)object
-{
- OFArray *otherArray;
- id const *objects, *otherObjects;
- size_t count;
-
- if (object == self)
- return true;
-
- if (![object isKindOfClass: [OFAdjacentArray class]] &&
- ![object isKindOfClass: [OFMutableAdjacentArray class]])
- return [super isEqual: object];
-
- otherArray = object;
-
- count = _array.count;
-
- if (count != otherArray.count)
- return false;
-
- objects = _array.items;
- otherObjects = otherArray.objects;
-
- for (size_t i = 0; i < count; i++)
- if (![objects[i] isEqual: otherObjects[i]])
- return false;
-
- return true;
-}
-
-- (unsigned long)hash
-{
- id const *objects = _array.items;
- size_t count = _array.count;
- unsigned long hash;
-
- OFHashInit(&hash);
-
- for (size_t i = 0; i < count; i++)
- OFHashAddHash(&hash, [objects[i] hash]);
-
- OFHashFinalize(&hash);
-
- return hash;
-}
-
-- (int)countByEnumeratingWithState: (OFFastEnumerationState *)state
- objects: (id *)objects
- count: (int)count_
-{
- size_t count = _array.count;
-
- if (count > INT_MAX)
- /*
- * Use the implementation from OFArray, which is slower, but can
- * enumerate in chunks.
- */
- return [super countByEnumeratingWithState: state
- objects: objects
- count: count_];
-
- if (state->state >= count)
- return 0;
-
- state->state = (unsigned long)count;
- state->itemsPtr = (id *)_array.items;
- state->mutationsPtr = (unsigned long *)self;
-
- return (int)count;
-}
-
-#ifdef OF_HAVE_BLOCKS
-- (void)enumerateObjectsUsingBlock: (OFArrayEnumerationBlock)block
-{
- id const *objects = _array.items;
- size_t count = _array.count;
- bool stop = false;
-
- for (size_t i = 0; i < count && !stop; i++)
- block(objects[i], i, &stop);
-}
-#endif
-
-- (void)dealloc
-{
- id const *objects = _array.items;
- size_t count = _array.count;
-
- for (size_t i = 0; i < count; i++)
- [objects[i] release];
-
- [_array release];
-
- [super dealloc];
-}
-@end
DELETED src/OFAdjacentSubarray.h
Index: src/OFAdjacentSubarray.h
==================================================================
--- src/OFAdjacentSubarray.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
- *
- * All rights reserved.
- *
- * This file is part of ObjFW. It may be distributed under the terms of the
- * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
- * the packaging of this file.
- *
- * Alternatively, it may be distributed under the terms of the GNU General
- * Public License, either version 2 or 3, which can be found in the file
- * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
- * file.
- */
-
-#import "OFSubarray.h"
-
-OF_ASSUME_NONNULL_BEGIN
-
-@interface OFAdjacentSubarray: OFSubarray
-@end
-
-OF_ASSUME_NONNULL_END
DELETED src/OFAdjacentSubarray.m
Index: src/OFAdjacentSubarray.m
==================================================================
--- src/OFAdjacentSubarray.m
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
- *
- * All rights reserved.
- *
- * This file is part of ObjFW. It may be distributed under the terms of the
- * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
- * the packaging of this file.
- *
- * Alternatively, it may be distributed under the terms of the GNU General
- * Public License, either version 2 or 3, which can be found in the file
- * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
- * file.
- */
-
-#include "config.h"
-
-#import "OFAdjacentSubarray.h"
-#import "OFAdjacentArray.h"
-#import "OFMutableAdjacentArray.h"
-
-@implementation OFAdjacentSubarray
-- (const id *)objects
-{
- return _array.objects + _range.location;
-}
-
-- (bool)isEqual: (id)object
-{
- OFArray *otherArray;
- id const *objects, *otherObjects;
-
- if (object == self)
- return true;
-
- if (![object isKindOfClass: [OFAdjacentArray class]] &&
- ![object isKindOfClass: [OFMutableAdjacentArray class]])
- return [super isEqual: object];
-
- otherArray = object;
-
- if (_range.length != otherArray.count)
- return false;
-
- objects = self.objects;
- otherObjects = otherArray.objects;
-
- for (size_t i = 0; i < _range.length; i++)
- if (![objects[i] isEqual: otherObjects[i]])
- return false;
-
- return true;
-}
-
-#ifdef OF_HAVE_BLOCKS
-- (void)enumerateObjectsUsingBlock: (OFArrayEnumerationBlock)block
-{
- id const *objects = self.objects;
- bool stop = false;
-
- for (size_t i = 0; i < _range.length && !stop; i++)
- block(objects[i], i, &stop);
-}
-#endif
-@end
Index: src/OFApplication.h
==================================================================
--- src/OFApplication.h
+++ src/OFApplication.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -27,10 +27,16 @@
@class OFMutableArray OF_GENERIC(ObjectType);
@class OFMutableDictionary OF_GENERIC(KeyType, ObjectType);
@class OFSandbox;
@class OFString;
+/**
+ * @brief A notification that will be sent when the application did finish
+ * launching.
+ */
+extern const OFNotificationName OFApplicationDidFinishLaunchingNotification;
+
/**
* @brief A notification that will be sent when the application will terminate.
*/
extern const OFNotificationName OFApplicationWillTerminateNotification;
@@ -49,11 +55,11 @@
*
* // In MyAppDelegate.m:
* OF_APPLICATION_DELEGATE(MyAppDelegate)
*
* @implementation MyAppDelegate
- * - (void)applicationDidFinishLaunching
+ * - (void)applicationDidFinishLaunching: (OFNotification *)notification
* {
* [OFApplication terminate];
* }
* @end
* @endcode
@@ -79,18 +85,24 @@
*/
@protocol OFApplicationDelegate
/**
* @brief A method which is called when the application was initialized and is
* running now.
+ *
+ * @param notification A notification with name
+ * OFApplicationDidFinishLaunchingNotification
*/
-- (void)applicationDidFinishLaunching;
+- (void)applicationDidFinishLaunching: (OFNotification *)notification;
@optional
/**
* @brief A method which is called when the application will terminate.
+ *
+ * @param notification A notification with name
+ * OFApplicationWillTerminateNotification
*/
-- (void)applicationWillTerminate;
+- (void)applicationWillTerminate: (OFNotification *)notification;
/**
* @brief A method which is called when the application received a SIGINT.
*
* @warning You are not allowed to send any messages inside this method, as
@@ -151,11 +163,11 @@
* In order to create a new OFApplication, you should create a class conforming
* to the optional @ref OFApplicationDelegate protocol and put
* `OF_APPLICATION_DELEGATE(NameOfYourClass)` in the .m file of that class.
*
* When the application is about to be terminated,
- * @ref OFApplicationDelegate#applicationWillTerminate will be called on the
+ * @ref OFApplicationDelegate#applicationWillTerminate: will be called on the
* delegate and an @ref OFApplicationWillTerminateNotification will be sent.
*/
OF_SUBCLASSING_RESTRICTED
@interface OFApplication: OFObject
{
Index: src/OFApplication.m
==================================================================
--- src/OFApplication.m
+++ src/OFApplication.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -35,10 +35,11 @@
#import "OFNotificationCenter.h"
#import "OFPair.h"
#import "OFRunLoop+Private.h"
#import "OFRunLoop.h"
#import "OFSandbox.h"
+#import "OFStdIOStream.h"
#import "OFString.h"
#import "OFSystemInfo.h"
#import "OFThread+Private.h"
#import "OFThread.h"
@@ -52,12 +53,14 @@
#elif defined(OF_WINDOWS)
# include
extern int _CRT_glob;
extern void __wgetmainargs(int *, wchar_t ***, wchar_t ***, int, int *);
#elif defined(OF_AMIGAOS)
+# define Class IntuitionClass
# include
# include
+# undef Class
#elif !defined(OF_IOS)
extern char **environ;
#endif
#ifdef OF_PSP
@@ -82,27 +85,30 @@
andWideArgumentValues: (wchar_t *[])wargv;
#endif
- (void)of_run;
@end
+const OFNotificationName OFApplicationDidFinishLaunchingNotification =
+ @"OFApplicationDidFinishLaunchingNotification";
const OFNotificationName OFApplicationWillTerminateNotification =
@"OFApplicationWillTerminateNotification";
static OFApplication *app = nil;
static void
atexitHandler(void)
{
id delegate = app.delegate;
-
- [[OFNotificationCenter defaultCenter]
- postNotificationName: OFApplicationWillTerminateNotification
+ OFNotification *notification = [OFNotification
+ notificationWithName: OFApplicationWillTerminateNotification
object: app];
- if ([delegate respondsToSelector: @selector(applicationWillTerminate)])
- [delegate applicationWillTerminate];
+ if ([delegate respondsToSelector: @selector(applicationWillTerminate:)])
+ [delegate applicationWillTerminate: notification];
[delegate release];
+
+ [[OFNotificationCenter defaultCenter] postNotification: notification];
#if defined(OF_HAVE_THREADS) && defined(OF_HAVE_SOCKETS) && \
defined(OF_AMIGAOS) && !defined(OF_MORPHOS)
OFSocketDeinit();
#endif
@@ -109,22 +115,21 @@
}
int
OFApplicationMain(int *argc, char **argv[], id delegate)
{
-#ifdef OF_WINDOWS
- wchar_t **wargv, **wenvp;
- int wargc, si = 0;
-#endif
-
[[OFLocale alloc] init];
app = [[OFApplication alloc] of_init];
#ifdef OF_WINDOWS
if ([OFSystemInfo isWindowsNT]) {
+ wchar_t **wargv, **wenvp;
+ int wargc, si = 0;
+
__wgetmainargs(&wargc, &wargv, &wenvp, _CRT_glob, &si);
+
[app of_setArgumentCount: argc
andArgumentValues: argv
andWideArgumentCount: wargc
andWideArgumentValues: wargv];
} else
@@ -258,13 +263,12 @@
continue;
}
pos = [tmp rangeOfString: @"="].location;
if (pos == OFNotFound) {
- fprintf(stderr,
- "Warning: Invalid environment "
- "variable: %s\n", tmp.UTF8String);
+ OFLog(@"Warning: Invalid environment "
+ "variable: %@", tmp);
continue;
}
key = [tmp substringToIndex: pos];
value = [tmp substringFromIndex: pos + 1];
@@ -300,13 +304,12 @@
continue;
}
pos = [tmp rangeOfString: @"="].location;
if (pos == OFNotFound) {
- fprintf(stderr,
- "Warning: Invalid environment "
- "variable: %s\n", tmp.UTF8String);
+ OFLog(@"Warning: Invalid environment "
+ "variable: %@", tmp);
continue;
}
key = [tmp substringToIndex: pos];
value = [tmp substringFromIndex: pos + 1];
@@ -394,12 +397,12 @@
void *pool = objc_autoreleasePoolPush();
OFString *key, *value;
char *sep;
if ((sep = strchr(*env, '=')) == NULL) {
- fprintf(stderr, "Warning: Invalid "
- "environment variable: %s\n", *env);
+ OFLog(@"Warning: Invalid environment "
+ "variable: %s", *env);
continue;
}
key = [OFString
stringWithCString: *env
@@ -578,10 +581,11 @@
- (void)of_run
{
void *pool = objc_autoreleasePoolPush();
OFRunLoop *runLoop;
+ OFNotification *notification;
#ifdef OF_HAVE_THREADS
[OFThread of_createMainThread];
runLoop = [OFRunLoop currentRunLoop];
#else
@@ -597,11 +601,19 @@
* of_setMainRunLoop: retained it. However, we only have a weak
* reference to it now, whereas we had a strong reference before.
*/
pool = objc_autoreleasePoolPush();
- [_delegate applicationDidFinishLaunching];
+
+ notification = [OFNotification
+ notificationWithName: OFApplicationDidFinishLaunchingNotification
+ object: app];
+
+ [[OFNotificationCenter defaultCenter] postNotification: notification];
+
+ [_delegate applicationDidFinishLaunching: notification];
+
objc_autoreleasePoolPop(pool);
[runLoop run];
}
Index: src/OFArchiveEntry.h
==================================================================
--- src/OFArchiveEntry.h
+++ src/OFArchiveEntry.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
ADDED src/OFArchiveIRIHandler.h
Index: src/OFArchiveIRIHandler.h
==================================================================
--- /dev/null
+++ src/OFArchiveIRIHandler.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#import "OFIRIHandler.h"
+
+OF_ASSUME_NONNULL_BEGIN
+
+@interface OFArchiveIRIHandler: OFIRIHandler
+@end
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern OFIRI *OFArchiveIRIHandlerIRIForFileInArchive(OFString *, OFString *,
+ OFIRI *);
+#ifdef __cplusplus
+}
+#endif
+
+OF_ASSUME_NONNULL_END
ADDED src/OFArchiveIRIHandler.m
Index: src/OFArchiveIRIHandler.m
==================================================================
--- /dev/null
+++ src/OFArchiveIRIHandler.m
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#include "config.h"
+
+#include
+
+#import "OFArchiveIRIHandler.h"
+#import "OFCharacterSet.h"
+#import "OFGZIPStream.h"
+#import "OFIRI.h"
+#import "OFLHAArchive.h"
+#import "OFStream.h"
+#import "OFTarArchive.h"
+#import "OFZIPArchive.h"
+
+#import "OFInvalidArgumentException.h"
+#import "OFOpenItemFailedException.h"
+
+@interface OFArchiveIRIHandlerPathAllowedCharacterSet: OFCharacterSet
+{
+ OFCharacterSet *_characterSet;
+ bool (*_characterIsMember)(id, SEL, OFUnichar);
+}
+@end
+
+static OFCharacterSet *pathAllowedCharacters;
+
+static void
+initPathAllowedCharacters(void)
+{
+ pathAllowedCharacters =
+ [[OFArchiveIRIHandlerPathAllowedCharacterSet alloc] init];
+}
+
+@implementation OFArchiveIRIHandler
+- (OFStream *)openItemAtIRI: (OFIRI *)IRI mode: (OFString *)mode
+{
+ void *pool = objc_autoreleasePoolPush();
+ OFString *scheme = IRI.scheme;
+ OFString *percentEncodedPath, *path;
+ size_t pos;
+ OFIRI *archiveIRI;
+ OFStream *stream;
+
+ if (IRI.host != nil || IRI.port != nil || IRI.user != nil ||
+ IRI.password != nil || IRI.query != nil || IRI.fragment != nil)
+ @throw [OFInvalidArgumentException exception];
+
+ if (![mode isEqual: @"r"])
+ /*
+ * Writing has some implications that are not decided yet: Will
+ * it always append to an archive? What happens if the file
+ * already exists?
+ */
+ @throw [OFInvalidArgumentException exception];
+
+ /*
+ * GZIP only compresses one file and thus has no path inside an
+ * archive.
+ */
+ if ([scheme isEqual: @"gzip"]) {
+ stream = [OFIRIHandler openItemAtIRI: [OFIRI IRIWithString:
+ IRI.path]
+ mode: @"r"];
+ stream = [OFGZIPStream streamWithStream: stream mode: @"r"];
+ goto end;
+ }
+
+ percentEncodedPath = IRI.percentEncodedPath;
+ pos = [percentEncodedPath rangeOfString: @"!"].location;
+
+ if (pos == OFNotFound)
+ @throw [OFInvalidArgumentException exception];
+
+ archiveIRI = [OFIRI IRIWithString:
+ [percentEncodedPath substringWithRange: OFMakeRange(0, pos)]
+ .stringByRemovingPercentEncoding];
+ path = [percentEncodedPath substringWithRange:
+ OFMakeRange(pos + 1, percentEncodedPath.length - pos - 1)]
+ .stringByRemovingPercentEncoding;
+
+ if ([scheme isEqual: @"lha"]) {
+ OFLHAArchive *archive = [OFLHAArchive archiveWithIRI: archiveIRI
+ mode: @"r"];
+ OFLHAArchiveEntry *entry;
+
+ while ((entry = [archive nextEntry]) != nil) {
+ if ([entry.fileName isEqual: path]) {
+ stream = [archive streamForReadingCurrentEntry];
+ goto end;
+ }
+ }
+
+ @throw [OFOpenItemFailedException exceptionWithIRI: IRI
+ mode: mode
+ errNo: ENOENT];
+ } else if ([scheme isEqual: @"tar"]) {
+ OFTarArchive *archive = [OFTarArchive archiveWithIRI: archiveIRI
+ mode: @"r"];
+ OFTarArchiveEntry *entry;
+
+ while ((entry = [archive nextEntry]) != nil) {
+ if ([entry.fileName isEqual: path]) {
+ stream = [archive streamForReadingCurrentEntry];
+ goto end;
+ }
+ }
+
+ @throw [OFOpenItemFailedException exceptionWithIRI: IRI
+ mode: mode
+ errNo: ENOENT];
+ } else if ([scheme isEqual: @"zip"]) {
+ OFZIPArchive *archive = [OFZIPArchive archiveWithIRI: archiveIRI
+ mode: @"r"];
+
+ stream = [archive streamForReadingFile: path];
+ } else
+ @throw [OFInvalidArgumentException exception];
+
+end:
+ stream = [stream retain];
+
+ objc_autoreleasePoolPop(pool);
+
+ return [stream autorelease];
+}
+@end
+
+@implementation OFArchiveIRIHandlerPathAllowedCharacterSet
+- (instancetype)init
+{
+ self = [super init];
+
+ @try {
+ _characterSet =
+ [[OFCharacterSet IRIPathAllowedCharacterSet] retain];
+ _characterIsMember = (bool (*)(id, SEL, OFUnichar))
+ [_characterSet methodForSelector:
+ @selector(characterIsMember:)];
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (void)dealloc
+{
+ [_characterSet release];
+
+ [super dealloc];
+}
+
+- (bool)characterIsMember: (OFUnichar)character
+{
+ return (character != '!' && _characterIsMember(_characterSet,
+ @selector(characterIsMember:), character));
+}
+@end
+
+OFIRI *
+OFArchiveIRIHandlerIRIForFileInArchive(OFString *scheme,
+ OFString *pathInArchive, OFIRI *archiveIRI)
+{
+ static OFOnceControl onceControl = OFOnceControlInitValue;
+ OFMutableIRI *ret = [OFMutableIRI IRIWithScheme: scheme];
+ void *pool = objc_autoreleasePoolPush();
+ OFString *archiveIRIString;
+
+ OFOnce(&onceControl, initPathAllowedCharacters);
+
+ pathInArchive = [pathInArchive
+ stringByAddingPercentEncodingWithAllowedCharacters:
+ pathAllowedCharacters];
+ archiveIRIString = [archiveIRI.string
+ stringByAddingPercentEncodingWithAllowedCharacters:
+ pathAllowedCharacters];
+
+ ret.percentEncodedPath = [OFString
+ stringWithFormat: @"%@!%@", archiveIRIString, pathInArchive];
+ [ret makeImmutable];
+
+ objc_autoreleasePoolPop(pool);
+
+ return ret;
+}
DELETED src/OFArchiveURIHandler.h
Index: src/OFArchiveURIHandler.h
==================================================================
--- src/OFArchiveURIHandler.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
- *
- * All rights reserved.
- *
- * This file is part of ObjFW. It may be distributed under the terms of the
- * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
- * the packaging of this file.
- *
- * Alternatively, it may be distributed under the terms of the GNU General
- * Public License, either version 2 or 3, which can be found in the file
- * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
- * file.
- */
-
-#import "OFURIHandler.h"
-
-OF_ASSUME_NONNULL_BEGIN
-
-@interface OFArchiveURIHandler: OFURIHandler
-@end
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-extern OFURI *OFArchiveURIHandlerURIForFileInArchive(OFString *, OFString *,
- OFURI *);
-#ifdef __cplusplus
-}
-#endif
-
-OF_ASSUME_NONNULL_END
DELETED src/OFArchiveURIHandler.m
Index: src/OFArchiveURIHandler.m
==================================================================
--- src/OFArchiveURIHandler.m
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
- *
- * All rights reserved.
- *
- * This file is part of ObjFW. It may be distributed under the terms of the
- * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
- * the packaging of this file.
- *
- * Alternatively, it may be distributed under the terms of the GNU General
- * Public License, either version 2 or 3, which can be found in the file
- * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
- * file.
- */
-
-#include "config.h"
-
-#include
-
-#import "OFArchiveURIHandler.h"
-#import "OFCharacterSet.h"
-#import "OFGZIPStream.h"
-#import "OFLHAArchive.h"
-#import "OFStream.h"
-#import "OFTarArchive.h"
-#import "OFURI.h"
-#import "OFZIPArchive.h"
-
-#import "OFInvalidArgumentException.h"
-#import "OFOpenItemFailedException.h"
-
-@interface OFArchiveURIHandlerPathAllowedCharacterSet: OFCharacterSet
-{
- OFCharacterSet *_characterSet;
- bool (*_characterIsMember)(id, SEL, OFUnichar);
-}
-@end
-
-static OFCharacterSet *pathAllowedCharacters;
-
-static void
-initPathAllowedCharacters(void)
-{
- pathAllowedCharacters =
- [[OFArchiveURIHandlerPathAllowedCharacterSet alloc] init];
-}
-
-@implementation OFArchiveURIHandler
-- (OFStream *)openItemAtURI: (OFURI *)URI mode: (OFString *)mode
-{
- void *pool = objc_autoreleasePoolPush();
- OFString *scheme = URI.scheme;
- OFString *percentEncodedPath, *path;
- size_t pos;
- OFURI *archiveURI;
- OFStream *stream;
-
- if (URI.host != nil || URI.port != nil || URI.user != nil ||
- URI.password != nil || URI.query != nil || URI.fragment != nil)
- @throw [OFInvalidArgumentException exception];
-
- if (![mode isEqual: @"r"])
- /*
- * Writing has some implications that are not decided yet: Will
- * it always append to an archive? What happens if the file
- * already exists?
- */
- @throw [OFInvalidArgumentException exception];
-
- /*
- * GZIP only compresses one file and thus has no path inside an
- * archive.
- */
- if ([scheme isEqual: @"gzip"]) {
- stream = [OFURIHandler openItemAtURI: [OFURI URIWithString:
- URI.path]
- mode: @"r"];
- stream = [OFGZIPStream streamWithStream: stream mode: @"r"];
- goto end;
- }
-
- percentEncodedPath = URI.percentEncodedPath;
- pos = [percentEncodedPath rangeOfString: @"!"].location;
-
- if (pos == OFNotFound)
- @throw [OFInvalidArgumentException exception];
-
- archiveURI = [OFURI URIWithString:
- [percentEncodedPath substringWithRange: OFMakeRange(0, pos)]
- .stringByRemovingPercentEncoding];
- path = [percentEncodedPath substringWithRange:
- OFMakeRange(pos + 1, percentEncodedPath.length - pos - 1)]
- .stringByRemovingPercentEncoding;
-
- if ([scheme isEqual: @"lha"]) {
- OFLHAArchive *archive = [OFLHAArchive archiveWithURI: archiveURI
- mode: @"r"];
- OFLHAArchiveEntry *entry;
-
- while ((entry = [archive nextEntry]) != nil) {
- if ([entry.fileName isEqual: path]) {
- stream = [archive streamForReadingCurrentEntry];
- goto end;
- }
- }
-
- @throw [OFOpenItemFailedException exceptionWithURI: URI
- mode: mode
- errNo: ENOENT];
- } else if ([scheme isEqual: @"tar"]) {
- OFTarArchive *archive = [OFTarArchive archiveWithURI: archiveURI
- mode: @"r"];
- OFTarArchiveEntry *entry;
-
- while ((entry = [archive nextEntry]) != nil) {
- if ([entry.fileName isEqual: path]) {
- stream = [archive streamForReadingCurrentEntry];
- goto end;
- }
- }
-
- @throw [OFOpenItemFailedException exceptionWithURI: URI
- mode: mode
- errNo: ENOENT];
- } else if ([scheme isEqual: @"zip"]) {
- OFZIPArchive *archive = [OFZIPArchive archiveWithURI: archiveURI
- mode: @"r"];
-
- stream = [archive streamForReadingFile: path];
- } else
- @throw [OFInvalidArgumentException exception];
-
-end:
- stream = [stream retain];
-
- objc_autoreleasePoolPop(pool);
-
- return [stream autorelease];
-}
-@end
-
-@implementation OFArchiveURIHandlerPathAllowedCharacterSet
-- (instancetype)init
-{
- self = [super init];
-
- @try {
- _characterSet =
- [[OFCharacterSet URIPathAllowedCharacterSet] retain];
- _characterIsMember = (bool (*)(id, SEL, OFUnichar))
- [_characterSet methodForSelector:
- @selector(characterIsMember:)];
- } @catch (id e) {
- [self release];
- @throw e;
- }
-
- return self;
-}
-
-- (void)dealloc
-{
- [_characterSet release];
-
- [super dealloc];
-}
-
-- (bool)characterIsMember: (OFUnichar)character
-{
- return (character != '!' && _characterIsMember(_characterSet,
- @selector(characterIsMember:), character));
-}
-@end
-
-OFURI *
-OFArchiveURIHandlerURIForFileInArchive(OFString *scheme,
- OFString *pathInArchive, OFURI *archiveURI)
-{
- static OFOnceControl onceControl = OFOnceControlInitValue;
- OFMutableURI *ret = [OFMutableURI URIWithScheme: scheme];
- void *pool = objc_autoreleasePoolPush();
- OFString *archiveURIString;
-
- OFOnce(&onceControl, initPathAllowedCharacters);
-
- pathInArchive = [pathInArchive
- stringByAddingPercentEncodingWithAllowedCharacters:
- pathAllowedCharacters];
- archiveURIString = [archiveURI.string
- stringByAddingPercentEncodingWithAllowedCharacters:
- pathAllowedCharacters];
-
- ret.percentEncodedPath = [OFString
- stringWithFormat: @"%@!%@", archiveURIString, pathInArchive];
- [ret makeImmutable];
-
- objc_autoreleasePoolPop(pool);
-
- return ret;
-}
Index: src/OFArray+Private.h
==================================================================
--- src/OFArray+Private.h
+++ src/OFArray+Private.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFArray.h
==================================================================
--- src/OFArray.h
+++ src/OFArray.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -23,11 +23,10 @@
#include
#import "OFObject.h"
#import "OFCollection.h"
#import "OFEnumerator.h"
-#import "OFSerialization.h"
#import "OFJSONRepresentation.h"
#import "OFMessagePackRepresentation.h"
OF_ASSUME_NONNULL_BEGIN
@@ -100,11 +99,11 @@
* @brief An abstract class for storing objects in an array.
*
* @note Subclasses must implement @ref count and @ref objectAtIndex:.
*/
@interface OFArray OF_GENERIC(ObjectType): OFObject
#if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN)
# define ObjectType id
#endif
/**
@@ -183,10 +182,17 @@
* @return A new autoreleased OFArray
*/
+ (instancetype)arrayWithObjects: (ObjectType const _Nonnull *_Nonnull)objects
count: (size_t)count;
+/**
+ * @brief Initializes an OFArray with no objects.
+ *
+ * @return An initialized OFArray
+ */
+- (instancetype)init OF_DESIGNATED_INITIALIZER;
+
/**
* @brief Initializes an OFArray with the specified object.
*
* @param object An object
* @return An initialized OFArray
@@ -226,11 +232,11 @@
* @param objects A C array of objects
* @param count The length of the C array
* @return An initialized OFArray
*/
- (instancetype)initWithObjects: (ObjectType const _Nonnull *_Nonnull)objects
- count: (size_t)count;
+ count: (size_t)count OF_DESIGNATED_INITIALIZER;
/**
* @brief Returns an OFEnumerator to enumerate through all objects of the array.
*
* @return An OFEnumerator to enumerate through all objects of the array
@@ -403,10 +409,24 @@
*/
- (OFArray OF_GENERIC(ObjectType) *)
sortedArrayUsingSelector: (SEL)selector
options: (OFArraySortOptions)options;
+/**
+ * @brief Returns a copy of the array sorted using the specified function and
+ * options.
+ *
+ * @param compare The function to use to sort the array
+ * @param context Context passed to the function to compare
+ * @param options The options to use when sorting the array
+ * @return A sorted copy of the array
+ */
+- (OFArray OF_GENERIC(ObjectType) *)
+ sortedArrayUsingFunction: (OFCompareFunction)compare
+ context: (nullable void *)context
+ options: (OFArraySortOptions)options;
+
#ifdef OF_HAVE_BLOCKS
/**
* @brief Returns a copy of the array sorted using the specified selector and
* options.
*
Index: src/OFArray.m
==================================================================
--- src/OFArray.m
+++ src/OFArray.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -16,20 +16,17 @@
#include "config.h"
#include
#include
-#include
-
#import "OFArray.h"
#import "OFArray+Private.h"
-#import "OFAdjacentArray.h"
+#import "OFConcreteArray.h"
#import "OFData.h"
#import "OFNull.h"
#import "OFString.h"
#import "OFSubarray.h"
-#import "OFXMLElement.h"
#import "OFEnumerationMutationException.h"
#import "OFInvalidArgumentException.h"
#import "OFOutOfRangeException.h"
@@ -45,82 +42,69 @@
@interface OFPlaceholderArray: OFArray
@end
@implementation OFPlaceholderArray
+#ifdef __clang__
+/* We intentionally don't call into super, so silence the warning. */
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wunknown-pragmas"
+# pragma clang diagnostic ignored "-Wobjc-designated-initializers"
+#endif
- (instancetype)init
{
- return (id)[[OFAdjacentArray alloc] init];
+ return (id)[[OFConcreteArray alloc] init];
}
- (instancetype)initWithObject: (id)object
{
- return (id)[[OFAdjacentArray alloc] initWithObject: object];
+ return (id)[[OFConcreteArray alloc] initWithObject: object];
}
- (instancetype)initWithObjects: (id)firstObject, ...
{
id ret;
va_list arguments;
va_start(arguments, firstObject);
- ret = [[OFAdjacentArray alloc] initWithObject: firstObject
+ ret = [[OFConcreteArray alloc] initWithObject: firstObject
arguments: arguments];
va_end(arguments);
return ret;
}
- (instancetype)initWithObject: (id)firstObject
arguments: (va_list)arguments
{
- return (id)[[OFAdjacentArray alloc] initWithObject: firstObject
+ return (id)[[OFConcreteArray alloc] initWithObject: firstObject
arguments: arguments];
}
- (instancetype)initWithArray: (OFArray *)array
{
- return (id)[[OFAdjacentArray alloc] initWithArray: array];
+ return (id)[[OFConcreteArray alloc] initWithArray: array];
}
- (instancetype)initWithObjects: (id const *)objects
count: (size_t)count
{
- return (id)[[OFAdjacentArray alloc] initWithObjects: objects
+ return (id)[[OFConcreteArray alloc] initWithObjects: objects
count: count];
}
-
-- (instancetype)initWithSerialization: (OFXMLElement *)element
-{
- return (id)[[OFAdjacentArray alloc] initWithSerialization: element];
-}
-
-- (instancetype)retain
-{
- return self;
-}
-
-- (instancetype)autorelease
-{
- return self;
-}
-
-- (void)release
-{
-}
-
-- (void)dealloc
-{
- OF_DEALLOC_UNSUPPORTED
-}
+#ifdef __clang__
+# pragma clang diagnostic pop
+#endif
+
+OF_SINGLETON_METHODS
@end
@implementation OFArray
+ (void)initialize
{
if (self == [OFArray class])
- placeholder.isa = [OFPlaceholderArray class];
+ object_setClass((id)&placeholder, [OFPlaceholderArray class]);
}
+ (instancetype)alloc
{
if (self == [OFArray class])
@@ -164,11 +148,12 @@
count: count] autorelease];
}
- (instancetype)init
{
- if ([self isMemberOfClass: [OFArray class]]) {
+ if ([self isMemberOfClass: [OFArray class]] ||
+ [self isMemberOfClass: [OFMutableArray class]]) {
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
@@ -180,16 +165,11 @@
return [super init];
}
- (instancetype)initWithObject: (id)object
{
- if (object == nil) {
- [self release];
- @throw [OFInvalidArgumentException exception];
- }
-
- return [self initWithObjects: object, nil];
+ return [self initWithObjects: &object count: 1];
}
- (instancetype)initWithObjects: (id)firstObject, ...
{
id ret;
@@ -200,31 +180,85 @@
va_end(arguments);
return ret;
}
-- (instancetype)initWithObject: (id)firstObject
- arguments: (va_list)arguments
+- (instancetype)initWithObject: (id)firstObject arguments: (va_list)arguments
{
- OF_INVALID_INIT_METHOD
+ size_t count = 1;
+ va_list argumentsCopy;
+ id *objects;
+
+ if (firstObject == nil)
+ return [self init];
+
+ va_copy(argumentsCopy, arguments);
+ while (va_arg(argumentsCopy, id) != nil)
+ count++;
+
+ @try {
+ objects = OFAllocMemory(count, sizeof(id));
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ @try {
+ objects[0] = firstObject;
+
+ for (size_t i = 1; i < count; i++) {
+ objects[i] = va_arg(arguments, id);
+ OFEnsure(objects[i] != nil);
+ }
+
+ self = [self initWithObjects: objects count: count];
+ } @finally {
+ OFFreeMemory(objects);
+ }
+
+ return self;
}
- (instancetype)initWithArray: (OFArray *)array
{
- OF_INVALID_INIT_METHOD
+ id *objects;
+ size_t count;
+
+ @try {
+ count = array.count;
+ objects = OFAllocMemory(count, sizeof(id));
+
+ [array getObjects: objects
+ inRange: OFMakeRange(0, count)];
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ @try {
+ self = [self initWithObjects: objects count: count];
+ } @finally {
+ OFFreeMemory(objects);
+ }
+
+ return self;
}
+#ifdef __clang__
+/* We intentionally don't call into super, so silence the warning. */
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wunknown-pragmas"
+# pragma clang diagnostic ignored "-Wobjc-designated-initializers"
+#endif
- (instancetype)initWithObjects: (id const *)objects
count: (size_t)count
{
OF_INVALID_INIT_METHOD
}
-
-- (instancetype)initWithSerialization: (OFXMLElement *)element
-{
- OF_INVALID_INIT_METHOD
-}
+#ifdef __clang__
+# pragma clang diagnostic pop
+#endif
- (size_t)count
{
OF_UNRECOGNIZED_SELECTOR
}
@@ -375,11 +409,12 @@
if (range.length > SIZE_MAX - range.location ||
range.location + range.length < self.count)
@throw [OFOutOfRangeException exception];
if (![self isKindOfClass: [OFMutableArray class]])
- return [OFSubarray arrayWithArray: self range: range];
+ return [[[OFSubarray alloc] initWithArray: self
+ range: range] autorelease];
buffer = OFAllocMemory(range.length, sizeof(*buffer));
@try {
[self getObjects: buffer inRange: range];
@@ -548,37 +583,10 @@
[ret makeImmutable];
return [ret autorelease];
}
-- (OFXMLElement *)XMLElementBySerializing
-{
- void *pool = objc_autoreleasePoolPush();
- OFXMLElement *element;
-
- if ([self isKindOfClass: [OFMutableArray class]])
- element = [OFXMLElement elementWithName: @"OFMutableArray"
- namespace: OFSerializationNS];
- else
- element = [OFXMLElement elementWithName: @"OFArray"
- namespace: OFSerializationNS];
-
- for (id object in self) {
- void *pool2 = objc_autoreleasePoolPush();
-
- [element addChild: object.XMLElementBySerializing];
-
- objc_autoreleasePoolPop(pool2);
- }
-
- [element retain];
-
- objc_autoreleasePoolPop(pool);
-
- return [element autorelease];
-}
-
- (OFString *)JSONRepresentation
{
return [self of_JSONRepresentationWithOptions: 0 depth: 0];
}
@@ -687,11 +695,11 @@
[data addItems: child.items count: child.count];
objc_autoreleasePoolPop(pool2);
}
- assert(i == count);
+ OFAssert(i == count);
[data makeImmutable];
objc_autoreleasePoolPop(pool);
@@ -725,10 +733,20 @@
OFMutableArray *new = [[self mutableCopy] autorelease];
[new sortUsingSelector: selector options: options];
[new makeImmutable];
return new;
}
+
+- (OFArray *)sortedArrayUsingFunction: (OFCompareFunction)compare
+ context: (void *)context
+ options: (OFArraySortOptions)options
+{
+ OFMutableArray *new = [[self mutableCopy] autorelease];
+ [new sortUsingFunction: compare context: context options: options];
+ [new makeImmutable];
+ return new;
+}
#ifdef OF_HAVE_BLOCKS
- (OFArray *)sortedArrayUsingComparator: (OFComparator)comparator
options: (OFArraySortOptions)options
{
@@ -749,10 +767,11 @@
- (int)countByEnumeratingWithState: (OFFastEnumerationState *)state
objects: (id *)objects
count: (int)count
{
+ static unsigned long dummyMutations;
OFRange range = OFMakeRange(state->state, count);
if (range.length > SIZE_MAX - range.location)
@throw [OFOutOfRangeException exception];
@@ -764,11 +783,11 @@
if (range.location + range.length > ULONG_MAX)
@throw [OFOutOfRangeException exception];
state->state = (unsigned long)(range.location + range.length);
state->itemsPtr = objects;
- state->mutationsPtr = (unsigned long *)self;
+ state->mutationsPtr = &dummyMutations;
return (int)range.length;
}
- (OFEnumerator *)objectEnumerator
Index: src/OFAsyncIPSocketConnector.h
==================================================================
--- src/OFAsyncIPSocketConnector.h
+++ src/OFAsyncIPSocketConnector.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFAsyncIPSocketConnector.m
==================================================================
--- src/OFAsyncIPSocketConnector.m
+++ src/OFAsyncIPSocketConnector.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFAtomic.h
==================================================================
--- src/OFAtomic.h
+++ src/OFAtomic.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -167,11 +167,11 @@
static OF_INLINE void
OFReleaseMemoryBarrier(void)
{
/* nop */
}
-#elif (defined(OF_X86_64) || defined(OF_X86)) && defined(__GNUC__)
+#elif (defined(OF_AMD64) || defined(OF_X86)) && defined(__GNUC__)
# import "platform/x86/OFAtomic.h"
#elif defined(OF_POWERPC) && defined(__GNUC__) && !defined(__APPLE_CC__) && \
!defined(OF_AIX)
# import "platform/PowerPC/OFAtomic.h"
#elif defined(OF_HAVE_ATOMIC_BUILTINS)
Index: src/OFBase64.h
==================================================================
--- src/OFBase64.h
+++ src/OFBase64.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFBase64.m
==================================================================
--- src/OFBase64.m
+++ src/OFBase64.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFBitSetCharacterSet.h
==================================================================
--- src/OFBitSetCharacterSet.h
+++ src/OFBitSetCharacterSet.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFBitSetCharacterSet.m
==================================================================
--- src/OFBitSetCharacterSet.m
+++ src/OFBitSetCharacterSet.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFBlock.h
==================================================================
--- src/OFBlock.h
+++ src/OFBlock.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFBlock.m
==================================================================
--- src/OFBlock.m
+++ src/OFBlock.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -24,10 +24,11 @@
# import "OFAtomic.h"
#endif
#ifdef OF_HAVE_THREADS
# import "OFPlainMutex.h"
#endif
+#import "OFString.h"
#import "OFAllocFailedException.h"
#import "OFInitializationFailedException.h"
#if defined(OF_OBJFW_RUNTIME)
@@ -161,11 +162,11 @@
# endif
#endif
static struct {
Class isa;
-} alloc_failed_exception;
+} allocFailedException;
#ifndef OF_HAVE_ATOMIC_OPS
# define numSpinlocks 8 /* needs to be a power of 2 */
# define SPINLOCK_HASH(p) ((uintptr_t)p >> 4) & (numSpinlocks - 1)
static OFSpinlock blockSpinlocks[numSpinlocks];
@@ -179,14 +180,13 @@
if ([(id)block isMemberOfClass: (Class)&_NSConcreteStackBlock]) {
struct Block *copy;
if ((copy = malloc(block->descriptor->size)) == NULL) {
- alloc_failed_exception.isa =
- [OFAllocFailedException class];
- @throw (OFAllocFailedException *)
- &alloc_failed_exception;
+ object_setClass((id)&allocFailedException,
+ [OFAllocFailedException class]);
+ @throw (OFAllocFailedException *)&allocFailedException;
}
memcpy(copy, block, block->descriptor->size);
object_setClass((id)copy, (Class)&_NSConcreteMallocBlock);
copy->flags++;
@@ -268,14 +268,14 @@
src = src->forwarding;
if ((src->flags & OFBlockRefCountMask) == 0) {
if ((*dst = malloc(src->size)) == NULL) {
- alloc_failed_exception.isa =
- [OFAllocFailedException class];
+ object_setClass((id)&allocFailedException,
+ [OFAllocFailedException class]);
@throw (OFAllocFailedException *)
- &alloc_failed_exception;
+ &allocFailedException;
}
memcpy(*dst, src, src->size);
(*dst)->flags =
((*dst)->flags & ~OFBlockRefCountMask) | 1;
DELETED src/OFBytesValue.h
Index: src/OFBytesValue.h
==================================================================
--- src/OFBytesValue.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
- *
- * All rights reserved.
- *
- * This file is part of ObjFW. It may be distributed under the terms of the
- * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
- * the packaging of this file.
- *
- * Alternatively, it may be distributed under the terms of the GNU General
- * Public License, either version 2 or 3, which can be found in the file
- * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
- * file.
- */
-
-#import "OFValue.h"
-
-OF_ASSUME_NONNULL_BEGIN
-
-@interface OFBytesValue: OFValue
-{
- size_t _size;
- void *_bytes;
- const char *_objCType;
-}
-@end
-
-OF_ASSUME_NONNULL_END
DELETED src/OFBytesValue.m
Index: src/OFBytesValue.m
==================================================================
--- src/OFBytesValue.m
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
- *
- * All rights reserved.
- *
- * This file is part of ObjFW. It may be distributed under the terms of the
- * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
- * the packaging of this file.
- *
- * Alternatively, it may be distributed under the terms of the GNU General
- * Public License, either version 2 or 3, which can be found in the file
- * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
- * file.
- */
-
-#import "OFBytesValue.h"
-#import "OFMethodSignature.h"
-
-#import "OFOutOfRangeException.h"
-
-@implementation OFBytesValue
-@synthesize objCType = _objCType;
-
-- (instancetype)initWithBytes: (const void *)bytes
- objCType: (const char *)objCType
-{
- self = [super init];
-
- @try {
- _size = OFSizeOfTypeEncoding(objCType);
- _objCType = objCType;
- _bytes = OFAllocMemory(1, _size);
-
- memcpy(_bytes, bytes, _size);
- } @catch (id e) {
- [self release];
- @throw e;
- }
-
- return self;
-}
-
-- (void)dealloc
-{
- OFFreeMemory(_bytes);
-
- [super dealloc];
-}
-
-- (void)getValue: (void *)value size: (size_t)size
-{
- if (size != _size)
- @throw [OFOutOfRangeException exception];
-
- memcpy(value, _bytes, _size);
-}
-@end
Index: src/OFCRC16.h
==================================================================
--- src/OFCRC16.h
+++ src/OFCRC16.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFCRC16.m
==================================================================
--- src/OFCRC16.m
+++ src/OFCRC16.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFCRC32.h
==================================================================
--- src/OFCRC32.h
+++ src/OFCRC32.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFCRC32.m
==================================================================
--- src/OFCRC32.m
+++ src/OFCRC32.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFCharacterSet.h
==================================================================
--- src/OFCharacterSet.h
+++ src/OFCharacterSet.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFCharacterSet.m
==================================================================
--- src/OFCharacterSet.m
+++ src/OFCharacterSet.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -54,37 +54,19 @@
- (instancetype)initWithRange: (OFRange)range
{
return (id)[[OFRangeCharacterSet alloc] initWithRange: range];
}
-- (instancetype)retain
-{
- return self;
-}
-
-- (instancetype)autorelease
-{
- return self;
-}
-
-- (void)release
-{
-}
-
-- (void)dealloc
-{
- OF_DEALLOC_UNSUPPORTED
-}
+OF_SINGLETON_METHODS
@end
@implementation OFCharacterSet
+ (void)initialize
{
- if (self != [OFCharacterSet class])
- return;
-
- placeholder.isa = [OFPlaceholderCharacterSet class];
+ if (self == [OFCharacterSet class])
+ object_setClass((id)&placeholder,
+ [OFPlaceholderCharacterSet class]);
}
+ (instancetype)alloc
{
if (self == [OFCharacterSet class])
@@ -149,29 +131,10 @@
initWithCharacterSet: self] autorelease];
}
@end
@implementation OFWhitespaceCharacterSet
-- (instancetype)autorelease
-{
- return self;
-}
-
-- (instancetype)retain
-{
- return self;
-}
-
-- (void)release
-{
-}
-
-- (unsigned int)retainCount
-{
- return OFMaxRetainCount;
-}
-
- (bool)characterIsMember: (OFUnichar)character
{
switch (character) {
case 0x0009:
case 0x0020:
@@ -194,6 +157,8 @@
return true;
default:
return false;
}
}
+
+OF_SINGLETON_METHODS
@end
Index: src/OFCollection.h
==================================================================
--- src/OFCollection.h
+++ src/OFCollection.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFColor.h
==================================================================
--- src/OFColor.h
+++ src/OFColor.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -21,15 +21,10 @@
* @class OFColor OFColor.h ObjFW/OFColor.h
*
* @brief A class for storing a color.
*/
@interface OFColor: OFObject
-{
- float _red, _green, _blue, _alpha;
- OF_RESERVE_IVARS(OFColor, 4)
-}
-
#ifdef OF_HAVE_CLASS_PROPERTIES
@property (class, readonly, nonatomic) OFColor *black;
@property (class, readonly, nonatomic) OFColor *silver;
@property (class, readonly, nonatomic) OFColor *grey;
@property (class, readonly, nonatomic) OFColor *white;
Index: src/OFColor.m
==================================================================
--- src/OFColor.m
+++ src/OFColor.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -12,27 +12,95 @@
* LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
* file.
*/
#include "config.h"
+
+#include
#import "OFColor.h"
+#import "OFConcreteColor.h"
#import "OFOnce.h"
+#import "OFString.h"
+#import "OFTaggedPointerColor.h"
+
+@interface OFPlaceholderColor: OFColor
+@end
+
+@interface OFConcreteColorSingleton: OFConcreteColor
+@end
+
+static struct {
+ Class isa;
+} placeholder;
+
+#ifdef OF_OBJFW_RUNTIME
+static const float allowedImprecision = 0.0000001;
+#endif
+
+@implementation OFPlaceholderColor
+- (instancetype)initWithRed: (float)red
+ green: (float)green
+ blue: (float)blue
+ alpha: (float)alpha
+{
+#ifdef OF_OBJFW_RUNTIME
+ uint8_t redInt = nearbyintf(red * 255);
+ uint8_t greenInt = nearbyintf(green * 255);
+ uint8_t blueInt = nearbyintf(blue * 255);
+
+ if (fabsf(red * 255 - redInt) < allowedImprecision &&
+ fabsf(green * 255 - greenInt) < allowedImprecision &&
+ fabsf(blue * 255 - blueInt) < allowedImprecision && alpha == 1) {
+ id ret = [OFTaggedPointerColor colorWithRed: redInt
+ green: greenInt
+ blue: blueInt];
+
+ if (ret != nil)
+ return ret;
+ }
+#endif
+
+ return (id)[[OFConcreteColor alloc] initWithRed: red
+ green: green
+ blue: blue
+ alpha: alpha];
+}
+
+OF_SINGLETON_METHODS
+@end
-#import "OFInvalidArgumentException.h"
+@implementation OFConcreteColorSingleton
+OF_SINGLETON_METHODS
+@end
@implementation OFColor
++ (void)initialize
+{
+ if (self == [OFColor class])
+ object_setClass((id)&placeholder, [OFPlaceholderColor class]);
+}
+
++ (instancetype)alloc
+{
+ if (self == [OFColor class])
+ return (id)&placeholder;
+
+ return [super alloc];
+}
+
#define PREDEFINED_COLOR(name, redValue, greenValue, blueValue) \
static OFColor *name##Color = nil; \
\
static void \
initPredefinedColor_##name(void) \
{ \
- name##Color = [[OFColor alloc] initWithRed: redValue \
- green: greenValue \
- blue: blueValue \
- alpha: 1]; \
+ name##Color = [[OFConcreteColorSingleton alloc] \
+ initWithRed: redValue \
+ green: greenValue \
+ blue: blueValue \
+ alpha: 1]; \
} \
\
+ (OFColor *)name \
{ \
static OFOnceControl onceControl = OFOnceControlInitValue; \
@@ -72,75 +140,78 @@
- (instancetype)initWithRed: (float)red
green: (float)green
blue: (float)blue
alpha: (float)alpha
{
- self = [super init];
-
- @try {
- if (red < 0.0 || red > 1.0 ||
- green < 0.0 || green > 1.0 ||
- blue < 0.0 || blue > 1.0 ||
- alpha < 0.0 || alpha > 1.0)
- @throw [OFInvalidArgumentException exception];
-
- _red = red;
- _green = green;
- _blue = blue;
- _alpha = alpha;
- } @catch (id e) {
- [self release];
- @throw e;
- }
-
- return self;
+ if ([self isMemberOfClass: [OFColor class]]) {
+ @try {
+ [self doesNotRecognizeSelector: _cmd];
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ abort();
+ }
+
+ return [super init];
}
- (bool)isEqual: (id)object
{
OFColor *other;
+ float red, green, blue, alpha;
+ float otherRed, otherGreen, otherBlue, otherAlpha;
if (object == self)
return true;
if (![object isKindOfClass: [OFColor class]])
return false;
other = object;
-
- if (other->_red != _red)
- return false;
- if (other->_green != _green)
- return false;
- if (other->_blue != _blue)
- return false;
- if (other->_alpha != _alpha)
+ [self getRed: &red green: &green blue: &blue alpha: &alpha];
+ [other getRed: &otherRed
+ green: &otherGreen
+ blue: &otherBlue
+ alpha: &otherAlpha];
+
+ if (otherRed != red)
+ return false;
+ if (otherGreen != green)
+ return false;
+ if (otherBlue != blue)
+ return false;
+ if (otherAlpha != alpha)
return false;
return true;
}
- (unsigned long)hash
{
+ float red, green, blue, alpha;
unsigned long hash;
float tmp;
+ [self getRed: &red green: &green blue: &blue alpha: &alpha];
+
OFHashInit(&hash);
- tmp = OFToLittleEndianFloat(_red);
+ tmp = OFToLittleEndianFloat(red);
+ for (uint_fast8_t i = 0; i < sizeof(float); i++)
+ OFHashAddByte(&hash, ((char *)&tmp)[i]);
+
+ tmp = OFToLittleEndianFloat(green);
for (uint_fast8_t i = 0; i < sizeof(float); i++)
OFHashAddByte(&hash, ((char *)&tmp)[i]);
- tmp = OFToLittleEndianFloat(_green);
+ tmp = OFToLittleEndianFloat(blue);
for (uint_fast8_t i = 0; i < sizeof(float); i++)
OFHashAddByte(&hash, ((char *)&tmp)[i]);
- tmp = OFToLittleEndianFloat(_blue);
- for (uint_fast8_t i = 0; i < sizeof(float); i++)
- OFHashAddByte(&hash, ((char *)&tmp)[i]);
-
- tmp = OFToLittleEndianFloat(_alpha);
+ tmp = OFToLittleEndianFloat(alpha);
for (uint_fast8_t i = 0; i < sizeof(float); i++)
OFHashAddByte(&hash, ((char *)&tmp)[i]);
OFHashFinalize(&hash);
@@ -150,13 +221,19 @@
- (void)getRed: (float *)red
green: (float *)green
blue: (float *)blue
alpha: (float *)alpha
{
- *red = _red;
- *green = _green;
- *blue = _blue;
+ OF_UNRECOGNIZED_SELECTOR
+}
+
+- (OFString *)description
+{
+ float red, green, blue, alpha;
+
+ [self getRed: &red green: &green blue: &blue alpha: &alpha];
- if (alpha != NULL)
- *alpha = _alpha;
+ return [OFString stringWithFormat:
+ @"<%@ red=%f green=%f blue=%f alpha=%f>",
+ self.class, red, green, blue, alpha];
}
@end
ADDED src/OFConcreteArray.h
Index: src/OFConcreteArray.h
==================================================================
--- /dev/null
+++ src/OFConcreteArray.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#import "OFArray.h"
+
+OF_ASSUME_NONNULL_BEGIN
+
+@class OFMutableData;
+
+@interface OFConcreteArray: OFArray
+{
+ OFMutableData *_array;
+}
+@end
+
+OF_ASSUME_NONNULL_END
ADDED src/OFConcreteArray.m
Index: src/OFConcreteArray.m
==================================================================
--- /dev/null
+++ src/OFConcreteArray.m
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#include "config.h"
+
+#include
+
+#import "OFConcreteArray.h"
+#import "OFConcreteMutableArray.h"
+#import "OFConcreteSubarray.h"
+#import "OFData.h"
+#import "OFString.h"
+
+#import "OFEnumerationMutationException.h"
+#import "OFInvalidArgumentException.h"
+#import "OFOutOfRangeException.h"
+
+@implementation OFConcreteArray
+- (instancetype)init
+{
+ self = [super init];
+
+ @try {
+ _array = [[OFMutableData alloc] initWithItemSize: sizeof(id)];
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (instancetype)initWithObject: (id)object
+{
+ self = [self init];
+
+ @try {
+ if (object == nil)
+ @throw [OFInvalidArgumentException exception];
+
+ [_array addItem: &object];
+ [object retain];
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (instancetype)initWithObject: (id)firstObject arguments: (va_list)arguments
+{
+ self = [self init];
+
+ @try {
+ id object;
+
+ [_array addItem: &firstObject];
+ [firstObject retain];
+
+ while ((object = va_arg(arguments, id)) != nil) {
+ [_array addItem: &object];
+ [object retain];
+ }
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (instancetype)initWithArray: (OFArray *)array
+{
+ id const *objects;
+ size_t count;
+
+ self = [super init];
+
+ if (array == nil)
+ return self;
+
+ @try {
+ objects = array.objects;
+ count = array.count;
+
+ _array = [[OFMutableData alloc] initWithItemSize: sizeof(id)
+ capacity: count];
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ @try {
+ for (size_t i = 0; i < count; i++)
+ [objects[i] retain];
+
+ [_array addItems: objects count: count];
+ } @catch (id e) {
+ for (size_t i = 0; i < count; i++)
+ [objects[i] release];
+
+ /* Prevent double-release of objects */
+ [_array release];
+ _array = nil;
+
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (instancetype)initWithObjects: (id const *)objects count: (size_t)count
+{
+ self = [super init];
+
+ @try {
+ bool ok = true;
+
+ for (size_t i = 0; i < count; i++) {
+ if (objects[i] == nil)
+ ok = false;
+
+ [objects[i] retain];
+ }
+
+ if (!ok)
+ @throw [OFInvalidArgumentException exception];
+
+ _array = [[OFMutableData alloc] initWithItemSize: sizeof(id)
+ capacity: count];
+ [_array addItems: objects count: count];
+ } @catch (id e) {
+ for (size_t i = 0; i < count; i++)
+ [objects[i] release];
+
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (size_t)count
+{
+ return _array.count;
+}
+
+- (id const *)objects
+{
+ return _array.items;
+}
+
+- (id)objectAtIndex: (size_t)idx
+{
+ return *((id *)[_array itemAtIndex: idx]);
+}
+
+- (id)objectAtIndexedSubscript: (size_t)idx
+{
+ return *((id *)[_array itemAtIndex: idx]);
+}
+
+- (void)getObjects: (id *)buffer inRange: (OFRange)range
+{
+ id const *objects = _array.items;
+ size_t count = _array.count;
+
+ if (range.length > SIZE_MAX - range.location ||
+ range.location + range.length > count)
+ @throw [OFOutOfRangeException exception];
+
+ for (size_t i = 0; i < range.length; i++)
+ buffer[i] = objects[range.location + i];
+}
+
+- (size_t)indexOfObject: (id)object
+{
+ id const *objects;
+ size_t count;
+
+ if (object == nil)
+ return OFNotFound;
+
+ objects = _array.items;
+ count = _array.count;
+
+ for (size_t i = 0; i < count; i++)
+ if ([objects[i] isEqual: object])
+ return i;
+
+ return OFNotFound;
+}
+
+- (size_t)indexOfObjectIdenticalTo: (id)object
+{
+ id const *objects;
+ size_t count;
+
+ if (object == nil)
+ return OFNotFound;
+
+ objects = _array.items;
+ count = _array.count;
+
+ for (size_t i = 0; i < count; i++)
+ if (objects[i] == object)
+ return i;
+
+ return OFNotFound;
+}
+
+
+- (OFArray *)objectsInRange: (OFRange)range
+{
+ if (range.length > SIZE_MAX - range.location ||
+ range.location + range.length > _array.count)
+ @throw [OFOutOfRangeException exception];
+
+ if ([self isKindOfClass: [OFMutableArray class]])
+ return [OFArray
+ arrayWithObjects: (id *)_array.items + range.location
+ count: range.length];
+
+ return [[[OFConcreteSubarray alloc] initWithArray: self
+ range: range] autorelease];
+}
+
+- (bool)isEqual: (id)object
+{
+ OFArray *otherArray;
+ id const *objects, *otherObjects;
+ size_t count;
+
+ if (object == self)
+ return true;
+
+ if (![object isKindOfClass: [OFConcreteArray class]] &&
+ ![object isKindOfClass: [OFConcreteMutableArray class]])
+ return [super isEqual: object];
+
+ otherArray = object;
+
+ count = _array.count;
+
+ if (count != otherArray.count)
+ return false;
+
+ objects = _array.items;
+ otherObjects = otherArray.objects;
+
+ for (size_t i = 0; i < count; i++)
+ if (![objects[i] isEqual: otherObjects[i]])
+ return false;
+
+ return true;
+}
+
+- (unsigned long)hash
+{
+ id const *objects = _array.items;
+ size_t count = _array.count;
+ unsigned long hash;
+
+ OFHashInit(&hash);
+
+ for (size_t i = 0; i < count; i++)
+ OFHashAddHash(&hash, [objects[i] hash]);
+
+ OFHashFinalize(&hash);
+
+ return hash;
+}
+
+- (int)countByEnumeratingWithState: (OFFastEnumerationState *)state
+ objects: (id *)objects
+ count: (int)count_
+{
+ static unsigned long dummyMutations;
+ size_t count = _array.count;
+
+ if (count > INT_MAX)
+ /*
+ * Use the implementation from OFArray, which is slower, but can
+ * enumerate in chunks.
+ */
+ return [super countByEnumeratingWithState: state
+ objects: objects
+ count: count_];
+
+ if (state->state >= count)
+ return 0;
+
+ state->state = (unsigned long)count;
+ state->itemsPtr = (id *)_array.items;
+ state->mutationsPtr = &dummyMutations;
+
+ return (int)count;
+}
+
+#ifdef OF_HAVE_BLOCKS
+- (void)enumerateObjectsUsingBlock: (OFArrayEnumerationBlock)block
+{
+ id const *objects = _array.items;
+ size_t count = _array.count;
+ bool stop = false;
+
+ for (size_t i = 0; i < count && !stop; i++)
+ block(objects[i], i, &stop);
+}
+#endif
+
+- (void)dealloc
+{
+ id const *objects = _array.items;
+ size_t count = _array.count;
+
+ for (size_t i = 0; i < count; i++)
+ [objects[i] release];
+
+ [_array release];
+
+ [super dealloc];
+}
+@end
ADDED src/OFConcreteColor.h
Index: src/OFConcreteColor.h
==================================================================
--- /dev/null
+++ src/OFConcreteColor.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#import "OFColor.h"
+
+OF_ASSUME_NONNULL_BEGIN
+
+@interface OFConcreteColor: OFColor
+{
+ float _red, _green, _blue, _alpha;
+}
+@end
+
+OF_ASSUME_NONNULL_END
ADDED src/OFConcreteColor.m
Index: src/OFConcreteColor.m
==================================================================
--- /dev/null
+++ src/OFConcreteColor.m
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#include "config.h"
+
+#import "OFConcreteColor.h"
+
+#import "OFInvalidArgumentException.h"
+
+@implementation OFConcreteColor
+- (instancetype)initWithRed: (float)red
+ green: (float)green
+ blue: (float)blue
+ alpha: (float)alpha
+{
+ self = [super init];
+
+ @try {
+ if (red < 0.0 || red > 1.0 ||
+ green < 0.0 || green > 1.0 ||
+ blue < 0.0 || blue > 1.0 ||
+ alpha < 0.0 || alpha > 1.0)
+ @throw [OFInvalidArgumentException exception];
+
+ _red = red;
+ _green = green;
+ _blue = blue;
+ _alpha = alpha;
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (void)getRed: (float *)red
+ green: (float *)green
+ blue: (float *)blue
+ alpha: (float *)alpha
+{
+ *red = _red;
+ *green = _green;
+ *blue = _blue;
+
+ if (alpha != NULL)
+ *alpha = _alpha;
+}
+@end
+
ADDED src/OFConcreteCountedSet.h
Index: src/OFConcreteCountedSet.h
==================================================================
--- /dev/null
+++ src/OFConcreteCountedSet.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#import "OFCountedSet.h"
+
+OF_ASSUME_NONNULL_BEGIN
+
+@class OFMapTable;
+
+@interface OFConcreteCountedSet: OFCountedSet
+{
+ OFMapTable *_mapTable;
+}
+@end
+
+OF_ASSUME_NONNULL_END
ADDED src/OFConcreteCountedSet.m
Index: src/OFConcreteCountedSet.m
==================================================================
--- /dev/null
+++ src/OFConcreteCountedSet.m
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#include "config.h"
+
+#import "OFConcreteCountedSet.h"
+#import "OFArray.h"
+#import "OFConcreteMutableSet.h"
+#import "OFMapTable.h"
+#import "OFString.h"
+#import "OFXMLAttribute.h"
+
+#import "OFInvalidArgumentException.h"
+#import "OFInvalidFormatException.h"
+#import "OFEnumerationMutationException.h"
+#import "OFOutOfRangeException.h"
+
+@implementation OFConcreteCountedSet
++ (void)initialize
+{
+ if (self == [OFConcreteCountedSet class])
+ [self inheritMethodsFromClass: [OFConcreteMutableSet class]];
+}
+
+- (instancetype)initWithSet: (OFSet *)set
+{
+ self = [self init];
+
+ @try {
+ void *pool = objc_autoreleasePoolPush();
+
+ if ([set isKindOfClass: [OFCountedSet class]]) {
+ OFCountedSet *countedSet = (OFCountedSet *)set;
+
+ for (id object in countedSet) {
+ size_t count =
+ [countedSet countForObject: object];
+
+ for (size_t i = 0; i < count; i++)
+ [self addObject: object];
+ }
+ } else
+ for (id object in set)
+ [self addObject: object];
+
+ objc_autoreleasePoolPop(pool);
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (instancetype)initWithArray: (OFArray *)array
+{
+ self = [self init];
+
+ @try {
+ id const *objects = array.objects;
+ size_t count = array.count;
+
+ for (size_t i = 0; i < count; i++)
+ [self addObject: objects[i]];
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (instancetype)initWithObjects: (id const *)objects count: (size_t)count
+{
+ self = [self init];
+
+ @try {
+ for (size_t i = 0; i < count; i++)
+ [self addObject: objects[i]];
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (instancetype)initWithObject: (id)firstObject arguments: (va_list)arguments
+{
+ self = [self init];
+
+ @try {
+ id object;
+
+ [self addObject: firstObject];
+
+ while ((object = va_arg(arguments, id)) != nil)
+ [self addObject: object];
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (size_t)countForObject: (id)object
+{
+ return (size_t)(uintptr_t)[_mapTable objectForKey: object];
+}
+
+#ifdef OF_HAVE_BLOCKS
+- (void)enumerateObjectsAndCountUsingBlock: (OFCountedSetEnumerationBlock)block
+{
+ @try {
+ [_mapTable enumerateKeysAndObjectsUsingBlock:
+ ^ (void *key, void *object, bool *stop) {
+ block(key, (size_t)(uintptr_t)object, stop);
+ }];
+ } @catch (OFEnumerationMutationException *e) {
+ @throw [OFEnumerationMutationException
+ exceptionWithObject: self];
+ }
+}
+#endif
+
+- (void)addObject: (id)object
+{
+ size_t count = (size_t)(uintptr_t)[_mapTable objectForKey: object];
+
+ if (SIZE_MAX - count < 1 || UINTPTR_MAX - count < 1)
+ @throw [OFOutOfRangeException exception];
+
+ [_mapTable setObject: (void *)(uintptr_t)(count + 1) forKey: object];
+}
+
+- (void)removeObject: (id)object
+{
+ size_t count = (size_t)(uintptr_t)[_mapTable objectForKey: object];
+
+ if (count == 0)
+ return;
+
+ count--;
+
+ if (count > 0)
+ [_mapTable setObject: (void *)(uintptr_t)count forKey: object];
+ else
+ [_mapTable removeObjectForKey: object];
+}
+
+- (void)removeAllObjects
+{
+ [_mapTable removeAllObjects];
+}
+
+- (void)makeImmutable
+{
+}
+@end
ADDED src/OFConcreteData.h
Index: src/OFConcreteData.h
==================================================================
--- /dev/null
+++ src/OFConcreteData.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#import "OFData.h"
+
+OF_ASSUME_NONNULL_BEGIN
+
+@interface OFConcreteData: OFData
+{
+ unsigned char *_Nullable _items;
+ size_t _capacity, _count, _itemSize;
+ bool _freeWhenDone;
+}
+@end
+
+OF_ASSUME_NONNULL_END
ADDED src/OFConcreteData.m
Index: src/OFConcreteData.m
==================================================================
--- /dev/null
+++ src/OFConcreteData.m
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#include "config.h"
+
+#include
+#include
+
+#import "OFConcreteData.h"
+
+#import "OFInvalidArgumentException.h"
+#import "OFOutOfRangeException.h"
+
+@implementation OFConcreteData
+- (instancetype)init
+{
+ return [self initWithItemSize: 1];
+}
+
+- (instancetype)initWithItemSize: (size_t)itemSize
+{
+ self = [super init];
+
+ @try {
+ if (itemSize == 0)
+ @throw [OFInvalidArgumentException exception];
+
+ _itemSize = itemSize;
+ _freeWhenDone = true;
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (instancetype)initWithItems: (const void *)items
+ count: (size_t)count
+ itemSize: (size_t)itemSize
+{
+ self = [super init];
+
+ @try {
+ if (itemSize == 0)
+ @throw [OFInvalidArgumentException exception];
+
+ _items = OFAllocMemory(count, itemSize);
+ _capacity = _count = count;
+ _itemSize = itemSize;
+ _freeWhenDone = true;
+
+ memcpy(_items, items, count * itemSize);
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (instancetype)initWithItemsNoCopy: (void *)items
+ count: (size_t)count
+ itemSize: (size_t)itemSize
+ freeWhenDone: (bool)freeWhenDone
+{
+ self = [super init];
+
+ @try {
+ if (itemSize == 0)
+ @throw [OFInvalidArgumentException exception];
+
+ _items = (unsigned char *)items;
+ _capacity = _count = count;
+ _itemSize = itemSize;
+ _freeWhenDone = freeWhenDone;
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (void)dealloc
+{
+ if (_freeWhenDone)
+ OFFreeMemory(_items);
+
+ [super dealloc];
+}
+
+- (size_t)count
+{
+ return _count;
+}
+
+- (size_t)itemSize
+{
+ return _itemSize;
+}
+
+- (const void *)items
+{
+ return _items;
+}
+@end
ADDED src/OFConcreteDate.h
Index: src/OFConcreteDate.h
==================================================================
--- /dev/null
+++ src/OFConcreteDate.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#import "OFDate.h"
+
+OF_ASSUME_NONNULL_BEGIN
+
+@interface OFConcreteDate: OFDate
+{
+ OFTimeInterval _seconds;
+}
+@end
+
+OF_ASSUME_NONNULL_END
ADDED src/OFConcreteDate.m
Index: src/OFConcreteDate.m
==================================================================
--- /dev/null
+++ src/OFConcreteDate.m
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#import "OFConcreteDate.h"
+
+@implementation OFConcreteDate
+- (instancetype)initWithTimeIntervalSince1970: (OFTimeInterval)seconds
+{
+ self = [super initWithTimeIntervalSince1970: seconds];
+
+ _seconds = seconds;
+
+ return self;
+}
+
+- (OFTimeInterval)timeIntervalSince1970
+{
+ return _seconds;
+}
+@end
ADDED src/OFConcreteDictionary.h
Index: src/OFConcreteDictionary.h
==================================================================
--- /dev/null
+++ src/OFConcreteDictionary.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#import "OFDictionary.h"
+
+OF_ASSUME_NONNULL_BEGIN
+
+@class OFMapTable;
+@class OFMapTableEnumerator;
+
+@interface OFConcreteDictionary: OFDictionary
+{
+ OFMapTable *_mapTable;
+}
+
+- (instancetype)initWithCapacity: (size_t)capacity;
+@end
+
+OF_ASSUME_NONNULL_END
ADDED src/OFConcreteDictionary.m
Index: src/OFConcreteDictionary.m
==================================================================
--- /dev/null
+++ src/OFConcreteDictionary.m
@@ -0,0 +1,383 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#include "config.h"
+
+#import "OFConcreteDictionary.h"
+#import "OFArray.h"
+#import "OFConcreteMutableDictionary.h"
+#import "OFMapTable+Private.h"
+#import "OFMapTable.h"
+#import "OFString.h"
+
+#import "OFEnumerationMutationException.h"
+#import "OFInvalidArgumentException.h"
+#import "OFInvalidFormatException.h"
+
+static void *
+copy(void *object)
+{
+ return [(id)object copy];
+}
+
+static void *
+retain(void *object)
+{
+ return [(id)object retain];
+}
+
+static void
+release(void *object)
+{
+ [(id)object release];
+}
+
+static unsigned long
+hash(void *object)
+{
+ return [(id)object hash];
+}
+
+static bool
+equal(void *object1, void *object2)
+{
+ return [(id)object1 isEqual: (id)object2];
+}
+
+static const OFMapTableFunctions keyFunctions = {
+ .retain = copy,
+ .release = release,
+ .hash = hash,
+ .equal = equal
+};
+static const OFMapTableFunctions objectFunctions = {
+ .retain = retain,
+ .release = release,
+ .hash = hash,
+ .equal = equal
+};
+
+@implementation OFConcreteDictionary
+- (instancetype)init
+{
+ return [self initWithCapacity: 0];
+}
+
+- (instancetype)initWithCapacity: (size_t)capacity
+{
+ self = [super init];
+
+ @try {
+ _mapTable = [[OFMapTable alloc]
+ initWithKeyFunctions: keyFunctions
+ objectFunctions: objectFunctions
+ capacity: capacity];
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (instancetype)initWithDictionary: (OFDictionary *)dictionary
+{
+ size_t count;
+
+ if (dictionary == nil)
+ return [self init];
+
+ if ([dictionary isKindOfClass: [OFConcreteDictionary class]] ||
+ [dictionary isKindOfClass: [OFConcreteMutableDictionary class]]) {
+ self = [super init];
+
+ @try {
+ OFConcreteDictionary *dictionary_ =
+ (OFConcreteDictionary *)dictionary;
+
+ _mapTable = [dictionary_->_mapTable copy];
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ return self;
+ }
+
+ @try {
+ count = dictionary.count;
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ self = [self initWithCapacity: count];
+
+ @try {
+ void *pool = objc_autoreleasePoolPush();
+ OFEnumerator *keyEnumerator, *objectEnumerator;
+ id key, object;
+
+ keyEnumerator = [dictionary keyEnumerator];
+ objectEnumerator = [dictionary objectEnumerator];
+ while ((key = [keyEnumerator nextObject]) != nil &&
+ (object = [objectEnumerator nextObject]) != nil)
+ [_mapTable setObject: object forKey: key];
+
+ objc_autoreleasePoolPop(pool);
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (instancetype)initWithObject: (id)object forKey: (id)key
+{
+ self = [self initWithCapacity: 1];
+
+ @try {
+ [_mapTable setObject: object forKey: key];
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (instancetype)initWithObjects: (id const *)objects
+ forKeys: (id const *)keys
+ count: (size_t)count
+{
+ self = [self initWithCapacity: count];
+
+ @try {
+ size_t i;
+
+ for (i = 0; i < count; i++)
+ [_mapTable setObject: objects[i] forKey: keys[i]];
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (instancetype)initWithKey: (id)firstKey arguments: (va_list)arguments
+{
+ self = [super init];
+
+ @try {
+ va_list argumentsCopy;
+ id key, object;
+ size_t i, count;
+
+ va_copy(argumentsCopy, arguments);
+
+ if (firstKey == nil)
+ @throw [OFInvalidArgumentException exception];
+
+ key = firstKey;
+
+ if ((object = va_arg(arguments, id)) == nil)
+ @throw [OFInvalidArgumentException exception];
+
+ count = 1;
+ for (; va_arg(argumentsCopy, id) != nil; count++);
+
+ if (count % 2 != 0)
+ @throw [OFInvalidArgumentException exception];
+
+ count /= 2;
+
+ _mapTable = [[OFMapTable alloc]
+ initWithKeyFunctions: keyFunctions
+ objectFunctions: objectFunctions
+ capacity: count];
+
+ [_mapTable setObject: object forKey: key];
+
+ for (i = 1; i < count; i++) {
+ key = va_arg(arguments, id);
+ object = va_arg(arguments, id);
+
+ if (key == nil || object == nil)
+ @throw [OFInvalidArgumentException exception];
+
+ [_mapTable setObject: object forKey: key];
+ }
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (void)dealloc
+{
+ [_mapTable release];
+
+ [super dealloc];
+}
+
+- (id)objectForKey: (id)key
+{
+ return [_mapTable objectForKey: key];
+}
+
+- (size_t)count
+{
+ return _mapTable.count;
+}
+
+- (bool)isEqual: (id)object
+{
+ OFConcreteDictionary *dictionary;
+
+ if (object == self)
+ return true;
+
+ if (![object isKindOfClass: [OFConcreteDictionary class]] &&
+ ![object isKindOfClass: [OFConcreteMutableDictionary class]])
+ return [super isEqual: object];
+
+ dictionary = (OFConcreteDictionary *)object;
+
+ return [dictionary->_mapTable isEqual: _mapTable];
+}
+
+- (bool)containsObject: (id)object
+{
+ return [_mapTable containsObject: object];
+}
+
+- (bool)containsObjectIdenticalTo: (id)object
+{
+ return [_mapTable containsObjectIdenticalTo: object];
+}
+
+- (OFArray *)allKeys
+{
+ OFArray *ret;
+ id *keys;
+ size_t count;
+
+ count = _mapTable.count;
+ keys = OFAllocMemory(count, sizeof(*keys));
+
+ @try {
+ void *pool = objc_autoreleasePoolPush();
+ OFMapTableEnumerator *enumerator;
+ void **keyPtr;
+ size_t i;
+
+ i = 0;
+ enumerator = [_mapTable keyEnumerator];
+ while ((keyPtr = [enumerator nextObject]) != NULL) {
+ OFAssert(i < count);
+
+ keys[i++] = (id)*keyPtr;
+ }
+
+ objc_autoreleasePoolPop(pool);
+
+ ret = [OFArray arrayWithObjects: keys count: count];
+ } @finally {
+ OFFreeMemory(keys);
+ }
+
+ return ret;
+}
+
+- (OFArray *)allObjects
+{
+ OFArray *ret;
+ id *objects;
+ size_t count;
+
+ count = _mapTable.count;
+ objects = OFAllocMemory(count, sizeof(*objects));
+
+ @try {
+ void *pool = objc_autoreleasePoolPush();
+ OFMapTableEnumerator *enumerator;
+ void **objectPtr;
+ size_t i;
+
+ i = 0;
+ enumerator = [_mapTable objectEnumerator];
+ while ((objectPtr = [enumerator nextObject]) != NULL) {
+ OFAssert(i < count);
+
+ objects[i++] = (id)*objectPtr;
+ }
+
+ objc_autoreleasePoolPop(pool);
+
+ ret = [OFArray arrayWithObjects: objects count: count];
+ } @finally {
+ OFFreeMemory(objects);
+ }
+
+ return ret;
+}
+
+- (OFEnumerator *)keyEnumerator
+{
+ return [[[OFMapTableEnumeratorWrapper alloc]
+ initWithEnumerator: [_mapTable keyEnumerator]
+ object: self] autorelease];
+}
+
+- (OFEnumerator *)objectEnumerator
+{
+ return [[[OFMapTableEnumeratorWrapper alloc]
+ initWithEnumerator: [_mapTable objectEnumerator]
+ object: self] autorelease];
+}
+
+- (int)countByEnumeratingWithState: (OFFastEnumerationState *)state
+ objects: (id *)objects
+ count: (int)count
+{
+ return [_mapTable countByEnumeratingWithState: state
+ objects: objects
+ count: count];
+}
+
+#ifdef OF_HAVE_BLOCKS
+- (void)enumerateKeysAndObjectsUsingBlock: (OFDictionaryEnumerationBlock)block
+{
+ @try {
+ [_mapTable enumerateKeysAndObjectsUsingBlock:
+ ^ (void *key, void *object, bool *stop) {
+ block(key, object, stop);
+ }];
+ } @catch (OFEnumerationMutationException *e) {
+ @throw [OFEnumerationMutationException
+ exceptionWithObject: self];
+ }
+}
+#endif
+
+- (unsigned long)hash
+{
+ return _mapTable.hash;
+}
+@end
ADDED src/OFConcreteMutableArray.h
Index: src/OFConcreteMutableArray.h
==================================================================
--- /dev/null
+++ src/OFConcreteMutableArray.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#import "OFArray.h"
+
+OF_ASSUME_NONNULL_BEGIN
+
+@class OFMutableData;
+
+@interface OFConcreteMutableArray: OFMutableArray
+{
+ OFMutableData *_array;
+ unsigned long _mutations;
+}
+@end
+
+OF_ASSUME_NONNULL_END
ADDED src/OFConcreteMutableArray.m
Index: src/OFConcreteMutableArray.m
==================================================================
--- /dev/null
+++ src/OFConcreteMutableArray.m
@@ -0,0 +1,383 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#include "config.h"
+
+#include
+
+#import "OFConcreteMutableArray.h"
+#import "OFConcreteArray.h"
+#import "OFArray+Private.h"
+#import "OFData.h"
+
+#import "OFEnumerationMutationException.h"
+#import "OFInvalidArgumentException.h"
+#import "OFOutOfRangeException.h"
+
+@implementation OFConcreteMutableArray
++ (void)initialize
+{
+ if (self == [OFConcreteMutableArray class])
+ [self inheritMethodsFromClass: [OFConcreteArray class]];
+}
+
+- (instancetype)initWithCapacity: (size_t)capacity
+{
+ self = [super init];
+
+ @try {
+ _array = [[OFMutableData alloc] initWithItemSize: sizeof(id)
+ capacity: capacity];
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (void)addObject: (id)object
+{
+ if (object == nil)
+ @throw [OFInvalidArgumentException exception];
+
+ [_array addItem: &object];
+ [object retain];
+
+ _mutations++;
+}
+
+- (void)insertObject: (id)object atIndex: (size_t)idx
+{
+ if (object == nil)
+ @throw [OFInvalidArgumentException exception];
+
+ @try {
+ [_array insertItem: &object atIndex: idx];
+ } @catch (OFOutOfRangeException *e) {
+ @throw [OFOutOfRangeException exception];
+ }
+ [object retain];
+
+ _mutations++;
+}
+
+- (void)insertObjectsFromArray: (OFArray *)array atIndex: (size_t)idx
+{
+ id const *objects = array.objects;
+ size_t count = array.count;
+
+ @try {
+ [_array insertItems: objects atIndex: idx count: count];
+ } @catch (OFOutOfRangeException *e) {
+ @throw [OFOutOfRangeException exception];
+ }
+
+ for (size_t i = 0; i < count; i++)
+ [objects[i] retain];
+
+ _mutations++;
+}
+
+- (void)replaceObject: (id)oldObject withObject: (id)newObject
+{
+ id *objects;
+ size_t count;
+
+ if (oldObject == nil || newObject == nil)
+ @throw [OFInvalidArgumentException exception];
+
+ objects = _array.mutableItems;
+ count = _array.count;
+
+ for (size_t i = 0; i < count; i++) {
+ if ([objects[i] isEqual: oldObject]) {
+ [newObject retain];
+ [objects[i] release];
+ objects[i] = newObject;
+ }
+ }
+}
+
+- (void)replaceObjectAtIndex: (size_t)idx withObject: (id)object
+{
+ id *objects;
+ id oldObject;
+
+ if (object == nil)
+ @throw [OFInvalidArgumentException exception];
+
+ objects = _array.mutableItems;
+
+ if (idx >= _array.count)
+ @throw [OFOutOfRangeException exception];
+
+ oldObject = objects[idx];
+ objects[idx] = [object retain];
+ [oldObject release];
+}
+
+- (void)replaceObjectIdenticalTo: (id)oldObject withObject: (id)newObject
+{
+ id *objects;
+ size_t count;
+
+ if (oldObject == nil || newObject == nil)
+ @throw [OFInvalidArgumentException exception];
+
+ objects = _array.mutableItems;
+ count = _array.count;
+
+ for (size_t i = 0; i < count; i++) {
+ if (objects[i] == oldObject) {
+ [newObject retain];
+ [objects[i] release];
+ objects[i] = newObject;
+
+ return;
+ }
+ }
+}
+
+- (void)removeObject: (id)object
+{
+ id const *objects;
+ size_t count;
+
+ if (object == nil)
+ @throw [OFInvalidArgumentException exception];
+
+ objects = _array.items;
+ count = _array.count;
+
+ for (size_t i = 0; i < count; i++) {
+ if ([objects[i] isEqual: object]) {
+ id tmp = objects[i];
+
+ [_array removeItemAtIndex: i];
+ _mutations++;
+
+ [tmp release];
+
+ objects = _array.items;
+ i--;
+ count--;
+ continue;
+ }
+ }
+}
+
+- (void)removeObjectIdenticalTo: (id)object
+{
+ id const *objects;
+ size_t count;
+
+ if (object == nil)
+ @throw [OFInvalidArgumentException exception];
+
+ objects = _array.items;
+ count = _array.count;
+
+ for (size_t i = 0; i < count; i++) {
+ if (objects[i] == object) {
+ [_array removeItemAtIndex: i];
+ _mutations++;
+
+ [object release];
+
+ objects = _array.items;
+ i--;
+ count--;
+ continue;
+ }
+ }
+}
+
+- (void)removeObjectAtIndex: (size_t)idx
+{
+#ifndef __clang_analyzer__
+ id object = [self objectAtIndex: idx];
+ [_array removeItemAtIndex: idx];
+ [object release];
+
+ _mutations++;
+#endif
+}
+
+- (void)removeAllObjects
+{
+ id const *objects = _array.items;
+ size_t count = _array.count;
+
+ for (size_t i = 0; i < count; i++)
+ [objects[i] release];
+
+ [_array removeAllItems];
+}
+
+- (void)removeObjectsInRange: (OFRange)range
+{
+ id const *objects = _array.items;
+ size_t count = _array.count;
+ id *copy;
+
+ if (range.length > SIZE_MAX - range.location ||
+ range.location >= count || range.length > count - range.location)
+ @throw [OFOutOfRangeException exception];
+
+ copy = OFAllocMemory(range.length, sizeof(*copy));
+ memcpy(copy, objects + range.location, range.length * sizeof(id));
+
+ @try {
+ [_array removeItemsInRange: range];
+ _mutations++;
+
+ for (size_t i = 0; i < range.length; i++)
+ [copy[i] release];
+ } @finally {
+ OFFreeMemory(copy);
+ }
+}
+
+- (void)removeLastObject
+{
+#ifndef __clang_analyzer__
+ size_t count = _array.count;
+ id object;
+
+ if (count == 0)
+ return;
+
+ object = [self objectAtIndex: count - 1];
+ [_array removeLastItem];
+ [object release];
+
+ _mutations++;
+#endif
+}
+
+- (void)exchangeObjectAtIndex: (size_t)idx1 withObjectAtIndex: (size_t)idx2
+{
+ id *objects = _array.mutableItems;
+ size_t count = _array.count;
+ id tmp;
+
+ if (idx1 >= count || idx2 >= count)
+ @throw [OFOutOfRangeException exception];
+
+ tmp = objects[idx1];
+ objects[idx1] = objects[idx2];
+ objects[idx2] = tmp;
+}
+
+- (void)reverse
+{
+ id *objects = _array.mutableItems;
+ size_t i, j, count = _array.count;
+
+ if (count == 0 || count == 1)
+ return;
+
+ for (i = 0, j = count - 1; i < j; i++, j--) {
+ id tmp = objects[i];
+ objects[i] = objects[j];
+ objects[j] = tmp;
+ }
+}
+
+- (int)countByEnumeratingWithState: (OFFastEnumerationState *)state
+ objects: (id *)objects
+ count: (int)count_
+{
+ size_t count = _array.count;
+
+ if (count > INT_MAX) {
+ /*
+ * Use the implementation from OFArray (OFMutableArray does not
+ * have one), which is slower, but can enumerate in chunks, and
+ * set the mutations pointer.
+ */
+ int ret = [super countByEnumeratingWithState: state
+ objects: objects
+ count: count_];
+ state->mutationsPtr = &_mutations;
+ return ret;
+ }
+
+ if (state->state >= count)
+ return 0;
+
+ state->state = (unsigned long)count;
+ state->itemsPtr = (id *)_array.items;
+ state->mutationsPtr = &_mutations;
+
+ return (int)count;
+}
+
+- (OFEnumerator *)objectEnumerator
+{
+ return [[[OFArrayEnumerator alloc]
+ initWithArray: self
+ mutationsPtr: &_mutations] autorelease];
+}
+
+#ifdef OF_HAVE_BLOCKS
+- (void)enumerateObjectsUsingBlock: (OFArrayEnumerationBlock)block
+{
+ id const *objects = _array.items;
+ size_t count = _array.count;
+ bool stop = false;
+ unsigned long mutations = _mutations;
+
+ for (size_t i = 0; i < count && !stop; i++) {
+ if (_mutations != mutations)
+ @throw [OFEnumerationMutationException
+ exceptionWithObject: self];
+
+ block(objects[i], i, &stop);
+ }
+}
+
+- (void)replaceObjectsUsingBlock: (OFArrayReplaceBlock)block
+{
+ id *objects = _array.mutableItems;
+ size_t count = _array.count;
+ unsigned long mutations = _mutations;
+
+ for (size_t i = 0; i < count; i++) {
+ id new;
+
+ if (_mutations != mutations)
+ @throw [OFEnumerationMutationException
+ exceptionWithObject: self];
+
+ new = block(objects[i], i);
+
+ if (new == nil)
+ @throw [OFInvalidArgumentException exception];
+
+ if (new != objects[i]) {
+ [objects[i] release];
+ objects[i] = [new retain];
+ }
+ }
+}
+#endif
+
+- (void)makeImmutable
+{
+ object_setClass(self, [OFConcreteArray class]);
+}
+@end
ADDED src/OFConcreteMutableData.h
Index: src/OFConcreteMutableData.h
==================================================================
--- /dev/null
+++ src/OFConcreteMutableData.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#import "OFMutableData.h"
+
+OF_ASSUME_NONNULL_BEGIN
+
+@interface OFConcreteMutableData: OFMutableData
+{
+ unsigned char *_Nullable _items;
+ size_t _capacity, _count, _itemSize;
+ bool _freeWhenDone;
+}
+@end
+
+OF_ASSUME_NONNULL_END
ADDED src/OFConcreteMutableData.m
Index: src/OFConcreteMutableData.m
==================================================================
--- /dev/null
+++ src/OFConcreteMutableData.m
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#include "config.h"
+
+#include
+#include
+
+#import "OFConcreteMutableData.h"
+#import "OFConcreteData.h"
+
+#import "OFInvalidArgumentException.h"
+#import "OFOutOfMemoryException.h"
+#import "OFOutOfRangeException.h"
+
+@implementation OFConcreteMutableData
++ (void)initialize
+{
+ if (self == [OFConcreteMutableData class])
+ [self inheritMethodsFromClass: [OFConcreteData class]];
+}
+
+- (instancetype)initWithItemSize: (size_t)itemSize capacity: (size_t)capacity
+{
+ self = [super init];
+
+ @try {
+ if (itemSize == 0)
+ @throw [OFInvalidArgumentException exception];
+
+ _items = OFAllocMemory(capacity, itemSize);
+ _itemSize = itemSize;
+ _capacity = capacity;
+ _freeWhenDone = true;
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (instancetype)initWithItemsNoCopy: (void *)items
+ count: (size_t)count
+ itemSize: (size_t)itemSize
+ freeWhenDone: (bool)freeWhenDone
+{
+ self = [self initWithItems: items count: count itemSize: itemSize];
+
+ if (freeWhenDone)
+ OFFreeMemory(items);
+
+ return self;
+}
+
+- (void *)mutableItems
+{
+ return _items;
+}
+
+- (void)addItem: (const void *)item
+{
+ if (SIZE_MAX - _count < 1)
+ @throw [OFOutOfRangeException exception];
+
+ if (_count + 1 > _capacity) {
+ _items = OFResizeMemory(_items, _count + 1, _itemSize);
+ _capacity = _count + 1;
+ }
+
+ memcpy(_items + _count * _itemSize, item, _itemSize);
+
+ _count++;
+}
+
+- (void)addItems: (const void *)items count: (size_t)count
+{
+ if (count > SIZE_MAX - _count)
+ @throw [OFOutOfRangeException exception];
+
+ if (_count + count > _capacity) {
+ _items = OFResizeMemory(_items, _count + count, _itemSize);
+ _capacity = _count + count;
+ }
+
+ memcpy(_items + _count * _itemSize, items, count * _itemSize);
+ _count += count;
+}
+
+- (void)insertItems: (const void *)items
+ atIndex: (size_t)idx
+ count: (size_t)count
+{
+ if (count > SIZE_MAX - _count || idx > _count)
+ @throw [OFOutOfRangeException exception];
+
+ if (_count + count > _capacity) {
+ _items = OFResizeMemory(_items, _count + count, _itemSize);
+ _capacity = _count + count;
+ }
+
+ memmove(_items + (idx + count) * _itemSize, _items + idx * _itemSize,
+ (_count - idx) * _itemSize);
+ memcpy(_items + idx * _itemSize, items, count * _itemSize);
+
+ _count += count;
+}
+
+- (void)increaseCountBy: (size_t)count
+{
+ if (count > SIZE_MAX - _count)
+ @throw [OFOutOfRangeException exception];
+
+ if (_count + count > _capacity) {
+ _items = OFResizeMemory(_items, _count + count, _itemSize);
+ _capacity = _count + count;
+ }
+
+ memset(_items + _count * _itemSize, '\0', count * _itemSize);
+ _count += count;
+}
+
+- (void)removeItemsInRange: (OFRange)range
+{
+ if (range.length > SIZE_MAX - range.location ||
+ range.location + range.length > _count)
+ @throw [OFOutOfRangeException exception];
+
+ memmove(_items + range.location * _itemSize,
+ _items + (range.location + range.length) * _itemSize,
+ (_count - range.location - range.length) * _itemSize);
+
+ _count -= range.length;
+ @try {
+ _items = OFResizeMemory(_items, _count, _itemSize);
+ _capacity = _count;
+ } @catch (OFOutOfMemoryException *e) {
+ /* We don't really care, as we only made it smaller */
+ }
+}
+
+- (void)removeLastItem
+{
+ if (_count == 0)
+ return;
+
+ _count--;
+ @try {
+ _items = OFResizeMemory(_items, _count, _itemSize);
+ _capacity = _count;
+ } @catch (OFOutOfMemoryException *e) {
+ /* We don't care, as we only made it smaller */
+ }
+}
+
+- (void)removeAllItems
+{
+ OFFreeMemory(_items);
+ _items = NULL;
+ _count = 0;
+ _capacity = 0;
+}
+
+- (void)makeImmutable
+{
+ if (_capacity != _count) {
+ @try {
+ _items = OFResizeMemory(_items, _count, _itemSize);
+ _capacity = _count;
+ } @catch (OFOutOfMemoryException *e) {
+ /* We don't care, as we only made it smaller */
+ }
+ }
+
+ object_setClass(self, [OFConcreteData class]);
+}
+@end
ADDED src/OFConcreteMutableDictionary.h
Index: src/OFConcreteMutableDictionary.h
==================================================================
--- /dev/null
+++ src/OFConcreteMutableDictionary.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#import "OFDictionary.h"
+
+OF_ASSUME_NONNULL_BEGIN
+
+@class OFMapTable;
+
+@interface OFConcreteMutableDictionary: OFMutableDictionary
+{
+ OFMapTable *_mapTable;
+}
+@end
+
+OF_ASSUME_NONNULL_END
ADDED src/OFConcreteMutableDictionary.m
Index: src/OFConcreteMutableDictionary.m
==================================================================
--- /dev/null
+++ src/OFConcreteMutableDictionary.m
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#include "config.h"
+
+#include
+
+#import "OFConcreteMutableDictionary.h"
+#import "OFConcreteDictionary.h"
+#import "OFMapTable.h"
+
+#import "OFEnumerationMutationException.h"
+#import "OFOutOfRangeException.h"
+
+@implementation OFConcreteMutableDictionary
++ (void)initialize
+{
+ if (self == [OFConcreteMutableDictionary class])
+ [self inheritMethodsFromClass: [OFConcreteDictionary class]];
+}
+
+- (void)setObject: (id)object forKey: (id)key
+{
+ [_mapTable setObject: object forKey: key];
+}
+
+- (void)removeObjectForKey: (id)key
+{
+ [_mapTable removeObjectForKey: key];
+}
+
+- (void)removeAllObjects
+{
+ [_mapTable removeAllObjects];
+}
+
+#ifdef OF_HAVE_BLOCKS
+- (void)replaceObjectsUsingBlock: (OFDictionaryReplaceBlock)block
+{
+ @try {
+ [_mapTable replaceObjectsUsingBlock:
+ ^ void *(void *key, void *object) {
+ return block(key, object);
+ }];
+ } @catch (OFEnumerationMutationException *e) {
+ @throw [OFEnumerationMutationException
+ exceptionWithObject: self];
+ }
+}
+#endif
+
+- (void)makeImmutable
+{
+ object_setClass(self, [OFConcreteDictionary class]);
+}
+@end
ADDED src/OFConcreteMutableSet.h
Index: src/OFConcreteMutableSet.h
==================================================================
--- /dev/null
+++ src/OFConcreteMutableSet.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#import "OFMutableSet.h"
+
+OF_ASSUME_NONNULL_BEGIN
+
+@class OFMapTable;
+
+@interface OFConcreteMutableSet: OFMutableSet
+{
+ OFMapTable *_mapTable;
+}
+@end
+
+OF_ASSUME_NONNULL_END
ADDED src/OFConcreteMutableSet.m
Index: src/OFConcreteMutableSet.m
==================================================================
--- /dev/null
+++ src/OFConcreteMutableSet.m
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#include "config.h"
+
+#import "OFConcreteMutableSet.h"
+#import "OFConcreteSet.h"
+#import "OFMapTable.h"
+
+@implementation OFConcreteMutableSet
++ (void)initialize
+{
+ if (self == [OFConcreteMutableSet class])
+ [self inheritMethodsFromClass: [OFConcreteSet class]];
+}
+
+- (void)addObject: (id)object
+{
+ [_mapTable setObject: (void *)1 forKey: object];
+}
+
+- (void)removeObject: (id)object
+{
+ [_mapTable removeObjectForKey: object];
+}
+
+- (void)removeAllObjects
+{
+ [_mapTable removeAllObjects];
+}
+
+- (void)makeImmutable
+{
+ object_setClass(self, [OFConcreteSet class]);
+}
+@end
ADDED src/OFConcreteNumber.h
Index: src/OFConcreteNumber.h
==================================================================
--- /dev/null
+++ src/OFConcreteNumber.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#import "OFNumber.h"
+
+OF_ASSUME_NONNULL_BEGIN
+
+@interface OFConcreteNumber: OFNumber
+{
+ union {
+ double float_;
+ long long signed_;
+ unsigned long long unsigned_;
+ } _value;
+ char _typeEncoding;
+}
+@end
+
+OF_ASSUME_NONNULL_END
ADDED src/OFConcreteNumber.m
Index: src/OFConcreteNumber.m
==================================================================
--- /dev/null
+++ src/OFConcreteNumber.m
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#include "config.h"
+
+#include
+
+#import "OFConcreteNumber.h"
+
+#import "OFInvalidFormatException.h"
+
+static bool
+isUnsigned(OFNumber *number)
+{
+ switch (*number.objCType) {
+ case 'B':
+ case 'C':
+ case 'S':
+ case 'I':
+ case 'L':
+ case 'Q':
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool
+isSigned(OFNumber *number)
+{
+ switch (*number.objCType) {
+ case 'c':
+ case 's':
+ case 'i':
+ case 'l':
+ case 'q':
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool
+isFloat(OFNumber *number)
+{
+ switch (*number.objCType) {
+ case 'f':
+ case 'd':
+ return true;
+ default:
+ return false;
+ }
+}
+
+@implementation OFConcreteNumber
+- (instancetype)initWithBytes: (const void *)bytes
+ objCType: (const char *)objCType
+{
+#define CASE(type, method) \
+ if (strcmp(objCType, @encode(type)) == 0) { \
+ type value; \
+ memcpy(&value, bytes, sizeof(type)); \
+ return [self method value]; \
+ }
+
+ CASE(bool, initWithBool:)
+ CASE(signed char, initWithChar:)
+ CASE(short, initWithShort:)
+ CASE(int, initWithInt:)
+ CASE(long, initWithLong:)
+ CASE(long long, initWithLongLong:)
+ CASE(unsigned char, initWithUnsignedChar:)
+ CASE(unsigned short, initWithUnsignedShort:)
+ CASE(unsigned int, initWithUnsignedInt:)
+ CASE(unsigned long, initWithUnsignedLong:)
+ CASE(unsigned long long, initWithUnsignedLongLong:)
+ CASE(float, initWithFloat:)
+ CASE(double, initWithDouble:)
+
+ [self release];
+ @throw [OFInvalidFormatException exception];
+}
+
+- (instancetype)initWithBool: (bool)value
+{
+ self = [super initWithBytes: &value objCType: @encode(bool)];
+
+ _value.unsigned_ = value;
+ _typeEncoding = *@encode(bool);
+
+ return self;
+}
+
+- (instancetype)initWithChar: (signed char)value
+{
+ self = [super initWithBytes: &value objCType: @encode(signed char)];
+
+ _value.signed_ = value;
+ _typeEncoding = *@encode(signed char);
+
+ return self;
+}
+
+- (instancetype)initWithShort: (short)value
+{
+ self = [super initWithBytes: &value objCType: @encode(short)];
+
+ _value.signed_ = value;
+ _typeEncoding = *@encode(short);
+
+ return self;
+}
+
+- (instancetype)initWithInt: (int)value
+{
+ self = [super initWithBytes: &value objCType: @encode(int)];
+
+ _value.signed_ = value;
+ _typeEncoding = *@encode(int);
+
+ return self;
+}
+
+- (instancetype)initWithLong: (long)value
+{
+ self = [super initWithBytes: &value objCType: @encode(long)];
+
+ _value.signed_ = value;
+ _typeEncoding = *@encode(long);
+
+ return self;
+}
+
+- (instancetype)initWithLongLong: (long long)value
+{
+ self = [super initWithBytes: &value objCType: @encode(long long)];
+
+ _value.signed_ = value;
+ _typeEncoding = *@encode(long long);
+
+ return self;
+}
+
+- (instancetype)initWithUnsignedChar: (unsigned char)value
+{
+ self = [super initWithBytes: &value objCType: @encode(unsigned char)];
+
+ _value.unsigned_ = value;
+ _typeEncoding = *@encode(unsigned long);
+
+ return self;
+}
+
+- (instancetype)initWithUnsignedShort: (unsigned short)value
+{
+ self = [super initWithBytes: &value objCType: @encode(unsigned short)];
+
+ _value.unsigned_ = value;
+ _typeEncoding = *@encode(unsigned short);
+
+ return self;
+}
+
+- (instancetype)initWithUnsignedInt: (unsigned int)value
+{
+ self = [super initWithBytes: &value objCType: @encode(unsigned int)];
+
+ _value.unsigned_ = value;
+ _typeEncoding = *@encode(unsigned int);
+
+ return self;
+}
+
+- (instancetype)initWithUnsignedLong: (unsigned long)value
+{
+ self = [super initWithBytes: &value objCType: @encode(unsigned long)];
+
+ _value.unsigned_ = value;
+ _typeEncoding = *@encode(unsigned long);
+
+ return self;
+}
+
+- (instancetype)initWithUnsignedLongLong: (unsigned long long)value
+{
+ self = [super initWithBytes: &value
+ objCType: @encode(unsigned long long)];
+
+ _value.unsigned_ = value;
+ _typeEncoding = *@encode(unsigned long long);
+
+ return self;
+}
+
+- (instancetype)initWithFloat: (float)value
+{
+ self = [super initWithBytes: &value objCType: @encode(float)];
+
+ _value.float_ = value;
+ _typeEncoding = *@encode(float);
+
+ return self;
+}
+
+- (instancetype)initWithDouble: (double)value
+{
+ self = [super initWithBytes: &value objCType: @encode(double)];
+
+ _value.float_ = value;
+ _typeEncoding = *@encode(double);
+
+ return self;
+}
+
+- (const char *)objCType
+{
+ return &_typeEncoding;
+}
+
+- (long long)longLongValue
+{
+ if (isFloat(self))
+ return _value.float_;
+ else if (isSigned(self))
+ return _value.signed_;
+ else if (isUnsigned(self))
+ return _value.unsigned_;
+ else
+ @throw [OFInvalidFormatException exception];
+}
+
+- (unsigned long long)unsignedLongLongValue
+{
+ if (isFloat(self))
+ return _value.float_;
+ else if (isSigned(self))
+ return _value.signed_;
+ else if (isUnsigned(self))
+ return _value.unsigned_;
+ else
+ @throw [OFInvalidFormatException exception];
+}
+
+- (double)doubleValue
+{
+ if (isFloat(self))
+ return _value.float_;
+ else if (isSigned(self))
+ return _value.signed_;
+ else if (isUnsigned(self))
+ return _value.unsigned_;
+ else
+ @throw [OFInvalidFormatException exception];
+}
+@end
ADDED src/OFConcreteSet.h
Index: src/OFConcreteSet.h
==================================================================
--- /dev/null
+++ src/OFConcreteSet.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#import "OFSet.h"
+
+OF_ASSUME_NONNULL_BEGIN
+
+@class OFMapTable;
+
+@interface OFConcreteSet: OFSet
+{
+ OFMapTable *_mapTable;
+}
+
+- (instancetype)initWithCapacity: (size_t)capacity;
+@end
+
+OF_ASSUME_NONNULL_END
ADDED src/OFConcreteSet.m
Index: src/OFConcreteSet.m
==================================================================
--- /dev/null
+++ src/OFConcreteSet.m
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#include "config.h"
+
+#import "OFConcreteSet.h"
+#import "OFArray.h"
+#import "OFConcreteCountedSet.h"
+#import "OFConcreteMutableSet.h"
+#import "OFMapTable+Private.h"
+#import "OFMapTable.h"
+#import "OFString.h"
+
+#import "OFInvalidArgumentException.h"
+#import "OFEnumerationMutationException.h"
+
+static void *
+retain(void *object)
+{
+ return [(id)object retain];
+}
+
+static void
+release(void *object)
+{
+ [(id)object release];
+}
+
+static unsigned long
+hash(void *object)
+{
+ return [(id)object hash];
+}
+
+static bool
+equal(void *object1, void *object2)
+{
+ return [(id)object1 isEqual: (id)object2];
+}
+
+static const OFMapTableFunctions keyFunctions = {
+ .retain = retain,
+ .release = release,
+ .hash = hash,
+ .equal = equal
+};
+static const OFMapTableFunctions objectFunctions = { NULL };
+
+@implementation OFConcreteSet
+- (instancetype)init
+{
+ return [self initWithCapacity: 0];
+}
+
+- (instancetype)initWithCapacity: (size_t)capacity
+{
+ self = [super init];
+
+ @try {
+ _mapTable = [[OFMapTable alloc]
+ initWithKeyFunctions: keyFunctions
+ objectFunctions: objectFunctions
+ capacity: capacity];
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (instancetype)initWithSet: (OFSet *)set
+{
+ size_t count;
+
+ if (set == nil)
+ return [self init];
+
+ @try {
+ count = set.count;
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ self = [self initWithCapacity: count];
+
+ @try {
+ for (id object in set)
+ [_mapTable setObject: (void *)1 forKey: object];
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (instancetype)initWithArray: (OFArray *)array
+{
+ size_t count;
+
+ if (array == nil)
+ return self;
+
+ @try {
+ count = array.count;
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ self = [self initWithCapacity: count];
+
+ @try {
+ for (id object in array)
+ [_mapTable setObject: (void *)1 forKey: object];
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (instancetype)initWithObjects: (id const *)objects count: (size_t)count
+{
+ self = [self initWithCapacity: count];
+
+ @try {
+ for (size_t i = 0; i < count; i++)
+ [_mapTable setObject: (void *)1 forKey: objects[i]];
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (instancetype)initWithObject: (id)firstObject arguments: (va_list)arguments
+{
+ self = [super init];
+
+ @try {
+ id object;
+ va_list argumentsCopy;
+ size_t count;
+
+ va_copy(argumentsCopy, arguments);
+
+ for (count = 1; va_arg(argumentsCopy, id) != nil; count++);
+
+ _mapTable = [[OFMapTable alloc]
+ initWithKeyFunctions: keyFunctions
+ objectFunctions: objectFunctions
+ capacity: count];
+
+ [_mapTable setObject: (void *)1 forKey: firstObject];
+
+ while ((object = va_arg(arguments, id)) != nil)
+ [_mapTable setObject: (void *)1 forKey: object];
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (void)dealloc
+{
+ [_mapTable release];
+
+ [super dealloc];
+}
+
+- (size_t)count
+{
+ return [_mapTable count];
+}
+
+- (bool)containsObject: (id)object
+{
+ if (object == nil)
+ return false;
+
+ return ([_mapTable objectForKey: object] != nil);
+}
+
+- (bool)isEqual: (id)object
+{
+ OFConcreteSet *set;
+
+ if (object == self)
+ return true;
+
+ if (![object isKindOfClass: [OFConcreteSet class]] &&
+ ![object isKindOfClass: [OFConcreteMutableSet class]] &&
+ ![object isKindOfClass: [OFConcreteCountedSet class]])
+ return [super isEqual: object];
+
+ set = object;
+
+ return [set->_mapTable isEqual: _mapTable];
+}
+
+- (id)anyObject
+{
+ void *pool = objc_autoreleasePoolPush();
+ void **objectPtr;
+ id object;
+
+ objectPtr = [[_mapTable keyEnumerator] nextObject];
+
+ if (objectPtr == NULL) {
+ objc_autoreleasePoolPop(pool);
+ return nil;
+ }
+
+ object = [(id)*objectPtr retain];
+
+ objc_autoreleasePoolPop(pool);
+
+ return [object autorelease];
+}
+
+- (OFEnumerator *)objectEnumerator
+{
+ return [[[OFMapTableEnumeratorWrapper alloc]
+ initWithEnumerator: [_mapTable keyEnumerator]
+ object: self] autorelease];
+}
+
+- (int)countByEnumeratingWithState: (OFFastEnumerationState *)state
+ objects: (id *)objects
+ count: (int)count
+{
+ return [_mapTable countByEnumeratingWithState: state
+ objects: objects
+ count: count];
+}
+
+#ifdef OF_HAVE_BLOCKS
+- (void)enumerateObjectsUsingBlock: (OFSetEnumerationBlock)block
+{
+ @try {
+ [_mapTable enumerateKeysAndObjectsUsingBlock:
+ ^ (void *key, void *object, bool *stop) {
+ block(key, stop);
+ }];
+ } @catch (OFEnumerationMutationException *e) {
+ @throw [OFEnumerationMutationException
+ exceptionWithObject: self];
+ }
+}
+#endif
+@end
ADDED src/OFConcreteSubarray.h
Index: src/OFConcreteSubarray.h
==================================================================
--- /dev/null
+++ src/OFConcreteSubarray.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#import "OFSubarray.h"
+
+OF_ASSUME_NONNULL_BEGIN
+
+@interface OFConcreteSubarray: OFSubarray
+@end
+
+OF_ASSUME_NONNULL_END
ADDED src/OFConcreteSubarray.m
Index: src/OFConcreteSubarray.m
==================================================================
--- /dev/null
+++ src/OFConcreteSubarray.m
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#include "config.h"
+
+#import "OFConcreteSubarray.h"
+#import "OFConcreteArray.h"
+#import "OFConcreteMutableArray.h"
+
+@implementation OFConcreteSubarray
+- (const id *)objects
+{
+ return _array.objects + _range.location;
+}
+
+- (bool)isEqual: (id)object
+{
+ OFArray *otherArray;
+ id const *objects, *otherObjects;
+
+ if (object == self)
+ return true;
+
+ if (![object isKindOfClass: [OFConcreteArray class]] &&
+ ![object isKindOfClass: [OFConcreteMutableArray class]])
+ return [super isEqual: object];
+
+ otherArray = object;
+
+ if (_range.length != otherArray.count)
+ return false;
+
+ objects = self.objects;
+ otherObjects = otherArray.objects;
+
+ for (size_t i = 0; i < _range.length; i++)
+ if (![objects[i] isEqual: otherObjects[i]])
+ return false;
+
+ return true;
+}
+
+#ifdef OF_HAVE_BLOCKS
+- (void)enumerateObjectsUsingBlock: (OFArrayEnumerationBlock)block
+{
+ id const *objects = self.objects;
+ bool stop = false;
+
+ for (size_t i = 0; i < _range.length && !stop; i++)
+ block(objects[i], i, &stop);
+}
+#endif
+@end
ADDED src/OFConcreteValue.h
Index: src/OFConcreteValue.h
==================================================================
--- /dev/null
+++ src/OFConcreteValue.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#import "OFValue.h"
+
+OF_ASSUME_NONNULL_BEGIN
+
+@interface OFConcreteValue: OFValue
+{
+ size_t _size;
+ void *_bytes;
+ char *_objCType;
+}
+@end
+
+OF_ASSUME_NONNULL_END
ADDED src/OFConcreteValue.m
Index: src/OFConcreteValue.m
==================================================================
--- /dev/null
+++ src/OFConcreteValue.m
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2008-2024 Jonathan Schleifer
+ *
+ * All rights reserved.
+ *
+ * This file is part of ObjFW. It may be distributed under the terms of the
+ * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
+ * the packaging of this file.
+ *
+ * Alternatively, it may be distributed under the terms of the GNU General
+ * Public License, either version 2 or 3, which can be found in the file
+ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
+ * file.
+ */
+
+#import "OFConcreteValue.h"
+#import "OFMethodSignature.h"
+#import "OFString.h"
+
+#import "OFOutOfRangeException.h"
+
+@implementation OFConcreteValue
+- (instancetype)initWithBytes: (const void *)bytes
+ objCType: (const char *)objCType
+{
+ self = [super initWithBytes: bytes objCType: objCType];
+
+ @try {
+ _size = OFSizeOfTypeEncoding(objCType);
+ _objCType = OFStrDup(objCType);
+ _bytes = OFAllocMemory(1, _size);
+ memcpy(_bytes, bytes, _size);
+ } @catch (id e) {
+ [self release];
+ @throw e;
+ }
+
+ return self;
+}
+
+- (void)dealloc
+{
+ OFFreeMemory(_bytes);
+ OFFreeMemory(_objCType);
+
+ [super dealloc];
+}
+
+- (const char *)objCType
+{
+ return _objCType;
+}
+
+- (void)getValue: (void *)value size: (size_t)size
+{
+ if (size != _size)
+ @throw [OFOutOfRangeException exception];
+
+ memcpy(value, _bytes, _size);
+}
+@end
Index: src/OFCondition.h
==================================================================
--- src/OFCondition.h
+++ src/OFCondition.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -48,11 +48,11 @@
*
* @throw OFWaitForConditionFailedException Waiting for the condition failed
*/
- (void)wait;
-#ifdef OF_AMIGAOS
+#if defined(OF_AMIGAOS) || defined(DOXYGEN)
/**
* @brief Blocks the current thread until another thread calls @ref signal,
* @ref broadcast or an Exec Signal is received.
*
* @note This is only available on AmigaOS!
@@ -75,11 +75,11 @@
* @return Whether the condition has been signaled
* @throw OFWaitForConditionFailedException Waiting for the condition failed
*/
- (bool)waitForTimeInterval: (OFTimeInterval)timeInterval;
-#ifdef OF_AMIGAOS
+#if defined(OF_AMIGAOS) || defined(DOXYGEN)
/**
* @brief Blocks the current thread until another thread calls @ref signal,
* @ref broadcast, the timeout is reached or an Exec Signal is received.
*
* @note This is only available on AmigaOS!
@@ -105,11 +105,11 @@
* @return Whether the condition has been signaled
* @throw OFWaitForConditionFailedException Waiting for the condition failed
*/
- (bool)waitUntilDate: (OFDate *)date;
-#ifdef OF_AMIGAOS
+#if defined(OF_AMIGAOS) || defined(DOXYGEN)
/**
* @brief Blocks the current thread until another thread calls @ref signal,
* @ref broadcast, the timeout is reached or an Exec Signal is received.
*
* @note This is only available on AmigaOS!
Index: src/OFCondition.m
==================================================================
--- src/OFCondition.m
+++ src/OFCondition.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -17,10 +17,11 @@
#include
#import "OFCondition.h"
#import "OFDate.h"
+#import "OFString.h"
#import "OFBroadcastConditionFailedException.h"
#import "OFConditionStillWaitingException.h"
#import "OFInitializationFailedException.h"
#import "OFSignalConditionFailedException.h"
Index: src/OFConstantString.h
==================================================================
--- src/OFConstantString.h
+++ src/OFConstantString.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -11,14 +11,11 @@
* 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.
*/
-#ifndef OBJFW_OF_CONSTANT_STRING_H
-#define OBJFW_OF_CONSTANT_STRING_H
-
-#include "OFString.h"
+#import "OFString.h"
OF_ASSUME_NONNULL_BEGIN
#if !defined(OF_CONSTANT_STRING_M) && \
defined(OF_APPLE_RUNTIME) && !defined(__OBJC2__)
@@ -29,11 +26,10 @@
# ifdef __cplusplus
}
# endif
#endif
-#ifdef __OBJC__
/**
* @class OFConstantString OFConstantString.h ObjFW/OFConstantString.h
*
* @brief A class for storing constant strings using the `@""` literal.
*/
@@ -42,10 +38,7 @@
{
char *_cString;
unsigned int _cStringLength;
}
@end
-#endif
OF_ASSUME_NONNULL_END
-
-#endif
Index: src/OFConstantString.m
==================================================================
--- src/OFConstantString.m
+++ src/OFConstantString.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -50,33 +50,11 @@
+ (instancetype)alloc
{
OF_UNRECOGNIZED_SELECTOR
}
-- (instancetype)retain
-{
- return self;
-}
-
-- (instancetype)autorelease
-{
- return self;
-}
-
-- (unsigned int)retainCount
-{
- return OFMaxRetainCount;
-}
-
-- (void)release
-{
-}
-
-- (void)dealloc
-{
- OF_DEALLOC_UNSUPPORTED
-}
+OF_SINGLETON_METHODS
@end
@implementation OFConstantString
+ (void)load
{
@@ -133,33 +111,11 @@
+ (instancetype)alloc
{
OF_UNRECOGNIZED_SELECTOR
}
-- (instancetype)retain
-{
- return self;
-}
-
-- (instancetype)autorelease
-{
- return self;
-}
-
-- (unsigned int)retainCount
-{
- return OFMaxRetainCount;
-}
-
-- (void)release
-{
-}
-
-- (void)dealloc
-{
- OF_DEALLOC_UNSUPPORTED
-}
+OF_SINGLETON_METHODS
/*
* In all following methods, the constant string is converted to an
* OFConstantUTF8String and the message sent again.
*/
@@ -547,24 +503,10 @@
{
[self finishInitialization];
return [self dataWithEncoding: encoding];
}
-#ifdef OF_HAVE_UNICODE_TABLES
-- (OFString *)decomposedStringWithCanonicalMapping
-{
- [self finishInitialization];
- return self.decomposedStringWithCanonicalMapping;
-}
-
-- (OFString *)decomposedStringWithCompatibilityMapping
-{
- [self finishInitialization];
- return self.decomposedStringWithCompatibilityMapping;
-}
-#endif
-
#ifdef OF_WINDOWS
- (OFString *)stringByExpandingWindowsEnvironmentStrings
{
[self finishInitialization];
return self.stringByExpandingWindowsEnvironmentStrings;
@@ -583,20 +525,20 @@
[self finishInitialization];
[self writeToFile: path encoding: encoding];
}
#endif
-- (void)writeToURI: (OFURI *)URI
+- (void)writeToIRI: (OFIRI *)IRI
{
[self finishInitialization];
- [self writeToURI: URI];
+ [self writeToIRI: IRI];
}
-- (void)writeToURI: (OFURI *)URI encoding: (OFStringEncoding)encoding
+- (void)writeToIRI: (OFIRI *)IRI encoding: (OFStringEncoding)encoding
{
[self finishInitialization];
- [self writeToURI: URI encoding: encoding];
+ [self writeToIRI: IRI encoding: encoding];
}
#ifdef OF_HAVE_BLOCKS
- (void)enumerateLinesUsingBlock: (OFStringLineEnumerationBlock)block
{
DELETED src/OFCountedMapTableSet.h
Index: src/OFCountedMapTableSet.h
==================================================================
--- src/OFCountedMapTableSet.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
- *
- * All rights reserved.
- *
- * This file is part of ObjFW. It may be distributed under the terms of the
- * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
- * the packaging of this file.
- *
- * Alternatively, it may be distributed under the terms of the GNU General
- * Public License, either version 2 or 3, which can be found in the file
- * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
- * file.
- */
-
-#import "OFCountedSet.h"
-
-OF_ASSUME_NONNULL_BEGIN
-
-@class OFMapTable;
-
-@interface OFCountedMapTableSet: OFCountedSet
-{
- OFMapTable *_mapTable;
-}
-@end
-
-OF_ASSUME_NONNULL_END
DELETED src/OFCountedMapTableSet.m
Index: src/OFCountedMapTableSet.m
==================================================================
--- src/OFCountedMapTableSet.m
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
- *
- * All rights reserved.
- *
- * This file is part of ObjFW. It may be distributed under the terms of the
- * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
- * the packaging of this file.
- *
- * Alternatively, it may be distributed under the terms of the GNU General
- * Public License, either version 2 or 3, which can be found in the file
- * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
- * file.
- */
-
-#include "config.h"
-
-#import "OFCountedMapTableSet.h"
-#import "OFArray.h"
-#import "OFMapTable.h"
-#import "OFMutableMapTableSet.h"
-#import "OFString.h"
-#import "OFXMLAttribute.h"
-#import "OFXMLElement.h"
-
-#import "OFInvalidArgumentException.h"
-#import "OFInvalidFormatException.h"
-#import "OFEnumerationMutationException.h"
-#import "OFOutOfRangeException.h"
-
-@implementation OFCountedMapTableSet
-+ (void)initialize
-{
- if (self == [OFCountedMapTableSet class])
- [self inheritMethodsFromClass: [OFMutableMapTableSet class]];
-}
-
-- (instancetype)initWithSet: (OFSet *)set
-{
- self = [self init];
-
- @try {
- void *pool = objc_autoreleasePoolPush();
-
- if ([set isKindOfClass: [OFCountedSet class]]) {
- OFCountedSet *countedSet = (OFCountedSet *)set;
-
- for (id object in countedSet) {
- size_t count =
- [countedSet countForObject: object];
-
- for (size_t i = 0; i < count; i++)
- [self addObject: object];
- }
- } else
- for (id object in set)
- [self addObject: object];
-
- objc_autoreleasePoolPop(pool);
- } @catch (id e) {
- [self release];
- @throw e;
- }
-
- return self;
-}
-
-- (instancetype)initWithArray: (OFArray *)array
-{
- self = [self init];
-
- @try {
- id const *objects = array.objects;
- size_t count = array.count;
-
- for (size_t i = 0; i < count; i++)
- [self addObject: objects[i]];
- } @catch (id e) {
- [self release];
- @throw e;
- }
-
- return self;
-}
-
-- (instancetype)initWithObjects: (id const *)objects count: (size_t)count
-{
- self = [self init];
-
- @try {
- for (size_t i = 0; i < count; i++)
- [self addObject: objects[i]];
- } @catch (id e) {
- [self release];
- @throw e;
- }
-
- return self;
-}
-
-- (instancetype)initWithObject: (id)firstObject arguments: (va_list)arguments
-{
- self = [self init];
-
- @try {
- id object;
-
- [self addObject: firstObject];
-
- while ((object = va_arg(arguments, id)) != nil)
- [self addObject: object];
- } @catch (id e) {
- [self release];
- @throw e;
- }
-
- return self;
-}
-
-- (instancetype)initWithSerialization: (OFXMLElement *)element
-{
- self = [self init];
-
- @try {
- void *pool = objc_autoreleasePoolPush();
-
- if (![element.name isEqual: @"OFCountedSet"] ||
- ![element.namespace isEqual: OFSerializationNS])
- @throw [OFInvalidArgumentException exception];
-
- for (OFXMLElement *objectElement in
- [element elementsForName: @"object"
- namespace: OFSerializationNS]) {
- void *pool2 = objc_autoreleasePoolPush();
- OFXMLElement *object;
- OFXMLAttribute *countAttribute;
- unsigned long long count;
-
- object = [objectElement elementsForNamespace:
- OFSerializationNS].firstObject;
- countAttribute =
- [objectElement attributeForName: @"count"];
-
- if (object == nil || countAttribute == nil)
- @throw [OFInvalidFormatException exception];
-
- count = countAttribute.unsignedLongLongValue;
- if (count > SIZE_MAX || count > UINTPTR_MAX)
- @throw [OFOutOfRangeException exception];
-
- [_mapTable setObject: (void *)(uintptr_t)count
- forKey: object.objectByDeserializing];
-
- objc_autoreleasePoolPop(pool2);
- }
-
- objc_autoreleasePoolPop(pool);
- } @catch (id e) {
- [self release];
- @throw e;
- }
-
- return self;
-}
-
-- (size_t)countForObject: (id)object
-{
- return (size_t)(uintptr_t)[_mapTable objectForKey: object];
-}
-
-#ifdef OF_HAVE_BLOCKS
-- (void)enumerateObjectsAndCountUsingBlock: (OFCountedSetEnumerationBlock)block
-{
- @try {
- [_mapTable enumerateKeysAndObjectsUsingBlock:
- ^ (void *key, void *object, bool *stop) {
- block(key, (size_t)(uintptr_t)object, stop);
- }];
- } @catch (OFEnumerationMutationException *e) {
- @throw [OFEnumerationMutationException
- exceptionWithObject: self];
- }
-}
-#endif
-
-- (void)addObject: (id)object
-{
- size_t count = (size_t)(uintptr_t)[_mapTable objectForKey: object];
-
- if (SIZE_MAX - count < 1 || UINTPTR_MAX - count < 1)
- @throw [OFOutOfRangeException exception];
-
- [_mapTable setObject: (void *)(uintptr_t)(count + 1) forKey: object];
-}
-
-- (void)removeObject: (id)object
-{
- size_t count = (size_t)(uintptr_t)[_mapTable objectForKey: object];
-
- if (count == 0)
- return;
-
- count--;
-
- if (count > 0)
- [_mapTable setObject: (void *)(uintptr_t)count forKey: object];
- else
- [_mapTable removeObjectForKey: object];
-}
-
-- (void)removeAllObjects
-{
- [_mapTable removeAllObjects];
-}
-
-- (void)makeImmutable
-{
-}
-@end
Index: src/OFCountedSet.h
==================================================================
--- src/OFCountedSet.h
+++ src/OFCountedSet.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFCountedSet.m
==================================================================
--- src/OFCountedSet.m
+++ src/OFCountedSet.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -16,94 +16,80 @@
#include "config.h"
#include
#import "OFCountedSet.h"
-#import "OFCountedMapTableSet.h"
+#import "OFConcreteCountedSet.h"
#import "OFNumber.h"
#import "OFString.h"
-#import "OFXMLElement.h"
static struct {
Class isa;
} placeholder;
-@interface OFCountedSetPlaceholder: OFCountedSet
+@interface OFPlaceholderCountedSet: OFCountedSet
@end
-@implementation OFCountedSetPlaceholder
+@implementation OFPlaceholderCountedSet
+#ifdef __clang__
+/* We intentionally don't call into super, so silence the warning. */
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wunknown-pragmas"
+# pragma clang diagnostic ignored "-Wobjc-designated-initializers"
+#endif
- (instancetype)init
{
- return (id)[[OFCountedMapTableSet alloc] init];
+ return (id)[[OFConcreteCountedSet alloc] init];
}
- (instancetype)initWithSet: (OFSet *)set
{
- return (id)[[OFCountedMapTableSet alloc] initWithSet: set];
+ return (id)[[OFConcreteCountedSet alloc] initWithSet: set];
}
- (instancetype)initWithArray: (OFArray *)array
{
- return (id)[[OFCountedMapTableSet alloc] initWithArray: array];
+ return (id)[[OFConcreteCountedSet alloc] initWithArray: array];
}
- (instancetype)initWithObjects: (id)firstObject, ...
{
id ret;
va_list arguments;
va_start(arguments, firstObject);
- ret = [[OFCountedMapTableSet alloc] initWithObject: firstObject
+ ret = [[OFConcreteCountedSet alloc] initWithObject: firstObject
arguments: arguments];
va_end(arguments);
return ret;
}
- (instancetype)initWithObjects: (id const *)objects count: (size_t)count
{
- return (id)[[OFCountedMapTableSet alloc] initWithObjects: objects
+ return (id)[[OFConcreteCountedSet alloc] initWithObjects: objects
count: count];
}
- (instancetype)initWithObject: (id)firstObject arguments: (va_list)arguments
{
- return (id)[[OFCountedMapTableSet alloc] initWithObject: firstObject
+ return (id)[[OFConcreteCountedSet alloc] initWithObject: firstObject
arguments: arguments];
}
-
-- (instancetype)initWithSerialization: (OFXMLElement *)element
-{
- return (id)[[OFCountedMapTableSet alloc]
- initWithSerialization: element];
-}
-
-- (instancetype)retain
-{
- return self;
-}
-
-- (instancetype)autorelease
-{
- return self;
-}
-
-- (void)release
-{
-}
-
-- (void)dealloc
-{
- OF_DEALLOC_UNSUPPORTED
-}
+#ifdef __clang__
+# pragma clang diagnostic pop
+#endif
+
+OF_SINGLETON_METHODS
@end
@implementation OFCountedSet
+ (void)initialize
{
if (self == [OFCountedSet class])
- placeholder.isa = [OFCountedSetPlaceholder class];
+ object_setClass((id)&placeholder,
+ [OFPlaceholderCountedSet class]);
}
+ (instancetype)alloc
{
if (self == [OFCountedSet class])
@@ -110,26 +96,10 @@
return (id)&placeholder;
return [super alloc];
}
-- (instancetype)init
-{
- if ([self isMemberOfClass: [OFCountedSet class]]) {
- @try {
- [self doesNotRecognizeSelector: _cmd];
- } @catch (id e) {
- [self release];
- @throw e;
- }
-
- abort();
- }
-
- return [super init];
-}
-
- (size_t)countForObject: (id)object
{
OF_UNRECOGNIZED_SELECTOR
}
@@ -175,46 +145,10 @@
- (id)mutableCopy
{
return [[OFCountedSet alloc] initWithSet: self];
}
-- (OFXMLElement *)XMLElementBySerializing
-{
- void *pool = objc_autoreleasePoolPush();
- OFXMLElement *element;
-
- element = [OFXMLElement elementWithName: @"OFCountedSet"
- namespace: OFSerializationNS];
-
- for (id object in self) {
- void *pool2 = objc_autoreleasePoolPush();
-
- OFXMLElement *objectElement;
- OFString *count;
-
- count =
- [OFString stringWithFormat: @"%zu",
- [self countForObject: object]];
-
- objectElement = [OFXMLElement
- elementWithName: @"object"
- namespace: OFSerializationNS];
- [objectElement addAttributeWithName: @"count"
- stringValue: count];
- [objectElement addChild: object.XMLElementBySerializing];
- [element addChild: objectElement];
-
- objc_autoreleasePoolPop(pool2);
- }
-
- [element retain];
-
- objc_autoreleasePoolPop(pool);
-
- return [element autorelease];
-}
-
#ifdef OF_HAVE_BLOCKS
- (void)enumerateObjectsAndCountUsingBlock: (OFCountedSetEnumerationBlock)block
{
[self enumerateObjectsUsingBlock: ^ (id object, bool *stop) {
block(object, [self countForObject: object], stop);
Index: src/OFCryptographicHash.h
==================================================================
--- src/OFCryptographicHash.h
+++ src/OFCryptographicHash.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFDDPSocket.h
==================================================================
--- src/OFDDPSocket.h
+++ src/OFDDPSocket.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -16,10 +16,11 @@
#import "OFDatagramSocket.h"
OF_ASSUME_NONNULL_BEGIN
@class OFString;
+@class OFDictionary OF_GENERIC(KeyType, ObjectType);
/**
* @protocol OFDDPSocketDelegate OFDDPSocket.h ObjFW/OFDDPSocket.h
*
* @brief A delegate for OFDDPSocket.
@@ -41,11 +42,11 @@
* socket number).
*
* @note On some systems, packets received with the wrong protocol type just
* get filtered by the kernel, however, on other systems, the packet is
* queued up and will raise an @ref OFReadFailedException with the
- * @ref errNo set to `ENOMSG` when being received.
+ * @ref OFReadFailedException#errNo set to `ENOMSG` when being received.
*
* @warning Even though the OFCopying protocol is implemented, it does *not*
* return an independent copy of the socket, but instead retains it.
* This is so that the socket can be used as a key for a dictionary,
* so context can be associated with a socket. Using a socket in more
@@ -79,14 +80,14 @@
* @param protocolType The DDP protocol type to use. Must not be 0. If you want
* to use DDP directly and not a protocol built on top of
* it, use 11 for compatibility with Open Transport.
* @return The address on which this socket can be reached
* @throw OFBindDDPSockeFailedException Binding failed
- * @throw OFAlreadyConnectedException The socket is already bound
+ * @throw OFAlreadyOpenException The socket is already bound
*/
- (OFSocketAddress)bindToNetwork: (uint16_t)network
node: (uint8_t)node
port: (uint8_t)port
protocolType: (uint8_t)protocolType;
@end
OF_ASSUME_NONNULL_END
Index: src/OFDDPSocket.m
==================================================================
--- src/OFDDPSocket.m
+++ src/OFDDPSocket.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -20,19 +20,32 @@
#ifdef HAVE_FCNTL_H
# include
#endif
#import "OFDDPSocket.h"
+#import "OFDictionary.h"
+#import "OFNumber.h"
+#import "OFPair.h"
#import "OFSocket.h"
#import "OFSocket+Private.h"
-#import "OFAlreadyConnectedException.h"
+#import "OFAlreadyOpenException.h"
#import "OFBindDDPSocketFailedException.h"
+#import "OFGetOptionFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFNotOpenException.h"
+#import "OFOutOfRangeException.h"
#import "OFReadFailedException.h"
+#import "OFSetOptionFailedException.h"
#import "OFWriteFailedException.h"
+
+#ifdef HAVE_NET_IF_H
+# include
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include
+#endif
#ifdef OF_HAVE_NETAT_APPLETALK_H
# include
# include
@@ -65,11 +78,11 @@
if (protocolType == 0)
@throw [OFInvalidArgumentException exception];
if (_socket != OFInvalidSocketHandle)
- @throw [OFAlreadyConnectedException exceptionWithSocket: self];
+ @throw [OFAlreadyOpenException exceptionWithObject: self];
address = OFSocketAddressMakeAppleTalk(network, node, port);
#if defined(OF_MACOS)
if ((_socket = socket(address.sockaddr.at.sat_family,
Index: src/OFDNSQuery.h
==================================================================
--- src/OFDNSQuery.h
+++ src/OFDNSQuery.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
Index: src/OFDNSQuery.m
==================================================================
--- src/OFDNSQuery.m
+++ src/OFDNSQuery.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -41,11 +41,11 @@
void *pool = objc_autoreleasePoolPush();
if (![domainName hasSuffix: @"."])
domainName = [domainName stringByAppendingString: @"."];
- _domainName = [domainName copy];
+ _domainName = [domainName.lowercaseString copy];
_DNSClass = DNSClass;
_recordType = recordType;
objc_autoreleasePoolPop(pool);
} @catch (id e) {
Index: src/OFDNSResolver.h
==================================================================
--- src/OFDNSResolver.h
+++ src/OFDNSResolver.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -28,12 +28,14 @@
@class OFDNSResolver;
@class OFDNSResolverContext;
@class OFDNSResolverSettings;
@class OFDate;
@class OFDictionary OF_GENERIC(KeyType, ObjectType);
+@class OFMutableArray OF_GENERIC(ObjectType);
@class OFMutableDictionary OF_GENERIC(KeyType, ObjectType);
@class OFNumber;
+@class OFPair OF_GENERIC(FirstType, SecondType);
@class OFTCPSocket;
@class OFUDPSocket;
/**
* @enum OFDNSResolverErrorCode OFDNSResolver.h ObjFW/OFDNSResolver.h
@@ -132,24 +134,36 @@
char _buffer[OFDNSResolverBufferLength];
OFMutableDictionary OF_GENERIC(OFNumber *, OFDNSResolverContext *)
*_queries;
OFMutableDictionary OF_GENERIC(OFTCPSocket *, OFDNSResolverContext *)
*_TCPQueries;
+ OFMutableDictionary OF_GENERIC(OFDNSQuery *,
+ OFPair OF_GENERIC(OFDate *, OFDNSResponse *) *) *_cache;
+ OFMutableArray OF_GENERIC(OFString *) *_lastNameServers;
+ OFTimeInterval _lastCacheCleanup;
}
/**
* @brief A dictionary of static hosts.
*
* This dictionary is checked before actually looking up a host.
+ *
+ * @warning If you change this, you need to set @ref configReloadInterval to 0
+ * to disable reloading the config after some time. If you don't, the
+ * config will be reloaded and your change overridden.
*/
@property (copy, nonatomic) OFDictionary OF_GENERIC(OFString *,
OFArray OF_GENERIC(OFString *) *) *staticHosts;
/**
* @brief An array of name servers to use.
*
* The name servers are tried in order.
+ *
+ * @warning If you change this, you need to set @ref configReloadInterval to 0
+ * to disable reloading the config after some time. If you don't, the
+ * config will be reloaded and your change overridden.
*/
@property (copy, nonatomic) OFArray OF_GENERIC(OFString *) *nameServers;
/**
* @brief The local domain.
@@ -156,40 +170,64 @@
*/
@property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *localDomain;
/**
* @brief The domains to search for queries for short names.
+ *
+ * @warning If you change this, you need to set @ref configReloadInterval to 0
+ * to disable reloading the config after some time. If you don't, the
+ * config will be reloaded and your change overridden.
*/
@property (copy, nonatomic) OFArray OF_GENERIC(OFString *) *searchDomains;
/**
* @brief The timeout, in seconds, after which the next name server should be
* tried.
+ *
+ * @warning If you change this, you need to set @ref configReloadInterval to 0
+ * to disable reloading the config after some time. If you don't, the
+ * config will be reloaded and your change overridden.
*/
@property (nonatomic) OFTimeInterval timeout;
/**
* @brief The number of attempts before giving up to resolve a host.
*
* Trying all name servers once is considered a single attempt.
+ *
+ * @warning If you change this, you need to set @ref configReloadInterval to 0
+ * to disable reloading the config after some time. If you don't, the
+ * config will be reloaded and your change overridden.
*/
@property (nonatomic) unsigned int maxAttempts;
/**
* @brief The minimum number of dots for a name to be considered absolute.
+ *
+ * @warning If you change this, you need to set @ref configReloadInterval to 0
+ * to disable reloading the config after some time. If you don't, the
+ * config will be reloaded and your change overridden.
*/
@property (nonatomic) unsigned int minNumberOfDotsInAbsoluteName;
/**
- * @brief Whether the resolver uses TCP to talk to a name server.
+ * @brief Whether the resolver forces TCP to talk to a name server.
+ *
+ * @warning If you change this, you need to set @ref configReloadInterval to 0
+ * to disable reloading the config after some time. If you don't, the
+ * config will be reloaded and your change overridden.
*/
-@property (nonatomic) bool usesTCP;
+@property (nonatomic) bool forcesTCP;
/**
* @brief The interval in seconds in which the config should be reloaded.
*
* Setting this to 0 disables config reloading.
+ *
+ * @warning If you change this to anything other than 0, the config will be
+ * reloaded eventually, which in turn can override the config
+ * reloading interval itself again.
*/
@property (nonatomic) OFTimeInterval configReloadInterval;
/**
* @brief Creates a new, autoreleased OFDNSResolver.
Index: src/OFDNSResolver.m
==================================================================
--- src/OFDNSResolver.m
+++ src/OFDNSResolver.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer
+ * Copyright (c) 2008-2024 Jonathan Schleifer
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
@@ -421,11 +421,11 @@
OFEnumerator OF_GENERIC(OFMutableArray *) *objectEnumerator;
OFMutableArray *array;
for (uint_fast16_t j = 0; j < count; j++) {
OFString *name = parseName(buffer, length, i,
- maxAllowedPointers);
+ maxAllowedPointers).lowercaseString;
OFDNSClass DNSClass;
OFDNSRecordType recordType;
uint32_t TTL;
uint16_t dataLength;
OFDNSResourceRecord *record;
@@ -464,10 +464,24 @@
[ret makeImmutable];
return ret;
}
+
+static bool
+containsExpiredRecord(OFDNSResponseRecords responseRecords, uint32_t age)
+{
+ OFEnumerator *enumerator = [responseRecords objectEnumerator];
+ OFArray OF_GENERIC(OFDNSResourceRecord *) *records;
+
+ while ((records = [enumerator nextObject]) != nil)
+ for (OFDNSResourceRecord *record in records)
+ if (record.TTL < age)
+ return true;
+
+ return false;
+}
@implementation OFDNSResolverContext
- (instancetype)initWithQuery: (OFDNSQuery *)query
ID: (OFNumber *)ID
settings: (OFDNSResolverSettings *)settings
@@ -576,10 +590,11 @@
@try {
_settings = [[OFDNSResolverSettings alloc] init];
_queries = [[OFMutableDictionary alloc] init];
_TCPQueries = [[OFMutableDictionary alloc] init];
+ _cache = [[OFMutableDictionary alloc] init];
[_settings reload];
} @catch (id e) {
[self release];
@throw e;
@@ -599,10 +614,12 @@
[_IPv6Socket cancelAsyncRequests];
[_IPv6Socket release];
#endif
[_queries release];
[_TCPQueries release];
+ [_cache release];
+ [_lastNameServers release];
[super dealloc];
}
- (OFDictionary *)staticHosts
@@ -676,18 +693,18 @@
{
_settings->_minNumberOfDotsInAbsoluteName =
minNumberOfDotsInAbsoluteName;
}
-- (bool)usesTCP
-{
- return _settings->_usesTCP;
-}
-
-- (void)setUsesTCP: (bool)usesTCP
-{
- _settings->_usesTCP = usesTCP;
+- (bool)forcesTCP
+{
+ return _settings->_forcesTCP;
+}
+
+- (void)setForcesTCP: (bool)forcesTCP
+{
+ _settings->_forcesTCP = forcesTCP;
}
- (OFTimeInterval)configReloadInterval
{
return _settings->_configReloadInterval;
@@ -721,11 +738,11 @@
forMode: runLoopMode];
nameServer = [context->_settings->_nameServers
objectAtIndex: context->_nameServersIndex];
- if (context->_settings->_usesTCP) {
+ if (context->_settings->_forcesTCP) {
OFEnsure(context->_TCPSocket == nil);
context->_TCPSocket = [[OFTCPSocket alloc] init];
[_TCPQueries setObject: context forKey: context->_TCPSocket];
@@ -786,10 +803,49 @@
runLoopMode: runLoopMode];
[sock asyncReceiveIntoBuffer: _buffer
length: bufferLength
runLoopMode: runLoopMode];
}
+
+- (void)of_cleanUpCache
+{
+ OFTimeInterval now = [[OFDate date] timeIntervalSince1970];
+ OFMutableArray *removeList;
+
+ if (_lastNameServers != _settings->_nameServers &&
+ ![_lastNameServers isEqual: _settings->_nameServers]) {
+ OFArray *old = _lastNameServers;
+ _lastNameServers = [_settings->_nameServers copy];
+ [old release];
+
+ [_cache removeAllObjects];
+
+ return;
+ }
+
+ if (now - _lastCacheCleanup < 1)
+ return;
+
+ _lastCacheCleanup = now;
+ removeList = [OFMutableArray arrayWithCapacity: _cache.count];
+
+ for (OFDNSQuery *query in _cache) {
+ OFPair OF_GENERIC(OFDate *, OFDNSResponse *) *entry =
+ [_cache objectForKey: query];
+ uint32_t age =
+ (uint32_t)now - [entry.firstObject timeIntervalSince1970];
+ OFDNSResponse *response = entry.secondObject;
+
+ if (containsExpiredRecord(response.answerRecords, age) ||
+ containsExpiredRecord(response.authorityRecords, age) ||
+ containsExpiredRecord(response.additionalRecords, age))
+ [removeList addObject: query];
+ }
+
+ for (OFDNSQuery *query in removeList)
+ [_cache removeObjectForKey: query];
+}
- (void)asyncPerformQuery: (OFDNSQuery *)query
delegate: (id )delegate
{
[self asyncPerformQuery: query
@@ -802,10 +858,40 @@
delegate: (id )delegate
{
void *pool = objc_autoreleasePoolPush();
OFNumber *ID;
OFDNSResolverContext *context;
+ OFPair OF_GENERIC(OFDate *, OFDNSResponse *) *cacheEntry;
+
+ [self of_cleanUpCache];
+
+ if ((cacheEntry = [_cache objectForKey: query]) != nil) {
+ uint32_t age =
+ (uint32_t)-[cacheEntry.firstObject timeIntervalSinceNow];
+ OFDNSResponse *response = cacheEntry.secondObject;
+
+ if (!containsExpiredRecord(response.answerRecords, age) &&
+ !containsExpiredRecord(response.authorityRecords, age) &&
+ !containsExpiredRecord(response.additionalRecords, age)) {
+ OFTimer *timer = [OFTimer
+ timerWithTimeInterval: 0
+ target: delegate
+ selector: @selector(resolver:
+ didPerformQuery:response:
+ exception:)
+ object: self
+ object: query
+ object: response
+ object: nil
+ repeats: false];
+ [[OFRunLoop currentRunLoop] addTimer: timer
+ forMode: runLoopMode];
+
+ objc_autoreleasePoolPop(pool);
+ return;
+ }
+ }
/* Random, unused ID */
do {
ID = [OFNumber numberWithUnsignedShort: OFRandom16()];
} while ([_queries objectForKey: ID] != nil);
@@ -946,14 +1032,14 @@
/* TC */
if (buffer[2] & 0x02) {
OFRunLoopMode runLoopMode;
- if (context->_settings->_usesTCP)
+ if (context->_settings->_forcesTCP)
@throw [OFTruncatedDataException exception];
- context->_settings->_usesTCP = true;
+ context->_settings->_forcesTCP = true;
runLoopMode = [OFRunLoop currentRunLoop].currentMode;
[self of_sendQueryForContext: context
runLoopMode: runLoopMode];
return false;
}
@@ -1038,10 +1124,19 @@
}
if (exception != nil)
response = nil;
+ [self of_cleanUpCache];
+
+ if (response != nil)
+ [_cache setObject: [OFPair pairWithFirstObject: [OFDate date]
+ secondObject: response]
+ forKey: context->_query];
+ else
+ [_cache removeObjectForKey: context->_query];
+
[context->_delegate resolver: self
didPerformQuery: context->_query
response: response
exception: exception];
Index: src/OFDNSResolverSettings.h
==================================================================
--- src/OFDNSResolverSettings.h
+++ src/OFDNSResolverSettings.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2022 Jonathan Schleifer