Index: .fossil-settings/clean-glob
==================================================================
--- .fossil-settings/clean-glob
+++ .fossil-settings/clean-glob
@@ -30,21 +30,27 @@
src/bridge/Info.plist
src/libobjfw.*
src/objfw-defs.h
src/runtime/Info.plist
src/runtime/libobjfwrt.*
+src/tls/Info.plist
tests/DerivedData
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
tests/tests.arm9
tests/tests.nds
+tests/tests.nro
+tests/tests.rpx
utils/objfw-config
utils/ofarc/ofarc
utils/ofdns/ofdns
utils/ofhash/ofhash
utils/ofhttp/ofhttp
Index: .fossil-settings/ignore-glob
==================================================================
--- .fossil-settings/ignore-glob
+++ .fossil-settings/ignore-glob
@@ -32,24 +32,30 @@
src/bridge/Info.plist
src/libobjfw.*
src/objfw-defs.h
src/runtime/Info.plist
src/runtime/libobjfwrt.*
+src/tls/Info.plist
tests/DerivedData
tests/EBOOT.PBP
tests/Info.plist
tests/PARAM.SFO
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
tests/tests.arm9
tests/tests.nds
+tests/tests.nro
+tests/tests.rpx
utils/objfw-config
utils/ofarc/ofarc
utils/ofdns/ofdns
utils/ofhash/ofhash
utils/ofhttp/ofhttp
ADDED .github/workflows/amiga-gcc.yml
Index: .github/workflows/amiga-gcc.yml
==================================================================
--- /dev/null
+++ .github/workflows/amiga-gcc.yml
@@ -0,0 +1,37 @@
+name: amiga-gcc
+on: [push, pull_request]
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ configure_flags:
+ -
+ - --disable-amiga-lib
+ steps:
+ - name: Install dependencies
+ run: docker pull amigadev/crosstools:m68k-amigaos
+ - uses: actions/checkout@v2
+ - name: autogen.sh
+ run: ./autogen.sh
+ - name: configure
+ run: |
+ docker run \
+ -e PATH="/opt/m68k-amigaos/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ amigadev/crosstools:m68k-amigaos \
+ sh -c 'cd /objfw && ./configure --host=m68k-amigaos ${{ matrix.configure_flags }}'
+ - name: make
+ run: |
+ docker run \
+ -e PATH="/opt/m68k-amigaos/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ amigadev/crosstools:m68k-amigaos \
+ sh -c "cd /objfw && make -j$(nproc)"
+ - name: make install
+ run: |
+ docker run \
+ -e PATH="/opt/m68k-amigaos/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ amigadev/crosstools:m68k-amigaos \
+ sh -c "cd /objfw && make -j$(nproc)"
ADDED .github/workflows/ios.yml
Index: .github/workflows/ios.yml
==================================================================
--- /dev/null
+++ .github/workflows/ios.yml
@@ -0,0 +1,35 @@
+name: ios
+on: [push, pull_request]
+jobs:
+ build:
+ runs-on: macos-latest
+ strategy:
+ matrix:
+ arch:
+ - arm64
+ - x86_64
+ configure_flags:
+ -
+ - --disable-shared
+ steps:
+ - name: Install dependencies
+ run: brew install autoconf automake
+ - uses: actions/checkout@v2
+ - name: autogen.sh
+ run: ./autogen.sh
+ - name: configure
+ run: |
+ export IPHONEOS_DEPLOYMENT_TARGET="9.0"
+ if [ "${{ matrix.arch}}" = "x86_64" ]; then
+ sdk="iphonesimulator"
+ else
+ sdk="iphoneos"
+ fi
+ export OBJC="clang -isysroot $(xcrun --sdk $sdk --show-sdk-path)"
+ export OBJC="$OBJC -arch ${{ matrix.arch }}"
+ ./configure --host=${{ matrix.arch }}-apple-darwin \
+ ${{ matrix.configure_flags }}
+ - name: make
+ run: make -j$(sysctl -n hw.logicalcpu)
+ - name: make install
+ run: sudo make install
ADDED .github/workflows/macos-10.15.yml
Index: .github/workflows/macos-10.15.yml
==================================================================
--- /dev/null
+++ .github/workflows/macos-10.15.yml
@@ -0,0 +1,31 @@
+name: macos-10.15
+on: [push, pull_request]
+jobs:
+ tests:
+ runs-on: macos-10.15
+ 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@v2
+ - 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
ADDED .github/workflows/macos-11.yml
Index: .github/workflows/macos-11.yml
==================================================================
--- /dev/null
+++ .github/workflows/macos-11.yml
@@ -0,0 +1,31 @@
+name: macos-11
+on: [push, pull_request]
+jobs:
+ tests:
+ runs-on: macos-11
+ 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@v2
+ - 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
ADDED .github/workflows/morphos.yml
Index: .github/workflows/morphos.yml
==================================================================
--- /dev/null
+++ .github/workflows/morphos.yml
@@ -0,0 +1,37 @@
+name: morphos
+on: [push, pull_request]
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ configure_flags:
+ -
+ - --disable-amiga-lib
+ steps:
+ - name: Install dependencies
+ run: docker pull amigadev/crosstools:ppc-morphos
+ - uses: actions/checkout@v2
+ - name: autogen.sh
+ run: ./autogen.sh
+ - name: configure
+ run: |
+ docker run \
+ -e PATH="/opt/ppc-morphos/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ amigadev/crosstools:ppc-morphos \
+ sh -c 'cd /objfw && ./configure --host=ppc-morphos ${{ matrix.configure_flags }}'
+ - name: make
+ run: |
+ docker run \
+ -e PATH="/opt/ppc-morphos/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ amigadev/crosstools:ppc-morphos \
+ sh -c "cd /objfw && make -j$(nproc)"
+ - name: make install
+ run: |
+ docker run \
+ -e PATH="/opt/ppc-morphos/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ amigadev/crosstools:ppc-morphos \
+ sh -c "cd /objfw && make -j$(nproc)"
ADDED .github/workflows/nintendo-3ds.yml
Index: .github/workflows/nintendo-3ds.yml
==================================================================
--- /dev/null
+++ .github/workflows/nintendo-3ds.yml
@@ -0,0 +1,35 @@
+name: nintendo-3ds
+on: [push, pull_request]
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Install dependencies
+ run: docker pull devkitpro/devkitarm
+ - uses: actions/checkout@v2
+ - name: autogen.sh
+ run: ./autogen.sh
+ - name: configure
+ run: |
+ docker run \
+ -e DEVKITPRO=/opt/devkitpro \
+ -e PATH="/opt/devkitpro/devkitARM/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ devkitpro/devkitarm \
+ sh -c 'cd /objfw && ./configure --host=arm-none-eabi --with-3ds'
+ - name: make
+ run: |
+ docker run \
+ -e DEVKITPRO=/opt/devkitpro \
+ -e PATH="/opt/devkitpro/devkitARM/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ devkitpro/devkitarm \
+ sh -c "cd /objfw && make -j$(nproc)"
+ - name: make install
+ run: |
+ docker run \
+ -e DEVKITPRO=/opt/devkitpro \
+ -e PATH="/opt/devkitpro/devkitARM/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ devkitpro/devkitarm \
+ sh -c "cd /objfw && make -j$(nproc)"
ADDED .github/workflows/nintendo-ds.yml
Index: .github/workflows/nintendo-ds.yml
==================================================================
--- /dev/null
+++ .github/workflows/nintendo-ds.yml
@@ -0,0 +1,35 @@
+name: nintendo-ds
+on: [push, pull_request]
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Install dependencies
+ run: docker pull devkitpro/devkitarm
+ - uses: actions/checkout@v2
+ - name: autogen.sh
+ run: ./autogen.sh
+ - name: configure
+ run: |
+ docker run \
+ -e DEVKITPRO=/opt/devkitpro \
+ -e PATH="/opt/devkitpro/devkitARM/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ devkitpro/devkitarm \
+ sh -c 'cd /objfw && ./configure --host=arm-none-eabi --with-nds'
+ - name: make
+ run: |
+ docker run \
+ -e DEVKITPRO=/opt/devkitpro \
+ -e PATH="/opt/devkitpro/devkitARM/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ devkitpro/devkitarm \
+ sh -c "cd /objfw && make -j$(nproc)"
+ - name: make install
+ run: |
+ docker run \
+ -e DEVKITPRO=/opt/devkitpro \
+ -e PATH="/opt/devkitpro/devkitARM/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ devkitpro/devkitarm \
+ sh -c "cd /objfw && make -j$(nproc)"
ADDED .github/workflows/nintendo-switch.yml
Index: .github/workflows/nintendo-switch.yml
==================================================================
--- /dev/null
+++ .github/workflows/nintendo-switch.yml
@@ -0,0 +1,35 @@
+name: nintendo-switch
+on: [push, pull_request]
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Install dependencies
+ run: docker pull devkitpro/devkita64
+ - uses: actions/checkout@v2
+ - name: autogen.sh
+ run: ./autogen.sh
+ - name: configure
+ run: |
+ docker run \
+ -e DEVKITPRO=/opt/devkitpro \
+ -e PATH="/opt/devkitpro/devkitA64/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ devkitpro/devkita64 \
+ sh -c 'cd /objfw && ./configure --host=aarch64-none-elf --with-nintendo-switch'
+ - name: make
+ run: |
+ docker run \
+ -e DEVKITPRO=/opt/devkitpro \
+ -e PATH="/opt/devkitpro/devkitA64/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ devkitpro/devkita64 \
+ sh -c "cd /objfw && make -j$(nproc)"
+ - name: make install
+ run: |
+ docker run \
+ -e DEVKITPRO=/opt/devkitpro \
+ -e PATH="/opt/devkitpro/devkitA64/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ devkitpro/devkita64 \
+ sh -c "cd /objfw && make -j$(nproc)"
ADDED .github/workflows/ubuntu-18.04-32bit.yml
Index: .github/workflows/ubuntu-18.04-32bit.yml
==================================================================
--- /dev/null
+++ .github/workflows/ubuntu-18.04-32bit.yml
@@ -0,0 +1,37 @@
+name: ubuntu-18.04, 32 bit
+on: [push, pull_request]
+jobs:
+ tests:
+ runs-on: ubuntu-18.04
+ strategy:
+ matrix:
+ configure_flags:
+ - --without-tls
+ - --without-tls --enable-seluid24
+ - --without-tls --disable-compiler-tls
+ - --without-tls --disable-threads
+ - --without-tls --disable-threads --disable-sockets
+ - --without-tls --disable-threads --disable-files
+ - --without-tls --disable-threads --disable-sockets --disable-files
+ - --without-tls --disable-sockets
+ - --without-tls --disable-sockets --disable-files
+ - --without-tls --disable-files
+ - --without-tls --disable-shared
+ - --without-tls --disable-shared --enable-seluid24
+ - --without-tls --disable-compiler-tls --disable-threads
+ steps:
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install gcc-multilib
+ - uses: actions/checkout@v2
+ - name: autogen.sh
+ run: ./autogen.sh
+ - name: configure
+ run: ./configure OBJC="clang -m32" ${{ matrix.configure_flags }}
+ - name: make
+ run: make -j$(nproc)
+ - name: make check
+ run: make check
+ - name: make install
+ run: sudo make install
ADDED .github/workflows/ubuntu-18.04-gcc-32bit.yml
Index: .github/workflows/ubuntu-18.04-gcc-32bit.yml
==================================================================
--- /dev/null
+++ .github/workflows/ubuntu-18.04-gcc-32bit.yml
@@ -0,0 +1,37 @@
+name: ubuntu-18.04, GCC, 32 bit
+on: [push, pull_request]
+jobs:
+ tests:
+ runs-on: ubuntu-18.04
+ strategy:
+ matrix:
+ configure_flags:
+ - --without-tls
+ - --without-tls --enable-seluid24
+ - --without-tls --disable-compiler-tls
+ - --without-tls --disable-threads
+ - --without-tls --disable-threads --disable-sockets
+ - --without-tls --disable-threads --disable-files
+ - --without-tls --disable-threads --disable-sockets --disable-files
+ - --without-tls --disable-sockets
+ - --without-tls --disable-sockets --disable-files
+ - --without-tls --disable-files
+ - --without-tls --disable-shared
+ - --without-tls --disable-shared --enable-seluid24
+ - --without-tls --disable-compiler-tls --disable-threads
+ steps:
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install gcc-multilib gobjc
+ - uses: actions/checkout@v2
+ - name: autogen.sh
+ run: ./autogen.sh
+ - name: configure
+ run: ./configure OBJC="gcc -m32" ${{ matrix.configure_flags }}
+ - name: make
+ run: make -j$(nproc)
+ - name: make check
+ run: make check
+ - name: make install
+ run: sudo make install
ADDED .github/workflows/ubuntu-18.04-gcc.yml
Index: .github/workflows/ubuntu-18.04-gcc.yml
==================================================================
--- /dev/null
+++ .github/workflows/ubuntu-18.04-gcc.yml
@@ -0,0 +1,39 @@
+name: ubuntu-18.04, GCC
+on: [push, pull_request]
+jobs:
+ tests:
+ runs-on: ubuntu-18.04
+ strategy:
+ matrix:
+ configure_flags:
+ -
+ - --enable-seluid24
+ - --disable-compiler-tls
+ - --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
+ - --disable-shared --enable-seluid24
+ - --disable-compiler-tls --disable-threads
+ - --with-tls=gnutls
+ - --with-tls=gnutls --disable-shared
+ steps:
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install gobjc libssl-dev gnutls-dev
+ - uses: actions/checkout@v2
+ - name: autogen.sh
+ run: ./autogen.sh
+ - name: configure
+ run: ./configure OBJC="gcc" ${{ matrix.configure_flags }}
+ - name: make
+ run: make -j$(nproc)
+ - name: make check
+ run: make check
+ - name: make install
+ run: sudo make install
ADDED .github/workflows/ubuntu-18.04.yml
Index: .github/workflows/ubuntu-18.04.yml
==================================================================
--- /dev/null
+++ .github/workflows/ubuntu-18.04.yml
@@ -0,0 +1,39 @@
+name: ubuntu-18.04
+on: [push, pull_request]
+jobs:
+ tests:
+ runs-on: ubuntu-18.04
+ strategy:
+ matrix:
+ configure_flags:
+ -
+ - --enable-seluid24
+ - --disable-compiler-tls
+ - --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
+ - --disable-shared --enable-seluid24
+ - --disable-compiler-tls --disable-threads
+ - --with-tls=gnutls
+ - --with-tls=gnutls --disable-shared
+ steps:
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install libssl-dev gnutls-dev
+ - uses: actions/checkout@v2
+ - name: autogen.sh
+ run: ./autogen.sh
+ - name: configure
+ run: ./configure ${{ matrix.configure_flags }}
+ - name: make
+ run: make -j$(nproc)
+ - name: make check
+ run: make check
+ - name: make install
+ run: sudo make install
ADDED .github/workflows/ubuntu-20.04-32bit.yml
Index: .github/workflows/ubuntu-20.04-32bit.yml
==================================================================
--- /dev/null
+++ .github/workflows/ubuntu-20.04-32bit.yml
@@ -0,0 +1,37 @@
+name: ubuntu-20.04, 32 bit
+on: [push, pull_request]
+jobs:
+ tests:
+ runs-on: ubuntu-20.04
+ strategy:
+ matrix:
+ configure_flags:
+ - --without-tls
+ - --without-tls --enable-seluid24
+ - --without-tls --disable-compiler-tls
+ - --without-tls --disable-threads
+ - --without-tls --disable-threads --disable-sockets
+ - --without-tls --disable-threads --disable-files
+ - --without-tls --disable-threads --disable-sockets --disable-files
+ - --without-tls --disable-sockets
+ - --without-tls --disable-sockets --disable-files
+ - --without-tls --disable-files
+ - --without-tls --disable-shared
+ - --without-tls --disable-shared --enable-seluid24
+ - --without-tls --disable-compiler-tls --disable-threads
+ steps:
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install gcc-multilib
+ - uses: actions/checkout@v2
+ - name: autogen.sh
+ run: ./autogen.sh
+ - name: configure
+ run: ./configure OBJC="clang -m32" ${{ matrix.configure_flags }}
+ - name: make
+ run: make -j$(nproc)
+ - name: make check
+ run: make check
+ - name: make install
+ run: sudo make install
ADDED .github/workflows/ubuntu-20.04-gcc-32bit.yml
Index: .github/workflows/ubuntu-20.04-gcc-32bit.yml
==================================================================
--- /dev/null
+++ .github/workflows/ubuntu-20.04-gcc-32bit.yml
@@ -0,0 +1,37 @@
+name: ubuntu-20.04, GCC, 32 bit
+on: [push, pull_request]
+jobs:
+ tests:
+ runs-on: ubuntu-20.04
+ strategy:
+ matrix:
+ configure_flags:
+ - --without-tls
+ - --without-tls --enable-seluid24
+ - --without-tls --disable-compiler-tls
+ - --without-tls --disable-threads
+ - --without-tls --disable-threads --disable-sockets
+ - --without-tls --disable-threads --disable-files
+ - --without-tls --disable-threads --disable-sockets --disable-files
+ - --without-tls --disable-sockets
+ - --without-tls --disable-sockets --disable-files
+ - --without-tls --disable-files
+ - --without-tls --disable-shared
+ - --without-tls --disable-shared --enable-seluid24
+ - --without-tls --disable-compiler-tls --disable-threads
+ steps:
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install gcc-multilib gobjc
+ - uses: actions/checkout@v2
+ - name: autogen.sh
+ run: ./autogen.sh
+ - name: configure
+ run: ./configure OBJC="gcc -m32" ${{ matrix.configure_flags }}
+ - name: make
+ run: make -j$(nproc)
+ - name: make check
+ run: make check
+ - name: make install
+ run: sudo make install
ADDED .github/workflows/ubuntu-20.04-gcc.yml
Index: .github/workflows/ubuntu-20.04-gcc.yml
==================================================================
--- /dev/null
+++ .github/workflows/ubuntu-20.04-gcc.yml
@@ -0,0 +1,39 @@
+name: ubuntu-20.04, GCC
+on: [push, pull_request]
+jobs:
+ tests:
+ runs-on: ubuntu-20.04
+ strategy:
+ matrix:
+ configure_flags:
+ -
+ - --enable-seluid24
+ - --disable-compiler-tls
+ - --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
+ - --disable-shared --enable-seluid24
+ - --disable-compiler-tls --disable-threads
+ - --with-tls=gnutls
+ - --with-tls=gnutls --disable-shared
+ steps:
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install gobjc libssl-dev gnutls-dev
+ - uses: actions/checkout@v2
+ - name: autogen.sh
+ run: ./autogen.sh
+ - name: configure
+ run: ./configure OBJC="gcc" ${{ matrix.configure_flags }}
+ - name: make
+ run: make -j$(nproc)
+ - name: make check
+ run: make check
+ - name: make install
+ run: sudo make install
ADDED .github/workflows/ubuntu-20.04.yml
Index: .github/workflows/ubuntu-20.04.yml
==================================================================
--- /dev/null
+++ .github/workflows/ubuntu-20.04.yml
@@ -0,0 +1,39 @@
+name: ubuntu-20.04
+on: [push, pull_request]
+jobs:
+ tests:
+ runs-on: ubuntu-20.04
+ strategy:
+ matrix:
+ configure_flags:
+ -
+ - --enable-seluid24
+ - --disable-compiler-tls
+ - --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
+ - --disable-shared --enable-seluid24
+ - --disable-compiler-tls --disable-threads
+ - --with-tls=gnutls
+ - --with-tls=gnutls --disable-shared
+ steps:
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install libssl-dev gnutls-dev
+ - uses: actions/checkout@v2
+ - name: autogen.sh
+ run: ./autogen.sh
+ - name: configure
+ run: ./configure ${{ matrix.configure_flags }}
+ - name: make
+ run: make -j$(nproc)
+ - name: make check
+ run: make check
+ - name: make install
+ run: sudo make install
ADDED .github/workflows/wii-u.yml
Index: .github/workflows/wii-u.yml
==================================================================
--- /dev/null
+++ .github/workflows/wii-u.yml
@@ -0,0 +1,35 @@
+name: wii-u
+on: [push, pull_request]
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Install dependencies
+ run: docker pull devkitpro/devkitppc
+ - uses: actions/checkout@v2
+ - name: autogen.sh
+ run: ./autogen.sh
+ - name: configure
+ run: |
+ docker run \
+ -e DEVKITPRO=/opt/devkitpro \
+ -e PATH="/opt/devkitpro/devkitPPC/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ devkitpro/devkitppc \
+ sh -c 'cd /objfw && ./configure --host=powerpc-eabi --with-wii-u'
+ - name: make
+ run: |
+ docker run \
+ -e DEVKITPRO=/opt/devkitpro \
+ -e PATH="/opt/devkitpro/devkitPPC/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ devkitpro/devkitppc \
+ sh -c "cd /objfw && make -j$(nproc)"
+ - name: make install
+ run: |
+ docker run \
+ -e DEVKITPRO=/opt/devkitpro \
+ -e PATH="/opt/devkitpro/devkitPPC/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ devkitpro/devkitppc \
+ sh -c "cd /objfw && make -j$(nproc)"
ADDED .github/workflows/wii.yml
Index: .github/workflows/wii.yml
==================================================================
--- /dev/null
+++ .github/workflows/wii.yml
@@ -0,0 +1,35 @@
+name: wii
+on: [push, pull_request]
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Install dependencies
+ run: docker pull devkitpro/devkitppc
+ - uses: actions/checkout@v2
+ - name: autogen.sh
+ run: ./autogen.sh
+ - name: configure
+ run: |
+ docker run \
+ -e DEVKITPRO=/opt/devkitpro \
+ -e PATH="/opt/devkitpro/devkitPPC/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ devkitpro/devkitppc \
+ sh -c 'cd /objfw && ./configure --host=powerpc-eabi --with-wii'
+ - name: make
+ run: |
+ docker run \
+ -e DEVKITPRO=/opt/devkitpro \
+ -e PATH="/opt/devkitpro/devkitPPC/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ devkitpro/devkitppc \
+ sh -c "cd /objfw && make -j$(nproc)"
+ - name: make install
+ run: |
+ docker run \
+ -e DEVKITPRO=/opt/devkitpro \
+ -e PATH="/opt/devkitpro/devkitPPC/bin:$PATH" \
+ -v "$PWD:/objfw" \
+ devkitpro/devkitppc \
+ sh -c "cd /objfw && make -j$(nproc)"
Index: .gitignore
==================================================================
--- .gitignore
+++ .gitignore
@@ -32,24 +32,30 @@
src/bridge/Info.plist
src/libobjfw.*
src/objfw-defs.h
src/runtime/Info.plist
src/runtime/libobjfwrt.*
+src/tls/Info.plist
tests/DerivedData
tests/EBOOT.PBP
tests/Info.plist
tests/PARAM.SFO
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
tests/tests.arm9
tests/tests.nds
+tests/tests.nro
+tests/tests.rpx
utils/objfw-config
utils/ofarc/ofarc
utils/ofdns/ofdns
utils/ofhash/ofhash
utils/ofhttp/ofhttp
Index: Doxyfile
==================================================================
--- Doxyfile
+++ Doxyfile
@@ -1,15 +1,18 @@
PROJECT_NAME = "ObjFW"
OUTPUT_DIRECTORY = docs/
INPUT = src src/exceptions src/runtime
FILE_PATTERNS = *.h *.m
HTML_OUTPUT = .
+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(...)= \
Index: Makefile
==================================================================
--- Makefile
+++ Makefile
@@ -14,10 +14,13 @@
.PHONY: docs release
utils tests: src
+check: tests
+ cd tests && ${MAKE} -s run
+
docs:
rm -fr docs
doxygen >/dev/null
release: docs
Index: PLATFORMS.md
==================================================================
--- PLATFORMS.md
+++ PLATFORMS.md
@@ -103,10 +103,20 @@
* OS Versions: 10.5, 10.7-10.15, Darling
* Architectures: PowerPC, PowerPC64, x86, x86_64
* Compilers: Clang 3.1-10.0, Apple GCC 4.0.1 & 4.2.1
* Runtimes: Apple, ObjFW
+
+MiNT
+----
+
+ * OS Versions: FreeMiNT 1.19
+ * Architectures: m68k
+ * Runtimes: ObjFW
+ * Compilers: GCC 4.6.4 (MiNT 20130415)
+ * Limitations: No shared libraries, no threads
+
MorphOS
-------
* OS Versions: 3.14
@@ -142,10 +152,20 @@
* Compilers: GCC 4.8.2 (devkitARM release 42)
* Runtimes: ObjFW
* Limitations: No threads, no sockets
* Notes: File support requires an argv-compatible launcher (such as HBMenu)
+
+Nintendo Switch
+---------------
+
+ * OS Versions: yuzu 1093
+ * Architectures: AArch64
+ * Compilers: GCC 12.1.0 (devkitA64 release 19)
+ * Runtimes: ObjFW
+ * Limitations: No sockets, no shared libraries, not tested on real hardware
+
OpenBSD
-------
* OS Versions: 5.2-6.7
@@ -189,20 +209,32 @@
* Architectures: PowerPC
* Compilers: GCC 4.6.3 (devkitPPC release 26)
* Runtimes: ObjFW
* Limitations: No threads
+
+Wii U
+-----
+
+ * OS Versions: Cemu 12.26.2f
+ * Architectures: PowerPC
+ * Compilers: gcc version 12.1.0 (devkitPPC release 41)
+ * Runtimes: ObjFW
+ * Limitations: No files, no threads, no sockets, no shared libraries, not
+ tested on real hardware
+
Windows
-------
- * OS Versions: 98 SE, NT 4.0, XP (x86), 7 (x64), 8 (x64), 8.1 (x64), 10,
+ * 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
+ * Architectures: x86, x86_64, AArch64
* Compilers: GCC 5.3.0 & 6.2.0 from msys2 (x86 & x64),
Clang 3.9.0 from msys2 (x86),
- Clang 10.0 from msys2 (x86 & x86_64)
+ Clang 10.0 from msys2 (x86 & x86_64),
+ Clang 14.0.4 from msys2 (AArch64)
* Runtimes: ObjFW
Others
------
Index: README.md
==================================================================
--- README.md
+++ README.md
@@ -1,10 +1,10 @@
There are three ways you are probably reading this right now:
- * On [ObjFW](https://objfw.nil.im/)'s homepage, via Fossil
+ * On [ObjFW](https://objfw.nil.im/)'s homepage, via Fossil's web interface
* On [GitHub](https://github.com/ObjFW/ObjFW)
- * Via an editor or pager, by opening `README.md` from a checkout or tarball
+ * Via an editor or pager, by opening `README.md` from a clone or tarball
ObjFW is developed using Fossil, so if you are reading this on GitHub or any
other place, you are most likely using a mirror.
@@ -19,12 +19,11 @@
* [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)
* [Getting MSYS2](#getting-msys2)
- * [Updating MSYS2](#updating-msys2)
- * [Installing MinGW-w64 using MSYS2](#installing-mingw-w64)
+ * [Setting up MSYS2](#setting-up-msys2)
* [Getting, building and installing ObjFW](#steps-windows)
* [Nintendo DS, Nintendo 3DS and Wii](#nintendo)
* [Nintendo DS](#nintendo-ds)
* [Nintendo 3DS](#nintendo-3ds)
* [Wii](#wii)
@@ -31,10 +30,12 @@
* [Amiga](#amiga)
* [Writing your first application with ObjFW](#first-app)
* [Documentation](#documentation)
* [Bugs and feature requests](#bugs)
* [Support and community](#support)
+ * [Donating](#donating)
+ * [Thanks](#thanks)
* [Commercial use](#commercial-use)
What is ObjFW?
@@ -106,17 +107,16 @@
Fossil
Clone the Fossil repository like this:
- $ fossil clone https://objfw.nil.im objfw.fossil
- $ mkdir objfw && cd objfw
- $ fossil open ../objfw.fossil
+ $ fossil clone https://objfw.nil.im
You can then use Fossil's web interface to browse the timeline, tickets,
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.
@@ -123,10 +123,16 @@
In order to verify the signature of the currently checked out checkin, you
can use:
$ fossil artifact current | gpg --verify
+
+ Please note that not all checkins are signed, as the signing key only resides
+ on trusted systems. This means that checkins I perform on e.g. Windows are
+ unsigned. However, usually it should not take long until there is another
+ signed checkin. Alternatively, you can go back until the last signed checkin
+ and review changes from there on.
Git
To clone the Git repository, use the following:
@@ -139,11 +145,12 @@
To install ObjFW, just run the following commands:
$ ./configure
$ make
- $ make install
+ $ make check
+ $ sudo make install
In case you checked out ObjFW from the Fossil or Git repository, you need to
run the following command first:
$ ./autogen.sh
@@ -151,27 +158,33 @@
macOS and iOS
Building as a framework
When building for macOS or iOS, everything is built as a `.framework` by
- default if `--disable-shared` has not been specified to `configure`.
+ default if `--disable-shared` has not been specified to `./configure`. The
+ frameworks will end up in `$PREFIX/Library/Frameworks`.
- To build for iOS, use something like this:
+ To build for macOS, just follow the
+ 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"
$ ./configure --prefix=/usr/local/ios --host=arm64-apple-darwin
- To build for the iOS simulator, use something like this:
+ 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 i386 -arch x86_64"
- $ export OBJCPP="$clang -arch i386 -E"
+ $ 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=x86_64-apple-darwin
+ $ ./configure --prefix=/usr/local/iossim --host=arm64-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`:
@@ -209,73 +222,61 @@
Getting MSYS2
The first thing to install is [MSYS2](https://www.msys2.org) to provide a
basic UNIX-like environment for Windows. Unfortunately, the binaries are not
- signed and there is no way to verify their integrity, so only download this
- from a trusted connection. Everything else you will download using MSYS2
- later will be cryptographically signed.
-
-Updating MSYS2
-
- The first thing to do is updating MSYS2. It is important to update things in
- a certain order, as `pacman` (the package manager MSYS2 uses, which comes
- from Arch Linux) does not know about a few things that are special on
- Windows.
-
- First, update the mirror list:
-
- $ pacman -Sy pacman-mirrors
-
- Then proceed to update the `msys2-runtime` itself, `bash` and `pacman`:
-
- $ pacman -S msys2-runtime bash pacman mintty
-
- Now close the current window and restart MSYS2, as the current window is now
- defunct. In a new MSYS2 window, update the rest of MSYS2:
-
- $ pacman -Su
-
- Now you have a fully updated MSYS2. Whenever you want to update MSYS2,
- proceed in this order. Notice that the first `pacman` invocation includes
- `-y` to actually fetch a new list of packages.
-
-Installing MinGW-w64 using MSYS2
-
- Now it's time to install MinGW-w64. If you want to build 32 bit binaries:
-
- $ pacman -S mingw-w64-i686-clang mingw-w64-i686-gcc-objc
-
- For 64 bit binaries:
-
- $ pacman -S mingw-w64-x86_64-clang mingw-w64-x86_64-gcc-objc
-
- There is nothing wrong with installing them both, as MSYS2 has created two
- entries in your start menu: `MinGW-w64 Win32 Shell` and
- `MinGW-w64 Win64 Shell`. So if you want to build for 32 or 64 bit, you just
- start the correct shell.
-
- Finally, install a few more things needed to build ObjFW:
-
- $ pacman -S autoconf automake fossil make
+ signed, so make sure you download it via HTTPS. However, packages you
+ download and install via MSYS2 are cryptographically signed.
+
+Setting up MSYS2
+
+ MSYS2 currently supports 5 different
+ [environments](https://www.msys2.org/docs/environments/). All of them except
+ for the one called just "MSYS" are supported, but which packages you need to
+ install depends on the environment(s) you want to use.
+
+ For MINGW64, use:
+
+ $ pacman -Syu mingw-w64-x86_64-clang mingw-w64-x86_64-fossil
+
+ For UCRT64, use:
+
+ $ pacman -Syu mingw-w64-ucrt-x86_64-clang mingw-w64-ucrt-x86_64-fossil
+
+ For CLANG64, use:
+
+ $ pacman -Syu mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-fossil
+
+ For MINGW32, use:
+
+ $ pacman -Syu mingw-w64-i686-clang mingw-w64-i686-fossil
+
+ When using `pacman` to install the packages, `pacman` might tell you to close
+ the window. If it does so, close the window, restart MSYS2 and execute the
+ `pacman` command again.
+
+ There is nothing wrong with installing multiple environments, as MSYS2 has
+ created shortcuts for each of them in your start menu. Just make sure to use
+ the correct shortcut for the environment you want to use.
+
+ Finally, install a few more things that are common between all environments:
+
+ $ pacman -S autoconf automake make
Getting, building and installing ObjFW
- Start the MinGW-w64 Win32 or Win64 Shell (depening on what version you want
- to build - do *not* use the MSYS2 Shell shortcut, but use the MinGW-w64 Win32
- or Win64 Shell shortcut instead!) and check out ObjFW:
-
- $ fossil clone https://objfw.nil.im objfw.fossil
- $ mkdir objfw && cd objfw
- $ fossil open ../objfw.fossil
-
- You can also download a release tarball if you want. Now go to the newly
+ Start the MSYS2 using the shortcut for the environment you want to use and
+ check out ObjFW:
+
+ $ fossil clone https://objfw.nil.im
+
+ You can also download a release tarball if you want. Now `cd` to the newly
checked out repository and build and install it:
$ ./autogen.sh && ./configure && make -j16 install
- If everything was successfully, you can now build projects using ObjFW for
+ If everything was successful, you can now build projects using ObjFW for
Windows using the normal `objfw-compile` and friends.
Nintendo DS, Nintendo 3DS and Wii
Download and install [devkitPro](https://devkitpro.org/wiki/Getting_Started).
@@ -368,12 +369,27 @@
* 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
+
+ If you want to donate to ObjFW, you can read about possible ways to do so
+ [here](https://objfw.nil.im/wiki?name=Donating).
+
+
+Thanks
+
+ * 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!
+
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: build-aux/m4/buildsys.m4
==================================================================
--- build-aux/m4/buildsys.m4
+++ build-aux/m4/buildsys.m4
@@ -24,10 +24,13 @@
AC_DEFUN([BUILDSYS_INIT], [
AC_REQUIRE([AC_CANONICAL_BUILD])
AC_REQUIRE([AC_CANONICAL_HOST])
+ AC_ARG_ENABLE(rpath,
+ AS_HELP_STRING([--disable-rpath], [do not use rpath]))
+
case "$build_os" in
darwin*)
case "$host_os" in
darwin*)
AC_SUBST(BUILD_AND_HOST_ARE_DARWIN, yes)
@@ -180,11 +183,13 @@
LIB_CFLAGS='-fPIC -DPIC'
LIB_LDFLAGS='-dynamiclib -current_version ${LIB_MAJOR}.${LIB_MINOR} -compatibility_version ${LIB_MAJOR}'
LIB_LDFLAGS_INSTALL_NAME='-Wl,-install_name,${libdir}/$${out%.dylib}.${LIB_MAJOR}.dylib'
LIB_PREFIX='lib'
LIB_SUFFIX='.dylib'
- LDFLAGS_RPATH='-Wl,-rpath,${libdir}'
+ 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'
@@ -198,21 +203,21 @@
CLEAN_LIB=''
;;
*-*-mingw* | *-*-cygwin*)
AC_MSG_RESULT(MinGW / Cygwin)
LIB_CFLAGS=''
- LIB_LDFLAGS='-shared -Wl,--export-all-symbols,--out-implib,lib$$out.a'
+ LIB_LDFLAGS='-shared -Wl,--export-all-symbols'
LIB_LDFLAGS_INSTALL_NAME=''
LIB_PREFIX=''
- LIB_SUFFIX='.dll'
- LDFLAGS_RPATH='-Wl,-rpath,${libdir}'
+ LIB_SUFFIX='${LIB_MAJOR}.dll'
+ LINK_LIB='&& ${LN_S} $$out lib$${out%${LIB_SUFFIX}}.dll.a'
PLUGIN_CFLAGS=''
- PLUGIN_LDFLAGS='-shared'
+ 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.a ${DESTDIR}${libdir}/lib$$i.a'
- UNINSTALL_LIB='&& rm -f ${DESTDIR}${bindir}/$$i ${DESTDIR}${libdir}/lib$$i.a'
+ 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*)
@@ -220,11 +225,13 @@
LIB_CFLAGS='-fPIC -DPIC'
LIB_LDFLAGS='-shared'
LIB_LDFLAGS_INSTALL_NAME=''
LIB_PREFIX='lib'
LIB_SUFFIX='.so.${LIB_MAJOR}.${LIB_MINOR}'
- LDFLAGS_RPATH='-Wl,-rpath,${libdir}'
+ 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'
@@ -238,11 +245,13 @@
LIB_CFLAGS='-fPIC -DPIC'
LIB_LDFLAGS='-shared -Wl,-soname=$$out.${LIB_MAJOR}.${LIB_MINOR}'
LIB_LDFLAGS_INSTALL_NAME=''
LIB_PREFIX='lib'
LIB_SUFFIX='.so'
- LDFLAGS_RPATH='-Wl,-rpath,${libdir}'
+ 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'
@@ -256,11 +265,10 @@
LIB_CFLAGS='-fPIC -DPIC'
LIB_LDFLAGS='-shared -Wl,-soname=$$out.${LIB_MAJOR}'
LIB_LDFLAGS_INSTALL_NAME=''
LIB_PREFIX='lib'
LIB_SUFFIX='.so'
- LDFLAGS_RPATH=''
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'
@@ -275,11 +283,13 @@
LIB_LDFLAGS='-shared -Wl,+h,$$out'
LIB_LDFLAGS_INSTALL_NAME=''
LIB_PREFIX='lib'
LIB_SUFFIX='.${LIB_MAJOR}'
LINK_LIB='&& rm -f $${out%%.*}.sl && ${LN_S} $$out $${out%%.*}.sl'
- LDFLAGS_RPATH='-Wl,+b,${libdir}'
+ 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'
@@ -294,11 +304,13 @@
LIB_LDFLAGS='-shared -Wl,+h,$$out'
LIB_LDFLAGS_INSTALL_NAME=''
LIB_PREFIX='lib'
LIB_SUFFIX='.${LIB_MAJOR}'
LINK_LIB='&& rm -f $${out%%.*}.so && ${LN_S} $$out $${out%%.*}.so'
- LDFLAGS_RPATH='-Wl,+b,${libdir}'
+ 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'
@@ -312,11 +324,13 @@
LIB_CFLAGS='-fPIC -DPIC'
LIB_LDFLAGS='-shared -Wl,-soname=$$out.${LIB_MAJOR}'
LIB_LDFLAGS_INSTALL_NAME=''
LIB_PREFIX='lib'
LIB_SUFFIX='.so'
- LDFLAGS_RPATH='-Wl,-rpath,${libdir}'
+ 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'
ADDED build-aux/m4/pkg.m4
Index: build-aux/m4/pkg.m4
==================================================================
--- /dev/null
+++ build-aux/m4/pkg.m4
@@ -0,0 +1,343 @@
+# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
+# serial 11 (pkg-config-0.29.1)
+
+dnl Copyright © 2004 Scott James Remnant .
+dnl Copyright © 2012-2015 Dan Nicholson
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+dnl General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+dnl 02111-1307, USA.
+dnl
+dnl As a special exception to the GNU General Public License, if you
+dnl distribute this file as part of a program that contains a
+dnl configuration script generated by Autoconf, you may include it under
+dnl the same distribution terms that you use for the rest of that
+dnl program.
+
+dnl PKG_PREREQ(MIN-VERSION)
+dnl -----------------------
+dnl Since: 0.29
+dnl
+dnl Verify that the version of the pkg-config macros are at least
+dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's
+dnl installed version of pkg-config, this checks the developer's version
+dnl of pkg.m4 when generating configure.
+dnl
+dnl To ensure that this macro is defined, also add:
+dnl m4_ifndef([PKG_PREREQ],
+dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])])
+dnl
+dnl See the "Since" comment for each macro you use to see what version
+dnl of the macros you require.
+m4_defun([PKG_PREREQ],
+[m4_define([PKG_MACROS_VERSION], [0.29.1])
+m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
+ [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
+])dnl PKG_PREREQ
+
+dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
+dnl ----------------------------------
+dnl Since: 0.16
+dnl
+dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
+dnl first found in the path. Checks that the version of pkg-config found
+dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
+dnl used since that's the first version where most current features of
+dnl pkg-config existed.
+AC_DEFUN([PKG_PROG_PKG_CONFIG],
+[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
+m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
+m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
+AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
+AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
+AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+ AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+fi
+if test -n "$PKG_CONFIG"; then
+ _pkg_min_version=m4_default([$1], [0.9.0])
+ AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
+ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ PKG_CONFIG=""
+ fi
+fi[]dnl
+])dnl PKG_PROG_PKG_CONFIG
+
+dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+dnl -------------------------------------------------------------------
+dnl Since: 0.18
+dnl
+dnl Check to see whether a particular set of modules exists. Similar to
+dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
+dnl
+dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+dnl only at the first occurence in configure.ac, so if the first place
+dnl it's called might be skipped (such as if it is within an "if", you
+dnl have to call PKG_CHECK_EXISTS manually
+AC_DEFUN([PKG_CHECK_EXISTS],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+if test -n "$PKG_CONFIG" && \
+ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
+ m4_default([$2], [:])
+m4_ifvaln([$3], [else
+ $3])dnl
+fi])
+
+dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+dnl ---------------------------------------------
+dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting
+dnl pkg_failed based on the result.
+m4_define([_PKG_CONFIG],
+[if test -n "$$1"; then
+ pkg_cv_[]$1="$$1"
+ elif test -n "$PKG_CONFIG"; then
+ PKG_CHECK_EXISTS([$3],
+ [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes ],
+ [pkg_failed=yes])
+ else
+ pkg_failed=untried
+fi[]dnl
+])dnl _PKG_CONFIG
+
+dnl _PKG_SHORT_ERRORS_SUPPORTED
+dnl ---------------------------
+dnl Internal check to see if pkg-config supports short errors.
+AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi[]dnl
+])dnl _PKG_SHORT_ERRORS_SUPPORTED
+
+
+dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+dnl [ACTION-IF-NOT-FOUND])
+dnl --------------------------------------------------------------
+dnl Since: 0.4.0
+dnl
+dnl Note that if there is a possibility the first call to
+dnl PKG_CHECK_MODULES might not happen, you should be sure to include an
+dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
+AC_DEFUN([PKG_CHECK_MODULES],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
+AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
+
+pkg_failed=no
+AC_MSG_CHECKING([for $1])
+
+_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
+_PKG_CONFIG([$1][_LIBS], [libs], [$2])
+
+m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
+and $1[]_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.])
+
+if test $pkg_failed = yes; then
+ AC_MSG_RESULT([no])
+ _PKG_SHORT_ERRORS_SUPPORTED
+ if test $_pkg_short_errors_supported = yes; then
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
+ else
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
+
+ m4_default([$4], [AC_MSG_ERROR(
+[Package requirements ($2) were not met:
+
+$$1_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+_PKG_TEXT])[]dnl
+ ])
+elif test $pkg_failed = untried; then
+ AC_MSG_RESULT([no])
+ m4_default([$4], [AC_MSG_FAILURE(
+[The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+_PKG_TEXT
+
+To get pkg-config, see .])[]dnl
+ ])
+else
+ $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
+ $1[]_LIBS=$pkg_cv_[]$1[]_LIBS
+ AC_MSG_RESULT([yes])
+ $3
+fi[]dnl
+])dnl PKG_CHECK_MODULES
+
+
+dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+dnl [ACTION-IF-NOT-FOUND])
+dnl ---------------------------------------------------------------------
+dnl Since: 0.29
+dnl
+dnl Checks for existence of MODULES and gathers its build flags with
+dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags
+dnl and VARIABLE-PREFIX_LIBS from --libs.
+dnl
+dnl Note that if there is a possibility the first call to
+dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to
+dnl include an explicit call to PKG_PROG_PKG_CONFIG in your
+dnl configure.ac.
+AC_DEFUN([PKG_CHECK_MODULES_STATIC],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+_save_PKG_CONFIG=$PKG_CONFIG
+PKG_CONFIG="$PKG_CONFIG --static"
+PKG_CHECK_MODULES($@)
+PKG_CONFIG=$_save_PKG_CONFIG[]dnl
+])dnl PKG_CHECK_MODULES_STATIC
+
+
+dnl PKG_INSTALLDIR([DIRECTORY])
+dnl -------------------------
+dnl Since: 0.27
+dnl
+dnl Substitutes the variable pkgconfigdir as the location where a module
+dnl should install pkg-config .pc files. By default the directory is
+dnl $libdir/pkgconfig, but the default can be changed by passing
+dnl DIRECTORY. The user can override through the --with-pkgconfigdir
+dnl parameter.
+AC_DEFUN([PKG_INSTALLDIR],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+ [pkg-config installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([pkgconfigdir],
+ [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
+ [with_pkgconfigdir=]pkg_default)
+AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+])dnl PKG_INSTALLDIR
+
+
+dnl PKG_NOARCH_INSTALLDIR([DIRECTORY])
+dnl --------------------------------
+dnl Since: 0.27
+dnl
+dnl Substitutes the variable noarch_pkgconfigdir as the location where a
+dnl module should install arch-independent pkg-config .pc files. By
+dnl default the directory is $datadir/pkgconfig, but the default can be
+dnl changed by passing DIRECTORY. The user can override through the
+dnl --with-noarch-pkgconfigdir parameter.
+AC_DEFUN([PKG_NOARCH_INSTALLDIR],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+ [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([noarch-pkgconfigdir],
+ [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
+ [with_noarch_pkgconfigdir=]pkg_default)
+AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+])dnl PKG_NOARCH_INSTALLDIR
+
+
+dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
+dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+dnl -------------------------------------------
+dnl Since: 0.28
+dnl
+dnl Retrieves the value of the pkg-config variable for the given module.
+AC_DEFUN([PKG_CHECK_VAR],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
+
+_PKG_CONFIG([$1], [variable="][$3]["], [$2])
+AS_VAR_COPY([$1], [pkg_cv_][$1])
+
+AS_VAR_IF([$1], [""], [$5], [$4])dnl
+])dnl PKG_CHECK_VAR
+
+dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES,
+dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND],
+dnl [DESCRIPTION], [DEFAULT])
+dnl ------------------------------------------
+dnl
+dnl Prepare a "--with-" configure option using the lowercase
+dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and
+dnl PKG_CHECK_MODULES in a single macro.
+AC_DEFUN([PKG_WITH_MODULES],
+[
+m4_pushdef([with_arg], m4_tolower([$1]))
+
+m4_pushdef([description],
+ [m4_default([$5], [build with ]with_arg[ support])])
+
+m4_pushdef([def_arg], [m4_default([$6], [auto])])
+m4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes])
+m4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no])
+
+m4_case(def_arg,
+ [yes],[m4_pushdef([with_without], [--without-]with_arg)],
+ [m4_pushdef([with_without],[--with-]with_arg)])
+
+AC_ARG_WITH(with_arg,
+ AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),,
+ [AS_TR_SH([with_]with_arg)=def_arg])
+
+AS_CASE([$AS_TR_SH([with_]with_arg)],
+ [yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)],
+ [auto],[PKG_CHECK_MODULES([$1],[$2],
+ [m4_n([def_action_if_found]) $3],
+ [m4_n([def_action_if_not_found]) $4])])
+
+m4_popdef([with_arg])
+m4_popdef([description])
+m4_popdef([def_arg])
+
+])dnl PKG_WITH_MODULES
+
+dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES,
+dnl [DESCRIPTION], [DEFAULT])
+dnl -----------------------------------------------
+dnl
+dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES
+dnl check._[VARIABLE-PREFIX] is exported as make variable.
+AC_DEFUN([PKG_HAVE_WITH_MODULES],
+[
+PKG_WITH_MODULES([$1],[$2],,,[$3],[$4])
+
+AM_CONDITIONAL([HAVE_][$1],
+ [test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"])
+])dnl PKG_HAVE_WITH_MODULES
+
+dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES,
+dnl [DESCRIPTION], [DEFAULT])
+dnl ------------------------------------------------------
+dnl
+dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after
+dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make
+dnl and preprocessor variable.
+AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES],
+[
+PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4])
+
+AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"],
+ [AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])])
+])dnl PKG_HAVE_DEFINE_WITH_MODULES
Index: buildsys.mk.in
==================================================================
--- buildsys.mk.in
+++ buildsys.mk.in
@@ -210,11 +210,11 @@
done
if test x"${includesubdir}" = x"${COPY_HEADERS_IF_SUBDIR}"; then \
for i in "" ${INCLUDES}; do \
test x"$$i" = x"" && continue; \
- ${MKDIR_P} ${COPY_HEADERS_DESTINATION} || 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}
@@ -731,11 +731,11 @@
if test x"${INSTALL_INCLUDES}" = x"yes"; then \
for i in "" ${INCLUDES}; do \
test x"$$i" = x"" && continue; \
${INSTALL_STATUS}; \
- if ${MKDIR_P} ${DESTDIR}${includedir}/${includesubdir} && ${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 \
Index: configure.ac
==================================================================
--- configure.ac
+++ configure.ac
@@ -1,6 +1,6 @@
-AC_INIT(ObjFW, 1.1-dev, js@nil.im)
+AC_INIT(ObjFW, 1.1dev, js@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])
@@ -44,14 +44,16 @@
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, objfwrt68k.library)
+ 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"
@@ -63,10 +65,11 @@
powerpc-*-amigaos*)
CPPFLAGS="$CPPFLAGS -D__USE_INLINE__"
enable_files="yes" # Required for reading ENV:
enable_shared="no"
+ with_tls="no"
AC_SUBST(LIBBASES_M, libbases.m)
;;
*-morphos*)
AS_IF([test x"$OBJCFLAGS" = x""], [OBJCFLAGS="-O2 -g"])
@@ -78,11 +81,12 @@
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.library)
+ 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")
])
@@ -133,10 +137,15 @@
dnl also used for .S files.
OBJCFLAGS="$OBJCFLAGS -include inttypes.h"
dnl We need -latomic for GCC's atomics to work.
LIBS="$LIBS -latomic"
;;
+*-*-mint*)
+ enable_shared="no"
+ enable_threads="no" # TODO
+ with_tls="no"
+ ;;
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}
@@ -171,18 +180,43 @@
flags="-mrvl -mcpu=750 -meabi -mhard-float"
OBJCFLAGS="$OBJCFLAGS $flags"
OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS $flags"
CPPFLAGS="$CPPFLAGS -DGEKKO -I$DEVKITPRO/libogc/include"
+ OBJFW_CPPFLAGS="$OBJFW_CPPFLAGS -DGEKKO -I\$DEVKITPRO/libogc/include"
LDFLAGS="$LDFLAGS -mrvl -mcpu=750 -meabi -mhard-float"
LIBS="$LIBS -L$DEVKITPRO/libogc/lib/wii -lfat -logc"
TESTS_LIBS="$TESTS_LIBS -lwiiuse -lbte"
enable_shared="no"
enable_threads="no" # TODO
+ with_tls="no"
AC_DEFINE(OF_WII, 1, [Whether we are compiling for Wii])
- OBJFW_CPPFLAGS="$OBJFW_CPPFLAGS -DGEKKO -I\$DEVKITPRO/libogc/include"
+ AC_SUBST(MAP_LDFLAGS, ['-Wl,-Map,$@.map'])
+])
+
+AC_ARG_WITH(wii-u,
+ AS_HELP_STRING([--with-wii-u], [build for Wii U]))
+AS_IF([test x"$with_wii_u" = x"yes"], [
+ AS_IF([test x"$DEVKITPRO" = x""], [
+ AC_MSG_ERROR([DEVKITPRO is not set! Please set DEVKITPRO.])
+ ])
+
+ flags="-mcpu=750 -meabi -mhard-float"
+ OBJCFLAGS="$OBJCFLAGS $flags"
+ OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS $flags"
+ CPPFLAGS="-isystem $DEVKITPRO/wut/include -D__WIIU__ -D__WUT__"
+ OBJFW_CPPFLAGS="$OBJFW_CPPFLAGS -isystem \$DEVKITPRO/wut/include"
+ OBJFW_CPPFLAGS="$OBJFW_CPPFLAGS -D__WIIU__ -D__WUT__"
+ LDFLAGS="-specs=$DEVKITPRO/wut/share/wut.specs"
+ LIBS="-L$DEVKITPRO/wut/lib -L$DEVKITPRO/wut/lib/stubs -lwut"
+ enable_files="no" # TODO
+ enable_shared="no" # TODO
+ enable_threads="no" # TODO
+ enable_sockets="no" # TODO
+
+ AC_DEFINE(OF_WII_U, 1, [Whether we are compiling for Wii U])
AC_SUBST(MAP_LDFLAGS, ['-Wl,-Map,$@.map'])
])
AC_ARG_WITH(nds,
AS_HELP_STRING([--with-nds], [build for Nintendo DS]))
@@ -193,20 +227,20 @@
flags="-march=armv5te -mtune=arm946e-s -mthumb -mthumb-interwork"
OBJCFLAGS="$OBJCFLAGS $flags"
OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS $flags"
CPPFLAGS="$CPPFLAGS -DARM9 -I$DEVKITPRO/libnds/include"
+ OBJFW_CPPFLAGS="$OBJFW_CPPFLAGS -DARM9 -I\$DEVKITPRO/libnds/include"
ASFLAGS="$ASFLAGS -march=armv5te"
LDFLAGS="$LDFLAGS -specs=ds_arm9.specs"
LIBS="$LIBS -L$DEVKITPRO/libnds/lib -lfilesystem -lfat -lnds9"
enable_shared="no"
enable_threads="no" # TODO
enable_sockets="no" # TODO
check_pedantic="no"
AC_DEFINE(OF_NINTENDO_DS, 1, [Whether we are compiling for Nintendo DS])
- OBJFW_CPPFLAGS="$OBJFW_CPPFLAGS -DARM9 -I\$DEVKITPRO/libnds/include"
AC_SUBST(MAP_LDFLAGS, ['-Wl,-Map,$@.map'])
])
AC_ARG_WITH(3ds,
AS_HELP_STRING([--with-3ds], [build for Nintendo 3DS]))
@@ -218,23 +252,48 @@
flags="-march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft"
flags="$flags -mword-relocations"
OBJCFLAGS="$OBJCFLAGS $flags"
OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS $flags"
CPPFLAGS="$CPPFLAGS -DARM11 -I$DEVKITPRO/libctru/include"
+ OBJFW_CPPFLAGS="$OBJFW_CPPFLAGS -DARM11 -I\$DEVKITPRO/libctru/include"
ASFLAGS="$ASFLAGS -march=armv6k"
LDFLAGS="$LDFLAGS -specs=3dsx.specs -march=armv6k -mtune=mpcore"
LDFLAGS="$LDFLAGS -mfloat-abi=hard -mtp=soft -mword-relocations"
LIBS="$LIBS -L$DEVKITPRO/libctru/lib -lctru"
enable_shared="no"
enable_threads="no" # TODO
+ with_tls="no"
check_pedantic="no"
AC_DEFINE(OF_NINTENDO_3DS, 1,
[Whether we are compiling for Nintendo 3DS])
- OBJFW_CPPFLAGS="$OBJFW_CPPFLAGS -DARM11 -I\$DEVKITPRO/libctru/include"
AC_SUBST(MAP_LDFLAGS, ['-Wl,-Map,$@.map'])
])
+
+AC_ARG_WITH(nintendo-switch,
+ AS_HELP_STRING([--with-nintendo-switch], [build for Nintendo Switch]))
+AS_IF([test x"$with_nintendo_switch" = x"yes"], [
+ AS_IF([test x"$DEVKITPRO" = x""], [
+ AC_MSG_ERROR([DEVKITPRO is not set! Please set DEVKITPRO.])
+ ])
+
+ flags="-march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE"
+ OBJCFLAGS="$OBJCFLAGS $flags"
+ OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS $flags"
+ CPPFLAGS="$CPPFLAGS -D__SWITCH__ -I$DEVKITPRO/libnx/include"
+ OBJFW_CPPFLAGS="$OBJFW_CPPFLAGS -D__SWITCH__ -I$DEVKITPRO/libnx/include"
+ ASFLAGS="$ASFLAGS $flags"
+ LDFLAGS="$LDFLAGS -specs=$DEVKITPRO/libnx/switch.specs $flags"
+ LIBS="$LIBS -L$DEVKITPRO/libnx/lib -lnx"
+ enable_shared="no"
+ enable_threads="yes"
+ enable_sockets="no" # TODO
+ check_pedantic="no"
+
+ AC_DEFINE(OF_NINTENDO_SWITCH, 1,
+ [Whether we are compiling for Nintendo Switch])
+])
CPP="$OBJCPP"
CPPFLAGS="$CPPFLAGS $OBJCPPFLAGS -DOF_COMPILING_OBJFW"
flags="-fexceptions -fobjc-exceptions -funwind-tables"
flags="$flags -fconstant-string-class=OFConstantString"
@@ -258,19 +317,10 @@
;;
i?86-*-darwin* | x86_64-*-darwin*)
dnl Don't use -no-integrated-as on Darwin. It breaks building
dnl for the iOS simulator.
;;
- i?86-*-* | x86_64-*-*)
- dnl Many older Clang versions don't support jmp short.
- ASFLAGS="$ASFLAGS -no-integrated-as"
- ;;
- *-*-mingw*)
- dnl Clang's assembler on Windows is not complete yet and cannot
- dnl compile all .S files.
- ASFLAGS="$ASFLAGS -no-integrated-as"
- ;;
sparc64-*-*openbsd*)
dnl Clang generates assembly output on SPARC64 that OpenBSD's
dnl assembler does not accept.
flag="-integrated-as"
OBJCFLAGS="$OBJCFLAGS $flag"
@@ -425,11 +475,11 @@
AC_MSG_CHECKING(whether we need -D_GNU_SOURCE)
AC_EGREP_CPP(egrep_cpp_yes, [
#include
#if defined(__GLIBC__) || defined(__MINGW32__) || \
- defined(__NEWLIB__) || defined(__MORPHOS__)
+ defined(__NEWLIB__) || defined(__MORPHOS__) || defined(__MINT__)
egrep_cpp_yes
#endif
], [
AC_MSG_RESULT(yes)
CPPFLAGS="-D_GNU_SOURCE $CPPFLAGS"
@@ -640,10 +690,13 @@
OBJCFLAGS="$old_OBJCFLAGS"
;;
esac
case "$host_os" in
+mint*)
+ dnl _Unwind_Backtrace crashes on MiNT
+ ;;
hpux*)
dnl _Unwind_Backtrace() returns complete garbage on HP-UX.
;;
*)
AC_CHECK_FUNCS(_Unwind_Backtrace)
@@ -829,10 +882,14 @@
AC_CHECK_FUNCS(strtof truncf)
AC_CHECK_FUNC(asprintf, [
case "$host" in
+ *-*-mint*)
+ dnl asprintf is not in headers
+ have_asprintf="no"
+ ;;
*-*-mingw*)
dnl asprintf from MinGW is broken on older Windows versions
have_asprintf="no"
;;
*-psp-*)
@@ -980,10 +1037,11 @@
;;
esac
AC_DEFINE(OF_HAVE_THREADS, 1, [Whether we have threads])
AC_SUBST(USE_SRCS_THREADS, '${SRCS_THREADS}')
+ AC_SUBST(OBJC_SYNC, objc_sync)
AC_ARG_ENABLE(compiler-tls,
AS_HELP_STRING([--disable-compiler-tls],
[disable compiler thread local storage]))
@@ -1336,10 +1394,13 @@
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])
+ AC_CHECK_HEADER(sys/un.h, [
+ AC_DEFINE(OF_HAVE_SYS_UN_H, 1, [Whether we have sys/un.h])
+ ])
AC_CHECK_HEADER(netipx/ipx.h, [
AC_DEFINE(OF_HAVE_NETIPX_IPX_H, 1,
[Whether we have netipx/ipx.h])
])
@@ -1369,10 +1430,13 @@
#endif
], [
AC_DEFINE(OF_HAVE_IPV6, 1, [Whether we have IPv6])
])
], [
+ dnl Work around a bug in autoconf 2.61 that creates a broken
+ dnl configure if this branch is empty.
+ :
], [
#ifdef _WIN32
typedef int BOOL;
#endif
@@ -1389,10 +1453,44 @@
# endif
# include
# include
#endif
])
+
+ AC_CHECK_HEADERS(afunix.h, [
+ AC_DEFINE(OF_HAVE_AFUNIX_H, 1, [Whether we have afunix.h])
+ ], [], [
+ #ifdef _WIN32
+ # include
+ #endif
+ ])
+ 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}')
+ ], [], [
+ #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 __morphos__
+ # error MorphOS has the struct but does not support it
+ #endif
+
+ #ifdef __MINT__
+ # error Gives invalid argument at runtime
+ #endif
+ ])
AC_CHECK_MEMBER(struct sockaddr_ipx.sipx_network, [], [
AC_CHECK_MEMBER(struct sockaddr_ipx.sa_netnum, [], [], [
#ifdef _WIN32
typedef int BOOL;
@@ -1506,18 +1604,124 @@
AC_SUBST(OF_SELECT_KERNEL_EVENT_OBSERVER_M,
"OFSelectKernelEventObserver.m")
])
;;
esac
+
+ AC_ARG_WITH(tls,
+ AS_HELP_STRING([--with-tls], [
+ enable TLS support using the specified library
+ (yes, openssl, gnutls, securetransport 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"], [
+ 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,
+ "OFSecureTransportTLSStream.m")
+
+ AC_CHECK_FUNCS(SSLCreateContext)
+ ], [])
+
+ LIBS="$old_LIBS"
+ ])
+ ])
+
+ AS_IF([test x"$with_tls" = x"openssl" \
+ -o \( x"$with_tls" = x"yes" -a x"$tls_support" = x"no" \)], [
+ case "$host_os" in
+ morphos*)
+ ssl="ssl_shared"
+ crypto="crypto_shared"
+ ;;
+ *)
+ ssl="ssl"
+ crypto="crypto"
+ ;;
+ 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")
+ ])
+ ], [], [-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], [
+ 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"$tls_support" != x"no"], [
+ AC_SUBST(TLS, "tls")
+ AC_SUBST(TLS_CPPFLAGS)
+ AC_SUBST(TLS_LIBS)
+ AC_DEFINE(HAVE_TLS_SUPPORT, 1,
+ [Whether we have an implementation for TLS])
+ AC_CONFIG_FILES(src/tls/Info.plist)
+
+ 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}")
+ ])
+ AS_IF([test x"$enable_static" = x"yes" \
+ -o x"$enable_shared" = x"no"], [
+ AC_SUBST(OBJFWTLS_STATIC_LIB, "libobjfwtls.a")
+ ])
+ AS_IF([test x"$build_framework" = x"yes"], [
+ AC_SUBST(OBJFWTLS_FRAMEWORK, "ObjFWTLS.framework")
+ ])
+ ])
+
+ AS_IF([test x"$with_tls" != x"no" -a x"$tls_support" = x"no"], [
+ AC_MSG_ERROR(m4_normalize([
+ No TLS implementation was found. Please install OpenSSL,
+ GnuTLS or use --without-tls.
+ ]))
+ ])
AS_IF([test x"$enable_threads" != x"no"], [
AC_SUBST(OF_HTTP_CLIENT_TESTS_M, "OFHTTPClientTests.m")
])
AC_SUBST(OFDNS, "ofdns")
AS_IF([test x"$enable_files" != x"no"], [
AC_SUBST(OFHTTP, "ofhttp")
+ AC_SUBST(OFHTTP_LIBS)
])
])
AC_DEFUN([CHECK_BUILTIN_BSWAP], [
AC_MSG_CHECKING(for __builtin_bswap$1)
@@ -1553,10 +1757,13 @@
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"
])
;;
@@ -1830,10 +2037,15 @@
__attribute__((__objc_root_class__))
# endif
#endif
@interface Test
@end
+
+ /**
+ * @struct Foo conftest.m conftest.m
+ */
+ typedef struct {} Foo;
])
], [
AC_MSG_RESULT(yes)
], [
AC_MSG_RESULT(no)
@@ -1913,11 +2125,10 @@
AC_CHECK_PROG(WINE, wine64, wine64)
;;
esac
AS_IF([test x"$WINE" != x""], [
- AC_SUBST(RUN_TESTS, "run")
AC_SUBST(WRAPPER, "$WINE")
])
AS_IF([test x"$with_wii" = x"yes"], [
dnl Keep this lowercase, as WIILOAD is a variable used by
@@ -1927,12 +2138,10 @@
AS_IF([test x"$wiiload" != x""], [
AC_SUBST(WRAPPER, "$wiiload")
])
])
-], [
- AC_SUBST(RUN_TESTS, "run")
])
AC_ARG_WITH(fish_completions,
AS_HELP_STRING([--with-fish-completions],
[install completions for the fish shell]))
Index: extra.mk.in
==================================================================
--- extra.mk.in
+++ extra.mk.in
@@ -1,23 +1,27 @@
OBJFW_SHARED_LIB = @OBJFW_SHARED_LIB@
OBJFW_STATIC_LIB = @OBJFW_STATIC_LIB@
OBJFW_FRAMEWORK = @OBJFW_FRAMEWORK@
-OBJFW_LIB_MAJOR = 9
-OBJFW_LIB_MINOR = 1
+OBJFW_LIB_MAJOR = 0
+OBJFW_LIB_MINOR = 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 = 1
+OBJFWRT_LIB_MAJOR = 0
OBJFWRT_LIB_MINOR = 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@
+
+OBJFWTLS_SHARED_LIB = @OBJFWTLS_SHARED_LIB@
+OBJFWTLS_STATIC_LIB = @OBJFWTLS_STATIC_LIB@
+OBJFWTLS_FRAMEWORK = @OBJFWTLS_FRAMEWORK@
BIN_PREFIX = @BIN_PREFIX@
BRIDGE = @BRIDGE@
CVINCLUDE_INLINE_H = @CVINCLUDE_INLINE_H@
ENCODINGS_A = @ENCODINGS_A@
@@ -38,19 +42,24 @@
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@
OFARC = @OFARC@
OFDNS = @OFDNS@
OFHASH = @OFHASH@
OFHTTP = @OFHTTP@
+OFHTTP_LIBS = @OFHTTP_LIBS@
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_OPENSSL_TLS_STREAM_M = @OF_OPENSSL_TLS_STREAM_M@
OF_POLL_KERNEL_EVENT_OBSERVER_M = @OF_POLL_KERNEL_EVENT_OBSERVER_M@
+OF_SECURE_TRANSPORT_TLS_STREAM_M = @OF_SECURE_TRANSPORT_TLS_STREAM_M@
OF_SELECT_KERNEL_EVENT_OBSERVER_M = @OF_SELECT_KERNEL_EVENT_OBSERVER_M@
OF_SUBPROCESS_M = @OF_SUBPROCESS_M@
REEXPORT_RUNTIME = @REEXPORT_RUNTIME@
REEXPORT_RUNTIME_FRAMEWORK = @REEXPORT_RUNTIME_FRAMEWORK@
RUNTIME = @RUNTIME@
@@ -57,22 +66,25 @@
RUNTIME_ARC_TESTS_M = @RUNTIME_ARC_TESTS_M@
RUNTIME_AUTORELEASE_M = @RUNTIME_AUTORELEASE_M@
RUNTIME_FRAMEWORK_LIBS = @RUNTIME_FRAMEWORK_LIBS@
RUNTIME_INSTANCE_M = @RUNTIME_INSTANCE_M@
RUNTIME_LIBS = @RUNTIME_LIBS@
-RUN_TESTS = @RUN_TESTS@
SFDC_INLINE_H = @SFDC_INLINE_H@
SFDC_TARGET = @SFDC_TARGET@
SFD_FILE = @SFD_FILE@
TESTPLUGIN = @TESTPLUGIN@
TESTPLUGIN_LIBS = @TESTPLUGIN_LIBS@
TESTS_LIBS = @TESTS_LIBS@
TESTS_STATIC_LIB = @TESTS_STATIC_LIB@
+TLS = @TLS@
+TLS_CPPFLAGS = @TLS_CPPFLAGS@
+TLS_LIBS = @TLS_LIBS@
UNICODE_M = @UNICODE_M@
USE_INCLUDES_ATOMIC = @USE_INCLUDES_ATOMIC@
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_THREADS = @USE_SRCS_THREADS@
+USE_SRCS_UNIX_SOCKETS = @USE_SRCS_UNIX_SOCKETS@
USE_SRCS_WINDOWS = @USE_SRCS_WINDOWS@
WRAPPER = @WRAPPER@
Index: generators/library/FuncArrayGenerator.h
==================================================================
--- generators/library/FuncArrayGenerator.h
+++ generators/library/FuncArrayGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: generators/library/FuncArrayGenerator.m
==================================================================
--- generators/library/FuncArrayGenerator.m
+++ generators/library/FuncArrayGenerator.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -65,14 +65,14 @@
- (void)generate
{
[_include writeString: COPYRIGHT];
[_include writeString:
- @"/* This file is automatically generated from library.xml */\n"
- @"\n"];
+ @"/* 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
Index: generators/library/GlueGenerator.h
==================================================================
--- generators/library/GlueGenerator.h
+++ generators/library/GlueGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: generators/library/GlueGenerator.m
==================================================================
--- generators/library/GlueGenerator.m
+++ generators/library/GlueGenerator.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -70,16 +70,16 @@
{
[_header writeString: COPYRIGHT];
[_impl writeString: COPYRIGHT];
[_header writeString:
- @"/* This file is automatically generated from library.xml */\n"
- @"\n"];
+ @"/* This file is automatically generated from amiga-library.xml */"
+ @"\n\n"];
[_impl writeString:
- @"/* This file is automatically generated from library.xml */\n"
- @"\n"
+ @"/* This file is automatically generated from amiga-library.xml */"
+ @"\n\n"
@"#include \"config.h\"\n"
@"\n"
@"#import \"amiga-glue.h\"\n"
@"\n"];
Index: generators/library/LibraryGenerator.m
==================================================================
--- generators/library/LibraryGenerator.m
+++ generators/library/LibraryGenerator.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -34,30 +34,34 @@
- (void)applicationDidFinishLaunching
{
OFURL *sourcesURL = [[OFFileManager defaultManager].currentDirectoryURL
URLByAppendingPathComponent: @"../../src"];
OFURL *runtimeLibraryURL = [sourcesURL
- URLByAppendingPathComponent: @"runtime/library.xml"];
+ URLByAppendingPathComponent: @"runtime/amiga-library.xml"];
OFURL *runtimeLinkLibURL = [sourcesURL
URLByAppendingPathComponent: @"runtime/linklib/linklib.m"];
OFURL *runtimeGlueHeaderURL = [sourcesURL
URLByAppendingPathComponent: @"runtime/amiga-glue.h"];
OFURL *runtimeGlueURL = [sourcesURL
URLByAppendingPathComponent: @"runtime/amiga-glue.m"];
OFURL *runtimeFuncArrayURL = [sourcesURL
URLByAppendingPathComponent: @"runtime/amiga-funcarray.inc"];
OFXMLElement *runtimeLibrary = [OFXMLElement elementWithStream:
- [OFFile fileWithURL: runtimeLibraryURL
- mode: @"r"]];
- OFFile *runtimeLinkLib = [OFFile fileWithURL: runtimeLinkLibURL
- mode: @"w"];
- OFFile *runtimeGlueHeader = [OFFile fileWithURL: runtimeGlueHeaderURL
- mode: @"w"];
- OFFile *runtimeGlue = [OFFile fileWithURL: runtimeGlueURL
- mode: @"w"];
- OFFile *runtimeFuncArray = [OFFile fileWithURL: runtimeFuncArrayURL
- mode: @"w"];
+ [OFFile fileWithPath: runtimeLibraryURL.fileSystemRepresentation
+ mode: @"r"]];
+ OFFile *runtimeLinkLib =
+ [OFFile fileWithPath: runtimeLinkLibURL.fileSystemRepresentation
+ mode: @"w"];
+ OFFile *runtimeGlueHeader =
+ [OFFile fileWithPath: runtimeGlueHeaderURL.fileSystemRepresentation
+ mode: @"w"];
+ OFFile *runtimeGlue =
+ [OFFile fileWithPath: runtimeGlueURL.fileSystemRepresentation
+ mode: @"w"];
+ OFFile *runtimeFuncArray =
+ [OFFile fileWithPath: runtimeFuncArrayURL.fileSystemRepresentation
+ mode: @"w"];
LinkLibGenerator *runtimeLinkLibGenerator = [[[LinkLibGenerator alloc]
initWithLibrary: runtimeLibrary
implementation: runtimeLinkLib] autorelease];
GlueGenerator *runtimeGlueGenerator = [[[GlueGenerator alloc]
initWithLibrary: runtimeLibrary
Index: generators/library/LinkLibGenerator.h
==================================================================
--- generators/library/LinkLibGenerator.h
+++ generators/library/LinkLibGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: generators/library/LinkLibGenerator.m
==================================================================
--- generators/library/LinkLibGenerator.m
+++ generators/library/LinkLibGenerator.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -69,12 +69,12 @@
OFArray OF_GENERIC(OFXMLElement *) *functions;
size_t funcIndex = 0;
[_impl writeString: COPYRIGHT];
[_impl writeString:
- @"/* This file is automatically generated from library.xml */\n"
- @"\n"
+ @"/* 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",
Index: generators/library/Makefile
==================================================================
--- generators/library/Makefile
+++ generators/library/Makefile
@@ -4,29 +4,33 @@
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.dll libobjfw.${OBJFW_LIB_MAJOR}.dylib
+ 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.dll libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib
+ 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.dll; then \
- ${LN_S} ../../src/objfw.dll objfw.dll; \
+ 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
@@ -36,12 +40,13 @@
${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.dll; then \
- ${LN_S} ../../src/runtime/objfwrt.dll objfwrt.dll; \
+ 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
@@ -54,17 +59,17 @@
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 objfw.so.${OBJFW_LIB_MAJOR_MINOR} objfw.dll; \
+ 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 objfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR} objfwrt.dll; \
+ rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \
+ rm -f objfwrt${OBJFWRT_LIB_MAJOR}.dll; \
rm -f libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib; \
exit $$EXIT
-include ../../buildsys.mk
-
CPPFLAGS += -I../../src -I../../src/exceptions -I../../src/runtime -I../..
LIBS := -L../../src -lobjfw -L../../src/runtime ${RUNTIME_LIBS} ${LIBS}
LD = ${OBJC}
Index: generators/library/copyright.h
==================================================================
--- generators/library/copyright.h
+++ generators/library/copyright.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -15,11 +15,11 @@
#import "OFString.h"
#define COPYRIGHT \
@"/*\n" \
- @" * Copyright (c) 2008-2021 Jonathan Schleifer \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" \
Index: generators/unicode/Makefile
==================================================================
--- generators/unicode/Makefile
+++ generators/unicode/Makefile
@@ -1,29 +1,33 @@
include ../../extra.mk
PROG_NOINST = gen_tables${PROG_SUFFIX}
SRCS = TableGenerator.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.dll libobjfw.${OBJFW_LIB_MAJOR}.dylib
+ 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.dll libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib
+ 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.dll; then \
- ${LN_S} ../../src/objfw.dll objfw.dll; \
+ 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
@@ -33,12 +37,13 @@
${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.dll; then \
- ${LN_S} ../../src/runtime/objfwrt.dll objfwrt.dll; \
+ 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
@@ -51,17 +56,17 @@
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 objfw.so.${OBJFW_LIB_MAJOR_MINOR} objfw.dll; \
+ 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 objfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR} objfwrt.dll; \
+ rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \
+ rm -f objfwrt${OBJFWRT_LIB_MAJOR}.dll; \
rm -f libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib; \
exit $$EXIT
-include ../../buildsys.mk
-
CPPFLAGS += -I../../src -I../../src/exceptions -I../../src/runtime -I../..
LIBS := -L../../src -lobjfw -L../../src/runtime ${RUNTIME_LIBS} ${LIBS}
LD = ${OBJC}
Index: generators/unicode/TableGenerator.h
==================================================================
--- generators/unicode/TableGenerator.h
+++ generators/unicode/TableGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: generators/unicode/TableGenerator.m
==================================================================
--- generators/unicode/TableGenerator.m
+++ generators/unicode/TableGenerator.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -53,12 +53,12 @@
_titlecaseTableSize = SIZE_MAX;
_caseFoldingTableSize = SIZE_MAX;
_decompositionTableSize = SIZE_MAX;
_decompositionCompatTableSize = SIZE_MAX;
} @catch (id e) {
- @throw e;
[self release];
+ @throw e;
}
return self;
}
Index: generators/unicode/copyright.h
==================================================================
--- generators/unicode/copyright.h
+++ generators/unicode/copyright.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -15,11 +15,11 @@
#import "OFString.h"
#define COPYRIGHT \
@"/*\n" \
- @" * Copyright (c) 2008-2021 Jonathan Schleifer \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" \
ADDED objfw.spec
Index: objfw.spec
==================================================================
--- /dev/null
+++ objfw.spec
@@ -0,0 +1,248 @@
+%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(openssl)
+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: openssl%{_isa} >= 1.1.1
+
+%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 (via ObjOpenSSL) 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
@@ -1,47 +1,47 @@
include ../extra.mk
SUBDIRS = ${RUNTIME} exceptions encodings forwarding invocation
-SUBDIRS_AFTER = ${BRIDGE}
+SUBDIRS_AFTER = ${BRIDGE} ${TLS}
DISTCLEAN = Info.plist objfw-defs.h
SHARED_LIB = ${OBJFW_SHARED_LIB}
STATIC_LIB = ${OBJFW_STATIC_LIB}
FRAMEWORK = ${OBJFW_FRAMEWORK}
LIB_MAJOR = ${OBJFW_LIB_MAJOR}
LIB_MINOR = ${OBJFW_LIB_MINOR}
-SRCS = OFASPrintF.m \
- OFApplication.m \
+SRCS = OFApplication.m \
OFArray.m \
- OFBase64.m \
OFBlock.m \
- OFCRC16.m \
- OFCRC32.m \
OFCharacterSet.m \
OFColor.m \
OFConstantString.m \
OFCountedSet.m \
OFData.m \
OFData+CryptographicHashing.m \
OFData+MessagePackParsing.m \
OFDate.m \
OFDictionary.m \
+ OFEmbeddedFileURLHandler.m \
OFEnumerator.m \
OFFileManager.m \
OFGZIPStream.m \
OFHMAC.m \
- OFHuffmanTree.m \
+ OFINICategory.m \
+ OFINIFile.m \
+ OFINIFileSettings.m \
OFInflate64Stream.m \
OFInflateStream.m \
OFInvocation.m \
OFLHAArchive.m \
OFLHAArchiveEntry.m \
OFList.m \
OFLocale.m \
OFMD5Hash.m \
OFMapTable.m \
+ OFMemoryStream.m \
OFMessagePackExtension.m \
OFMethodSignature.m \
OFMutableArray.m \
OFMutableData.m \
OFMutableDictionary.m \
@@ -51,10 +51,12 @@
OFMutableString.m \
OFMutableTarArchiveEntry.m \
OFMutableTriple.m \
OFMutableURL.m \
OFMutableZIPArchiveEntry.m \
+ OFNotification.m \
+ OFNotificationCenter.m \
OFNull.m \
OFNumber.m \
OFObject.m \
OFObject+KeyValueCoding.m \
OFObject+Serialization.m \
@@ -76,29 +78,30 @@
OFSeekableStream.m \
OFSerialization.m \
OFSet.m \
OFSortedList.m \
OFStdIOStream.m \
- OFStrPTime.m \
OFStream.m \
OFString.m \
OFString+CryptographicHashing.m \
OFString+JSONParsing.m \
OFString+PropertyListParsing.m \
OFString+Serialization.m \
OFString+URLEncoding.m \
OFString+XMLEscaping.m \
OFString+XMLUnescaping.m \
- ${OF_SUBUPROCESS_M} \
+ ${OF_SUBPROCESS_M} \
+ OFSettings.m \
OFSystemInfo.m \
OFTarArchive.m \
OFTarArchiveEntry.m \
OFThread.m \
OFTimer.m \
OFTriple.m \
OFURL.m \
OFURLHandler.m \
+ OFUUID.m \
OFValue.m \
OFXMLAttribute.m \
OFXMLCDATA.m \
OFXMLCharacters.m \
OFXMLComment.m \
@@ -114,17 +117,11 @@
${USE_SRCS_PLUGINS} \
${USE_SRCS_SOCKETS} \
${USE_SRCS_THREADS} \
${USE_SRCS_WINDOWS}
SRCS_FILES = OFFile.m \
- OFINICategory.m \
- OFINIFile.m \
- OFSettings.m \
OFString+PathAdditions.m
-SRCS_IPX = OFIPXSocket.m \
- OFSPXSocket.m \
- OFSPXStreamSocket.m
SRCS_PLUGINS = OFPlugin.m
SRCS_SOCKETS = OFDNSQuery.m \
OFDNSResolver.m \
OFDNSResourceRecord.m \
OFDNSResponse.m \
@@ -137,50 +134,59 @@
OFHTTPServer.m \
OFSequencedPacketSocket.m \
OFSocket.m \
OFStreamSocket.m \
OFTCPSocket.m \
+ OFTLSStream.m \
OFUDPSocket.m \
- ${USE_SRCS_IPX}
+ ${USE_SRCS_IPX} \
+ ${USE_SRCS_UNIX_SOCKETS}
+SRCS_IPX = OFIPXSocket.m \
+ OFSPXSocket.m \
+ OFSPXStreamSocket.m
+SRCS_UNIX_SOCKETS = OFUNIXDatagramSocket.m \
+ OFUNIXStreamSocket.m
SRCS_THREADS = OFCondition.m \
OFMutex.m \
OFPlainCondition.m \
OFPlainMutex.m \
OFPlainThread.m \
OFRecursiveMutex.m \
- OFTLSKey.m \
- OFThreadPool.m
+ OFTLSKey.m
SRCS_WINDOWS = OFWin32ConsoleStdIOStream.m \
OFWindowsRegistryKey.m
INCLUDES_ATOMIC = OFAtomic.h \
- OFAtomic_builtins.h \
- OFAtomic_no_threads.h \
- OFAtomic_osatomic.h \
- OFAtomic_powerpc.h \
- OFAtomic_sync_builtins.h \
- OFAtomic_x86.h
+ platform/GCC4/OFAtomic.h \
+ platform/GCC4.7/OFAtomic.h \
+ platform/PowerPC/OFAtomic.h \
+ platform/macOS/OFAtomic.h \
+ platform/x86/OFAtomic.h
INCLUDES := ${SRCS:.m=.h} \
OFCollection.h \
OFCryptographicHash.h \
OFJSONRepresentation.h \
OFKernelEventObserver.h \
OFKeyValueCoding.h \
OFLocking.h \
OFMessagePackRepresentation.h \
- OFTLSSocket.h \
ObjFW.h \
macros.h \
objfw-defs.h \
platform.h \
${USE_INCLUDES_ATOMIC}
-SRCS += OFAdjacentArray.m \
+SRCS += OFASPrintF.m \
+ OFAdjacentArray.m \
OFAdjacentSubarray.m \
+ OFBase64.m \
OFBitSetCharacterSet.m \
OFBytesValue.m \
+ OFCRC16.m \
+ OFCRC32.m \
OFCountedMapTableSet.m \
+ OFHuffmanTree.m \
OFInvertedCharacterSet.m \
OFLHADecompressingStream.m \
OFMapTableDictionary.m \
OFMapTableSet.m \
OFMutableAdjacentArray.m \
@@ -193,24 +199,24 @@
OFRangeCharacterSet.m \
OFRangeValue.m \
OFRectValue.m \
OFSandbox.m \
OFSizeValue.m \
+ OFStrPTime.m \
OFSubarray.m \
OFUTF8String.m \
${LIBBASES_M} \
${RUNTIME_AUTORELEASE_M} \
${RUNTIME_INSTANCE_M} \
${UNICODE_M}
-SRCS_FILES += OFFileURLHandler.m \
- OFINIFileSettings.m
+SRCS_FILES += OFFileURLHandler.m
SRCS_SOCKETS += OFDNSResolverSettings.m \
+ ${OF_EPOLL_KERNEL_EVENT_OBSERVER_M} \
OFHTTPURLHandler.m \
OFHostAddressResolver.m \
OFIPSocketAsyncConnector.m \
OFKernelEventObserver.m \
- ${OF_EPOLL_KERNEL_EVENT_OBSERVER_M} \
${OF_KQUEUE_KERNEL_EVENT_OBSERVER_M} \
${OF_POLL_KERNEL_EVENT_OBSERVER_M} \
${OF_SELECT_KERNEL_EVENT_OBSERVER_M} \
OFTCPSocketSOCKS5Connector.m
Index: src/OFASPrintF.h
==================================================================
--- src/OFASPrintF.h
+++ src/OFASPrintF.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFASPrintF.m
==================================================================
--- src/OFASPrintF.m
+++ src/OFASPrintF.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -51,11 +51,11 @@
*/
# define asprintf asprintf_
# define vasprintf vasprintf_
#endif
-struct context {
+struct Context {
const char *format;
size_t formatLen;
char subformat[maxSubformatLen + 1];
size_t subformatLen;
va_list arguments;
@@ -146,11 +146,11 @@
return ret;
}
#endif
static bool
-appendString(struct context *ctx, const char *append, size_t appendLen)
+appendString(struct Context *ctx, const char *append, size_t appendLen)
{
char *newBuf;
if (appendLen == 0)
return true;
@@ -166,11 +166,11 @@
return true;
}
static bool
-appendSubformat(struct context *ctx, const char *subformat,
+appendSubformat(struct Context *ctx, const char *subformat,
size_t subformatLen)
{
if (ctx->subformatLen + subformatLen > maxSubformatLen)
return false;
@@ -180,11 +180,11 @@
return true;
}
static bool
-stringState(struct context *ctx)
+stringState(struct Context *ctx)
{
if (ctx->format[ctx->i] == '%') {
if (ctx->i > 0)
if (!appendString(ctx, ctx->format + ctx->last,
ctx->i - ctx->last))
@@ -199,11 +199,11 @@
return true;
}
static bool
-formatFlagsState(struct context *ctx)
+formatFlagsState(struct Context *ctx)
{
switch (ctx->format[ctx->i]) {
case '-':
case '+':
case ' ':
@@ -226,11 +226,11 @@
return true;
}
static bool
-formatFieldWidthState(struct context *ctx)
+formatFieldWidthState(struct Context *ctx)
{
if ((ctx->format[ctx->i] >= '0' && ctx->format[ctx->i] <= '9') ||
ctx->format[ctx->i] == '*' || ctx->format[ctx->i] == '.') {
if (!appendSubformat(ctx, ctx->format + ctx->i, 1))
return false;
@@ -241,11 +241,11 @@
return true;
}
static bool
-formatLengthModifierState(struct context *ctx)
+formatLengthModifierState(struct Context *ctx)
{
/* Only one allowed */
switch (ctx->format[ctx->i]) {
case 'h': /* and also hh */
if (ctx->formatLen > ctx->i + 1 &&
@@ -371,11 +371,11 @@
ctx->state = stateFormatConversionSpecifier;
return true;
}
static bool
-formatConversionSpecifierState(struct context *ctx)
+formatConversionSpecifierState(struct Context *ctx)
{
char *tmp = NULL;
int tmpLen = 0;
#ifndef HAVE_ASPRINTF_L
OFString *point;
@@ -729,11 +729,11 @@
ctx->state = stateString;
return true;
}
-static bool (*states[])(struct context *) = {
+static bool (*states[])(struct Context *) = {
stringState,
formatFlagsState,
formatFieldWidthState,
formatLengthModifierState,
formatConversionSpecifierState
@@ -740,11 +740,11 @@
};
int
OFVASPrintF(char **string, const char *format, va_list arguments)
{
- struct context ctx;
+ struct Context ctx;
ctx.format = format;
ctx.formatLen = strlen(format);
memset(ctx.subformat, 0, maxSubformatLen + 1);
ctx.subformatLen = 0;
Index: src/OFAdjacentArray.h
==================================================================
--- src/OFAdjacentArray.h
+++ src/OFAdjacentArray.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFAdjacentArray.m
==================================================================
--- src/OFAdjacentArray.m
+++ src/OFAdjacentArray.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFAdjacentSubarray.h
==================================================================
--- src/OFAdjacentSubarray.h
+++ src/OFAdjacentSubarray.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFAdjacentSubarray.m
==================================================================
--- src/OFAdjacentSubarray.m
+++ src/OFAdjacentSubarray.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFApplication.h
==================================================================
--- src/OFApplication.h
+++ src/OFApplication.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -14,10 +14,11 @@
*/
#include
#import "OFObject.h"
+#import "OFNotification.h"
OF_ASSUME_NONNULL_BEGIN
/** @file */
@@ -26,10 +27,15 @@
@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 will terminate.
+ */
+extern const OFNotificationName OFApplicationWillTerminateNotification;
+
/**
* @brief Specify the class to be used as the application delegate.
*
* An instance of this class will be created and act as the application
* delegate.
@@ -143,10 +149,14 @@
* @brief A class which represents the application as an object.
*
* 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
+ * delegate and an @ref OFApplicationWillTerminateNotification will be sent.
*/
OF_SUBCLASSING_RESTRICTED
@interface OFApplication: OFObject
{
OFString *_programName;
Index: src/OFApplication.m
==================================================================
--- src/OFApplication.m
+++ src/OFApplication.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -30,10 +30,11 @@
#ifdef OF_AMIGAOS
# import "OFFile.h"
# import "OFFileManager.h"
#endif
#import "OFLocale.h"
+#import "OFNotificationCenter.h"
#import "OFPair.h"
#import "OFRunLoop+Private.h"
#import "OFRunLoop.h"
#import "OFSandbox.h"
#import "OFString.h"
@@ -73,21 +74,30 @@
OF_DIRECT_MEMBERS
@interface OFApplication ()
- (instancetype)of_init OF_METHOD_FAMILY(init);
- (void)of_setArgumentCount: (int *)argc andArgumentValues: (char **[])argv;
#ifdef OF_WINDOWS
-- (void)of_setArgumentCount: (int)argc andWideArgumentValues: (wchar_t *[])argv;
+- (void)of_setArgumentCount: (int *)argc
+ andArgumentValues: (char **[])argv
+ andWideArgumentCount: (int)wargc
+ andWideArgumentValues: (wchar_t *[])wargv;
#endif
- (void)of_run;
@end
+const OFNotificationName OFApplicationWillTerminateNotification =
+ @"OFApplicationWillTerminateNotification";
static OFApplication *app = nil;
static void
atexitHandler(void)
{
id delegate = app.delegate;
+
+ [[OFNotificationCenter defaultCenter]
+ postNotificationName: OFApplicationWillTerminateNotification
+ object: app];
if ([delegate respondsToSelector: @selector(applicationWillTerminate)])
[delegate applicationWillTerminate];
[delegate release];
@@ -111,11 +121,14 @@
app = [[OFApplication alloc] of_init];
#ifdef OF_WINDOWS
if ([OFSystemInfo isWindowsNT]) {
__wgetmainargs(&wargc, &wargv, &wenvp, _CRT_glob, &si);
- [app of_setArgumentCount: wargc andWideArgumentValues: wargv];
+ [app of_setArgumentCount: argc
+ andArgumentValues: argv
+ andWideArgumentCount: wargc
+ andWideArgumentValues: wargv];
} else
#endif
[app of_setArgumentCount: argc andArgumentValues: argv];
app.delegate = delegate;
@@ -460,11 +473,11 @@
[_environment release];
[super dealloc];
}
-- (void)of_setArgumentCount: (int *)argc andArgumentValues: (char ***)argv
+- (void)of_setArgumentCount: (int *)argc andArgumentValues: (char **[])argv
{
void *pool = objc_autoreleasePoolPush();
OFMutableArray *arguments;
OFStringEncoding encoding;
@@ -493,22 +506,28 @@
objc_autoreleasePoolPop(pool);
}
#ifdef OF_WINDOWS
-- (void)of_setArgumentCount: (int)argc andWideArgumentValues: (wchar_t **)argv
+- (void)of_setArgumentCount: (int *)argc
+ andArgumentValues: (char **[])argv
+ andWideArgumentCount: (int)wargc
+ andWideArgumentValues: (wchar_t *[])wargv
{
void *pool = objc_autoreleasePoolPush();
OFMutableArray *arguments;
- if (argc > 0) {
- _programName = [[OFString alloc] initWithUTF16String: argv[0]];
+ _argc = argc;
+ _argv = argv;
+
+ if (wargc > 0) {
+ _programName = [[OFString alloc] initWithUTF16String: wargv[0]];
arguments = [[OFMutableArray alloc] init];
- for (int i = 1; i < argc; i++)
+ for (int i = 1; i < wargc; i++)
[arguments addObject:
- [OFString stringWithUTF16String: argv[i]]];
+ [OFString stringWithUTF16String: wargv[i]]];
[arguments makeImmutable];
_arguments = arguments;
}
Index: src/OFArray+Private.h
==================================================================
--- src/OFArray+Private.h
+++ src/OFArray+Private.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFArray.h
==================================================================
--- src/OFArray.h
+++ src/OFArray.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -180,13 +180,12 @@
*
* @param objects A C array of objects
* @param count The length of the C array
* @return A new autoreleased OFArray
*/
-+ (instancetype)
- arrayWithObjects: (ObjectType const _Nonnull *_Nonnull)objects
- count: (size_t)count;
++ (instancetype)arrayWithObjects: (ObjectType const _Nonnull *_Nonnull)objects
+ count: (size_t)count;
/**
* @brief Initializes an OFArray with the specified object.
*
* @param object An object
@@ -435,18 +434,10 @@
* @return A new array with the objects from the specified array added
*/
- (OFArray OF_GENERIC(ObjectType) *)arrayByAddingObjectsFromArray:
(OFArray OF_GENERIC(ObjectType) *)array;
-/**
- * @brief Creates a new array with the specified object removed.
- *
- * @param object The object to remove
- * @return A new array with the specified object removed
- */
-- (OFArray OF_GENERIC(ObjectType) *)arrayByRemovingObject: (ObjectType)object;
-
#ifdef OF_HAVE_BLOCKS
/**
* @brief Executes a block for each object.
*
* @param block The block to execute for each object
Index: src/OFArray.m
==================================================================
--- src/OFArray.m
+++ src/OFArray.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -237,22 +237,25 @@
- (id const *)objects
{
size_t count = self.count;
id *buffer = OFAllocMemory(count, sizeof(id));
+ id const *ret;
@try {
[self getObjects: buffer inRange: OFRangeMake(0, count)];
- return [[OFData dataWithItemsNoCopy: buffer
- count: count
- itemSize: sizeof(id)
- freeWhenDone: true] items];
+ ret = [[OFData dataWithItemsNoCopy: buffer
+ count: count
+ itemSize: sizeof(id)
+ freeWhenDone: true] items];
} @catch (id e) {
OFFreeMemory(buffer);
@throw e;
}
+
+ return ret;
}
- (id)copy
{
return [self retain];
@@ -810,18 +813,10 @@
[ret makeImmutable];
return ret;
}
-- (OFArray *)arrayByRemovingObject: (id)object
-{
- OFMutableArray *ret = [[self mutableCopy] autorelease];
- [ret removeObject: object];
- [ret makeImmutable];
- return ret;
-}
-
#ifdef OF_HAVE_BLOCKS
- (OFArray *)mappedArrayUsingBlock: (OFArrayMapBlock)block
{
OFArray *ret;
size_t count = self.count;
Index: src/OFAtomic.h
==================================================================
--- src/OFAtomic.h
+++ src/OFAtomic.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -20,20 +20,166 @@
#ifndef OF_HAVE_ATOMIC_OPS
# error No atomic operations available!
#endif
#if !defined(OF_HAVE_THREADS)
-# import "OFAtomic_no_threads.h"
+static OF_INLINE int
+OFAtomicIntAdd(volatile int *_Nonnull p, int i)
+{
+ return (*p += i);
+}
+
+static OF_INLINE int32_t
+OFAtomicInt32Add(volatile int32_t *_Nonnull p, int32_t i)
+{
+ return (*p += i);
+}
+
+static OF_INLINE void *_Nullable
+OFAtomicPointerAdd(void *volatile _Nullable *_Nonnull p, intptr_t i)
+{
+ return (*(char *volatile *)p += i);
+}
+
+static OF_INLINE int
+OFAtomicIntSubtract(volatile int *_Nonnull p, int i)
+{
+ return (*p -= i);
+}
+
+static OF_INLINE int32_t
+OFAtomicInt32Subtract(volatile int32_t *_Nonnull p, int32_t i)
+{
+ return (*p -= i);
+}
+
+static OF_INLINE void *_Nullable
+OFAtomicPointerSubtract(void *volatile _Nullable *_Nonnull p, intptr_t i)
+{
+ return (*(char *volatile *)p -= i);
+}
+
+static OF_INLINE int
+OFAtomicIntIncrease(volatile int *_Nonnull p)
+{
+ return ++*p;
+}
+
+static OF_INLINE int32_t
+OFAtomicInt32Increase(volatile int32_t *_Nonnull p)
+{
+ return ++*p;
+}
+
+static OF_INLINE int
+OFAtomicIntDecrease(volatile int *_Nonnull p)
+{
+ return --*p;
+}
+
+static OF_INLINE int32_t
+OFAtomicInt32Decrease(volatile int32_t *_Nonnull p)
+{
+ return --*p;
+}
+
+static OF_INLINE unsigned int
+OFAtomicIntOr(volatile unsigned int *_Nonnull p, unsigned int i)
+{
+ return (*p |= i);
+}
+
+static OF_INLINE uint32_t
+OFAtomicInt32Or(volatile uint32_t *_Nonnull p, uint32_t i)
+{
+ return (*p |= i);
+}
+
+static OF_INLINE unsigned int
+OFAtomicIntAnd(volatile unsigned int *_Nonnull p, unsigned int i)
+{
+ return (*p &= i);
+}
+
+static OF_INLINE uint32_t
+OFAtomicInt32And(volatile uint32_t *_Nonnull p, uint32_t i)
+{
+ return (*p &= i);
+}
+
+static OF_INLINE unsigned int
+OFAtomicIntXor(volatile unsigned int *_Nonnull p, unsigned int i)
+{
+ return (*p ^= i);
+}
+
+static OF_INLINE uint32_t
+OFAtomicInt32Xor(volatile uint32_t *_Nonnull p, uint32_t i)
+{
+ return (*p ^= i);
+}
+
+static OF_INLINE bool
+OFAtomicIntCompareAndSwap(volatile int *_Nonnull p, int o, int n)
+{
+ if (*p == o) {
+ *p = n;
+ return true;
+ }
+
+ return false;
+}
+
+static OF_INLINE bool
+OFAtomicInt32CompareAndSwap(volatile int32_t *_Nonnull p, int32_t o, int32_t n)
+{
+ if (*p == o) {
+ *p = n;
+ return true;
+ }
+
+ return false;
+}
+
+static OF_INLINE bool
+OFAtomicPointerCompareAndSwap(void *volatile _Nullable *_Nonnull p,
+ void *_Nullable o, void *_Nullable n)
+{
+ if (*p == o) {
+ *p = n;
+ return true;
+ }
+
+ return false;
+}
+
+static OF_INLINE void
+OFMemoryBarrier(void)
+{
+ /* nop */
+}
+
+static OF_INLINE void
+OFAcquireMemoryBarrier(void)
+{
+ /* nop */
+}
+
+static OF_INLINE void
+OFReleaseMemoryBarrier(void)
+{
+ /* nop */
+}
#elif (defined(OF_X86_64) || defined(OF_X86)) && defined(__GNUC__)
-# import "OFAtomic_x86.h"
+# import "platform/x86/OFAtomic.h"
#elif defined(OF_POWERPC) && defined(__GNUC__) && !defined(__APPLE_CC__) && \
!defined(OF_AIX)
-# import "OFAtomic_powerpc.h"
+# import "platform/PowerPC/OFAtomic.h"
#elif defined(OF_HAVE_ATOMIC_BUILTINS)
-# import "OFAtomic_builtins.h"
+# import "platform/GCC4.7/OFAtomic.h"
#elif defined(OF_HAVE_SYNC_BUILTINS)
-# import "OFAtomic_sync_builtins.h"
+# import "platform/GCC4/OFAtomic.h"
#elif defined(OF_HAVE_OSATOMIC)
-# import "OFAtomic_osatomic.h"
+# import "platform/macOS/OFAtomic.h"
#else
# error No atomic operations available!
#endif
DELETED src/OFAtomic_builtins.h
Index: src/OFAtomic_builtins.h
==================================================================
--- src/OFAtomic_builtins.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (c) 2008-2021 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.
- */
-
-static OF_INLINE int
-OFAtomicIntAdd(volatile int *_Nonnull p, int i)
-{
- return __atomic_add_fetch(p, i, __ATOMIC_RELAXED);
-}
-
-static OF_INLINE int32_t
-OFAtomicInt32Add(volatile int32_t *_Nonnull p, int32_t i)
-{
- return __atomic_add_fetch(p, i, __ATOMIC_RELAXED);
-}
-
-static OF_INLINE void *_Nullable
-OFAtomicPointerAdd(void *volatile _Nullable *_Nonnull p, intptr_t i)
-{
- return __atomic_add_fetch(p, i, __ATOMIC_RELAXED);
-}
-
-static OF_INLINE int
-OFAtomicIntSubtract(volatile int *_Nonnull p, int i)
-{
- return __atomic_sub_fetch(p, i, __ATOMIC_RELAXED);
-}
-
-static OF_INLINE int32_t
-OFAtomicInt32Subtract(volatile int32_t *_Nonnull p, int32_t i)
-{
- return __atomic_sub_fetch(p, i, __ATOMIC_RELAXED);
-}
-
-static OF_INLINE void *_Nullable
-OFAtomicPointerSubtract(void *volatile _Nullable *_Nonnull p, intptr_t i)
-{
- return __atomic_sub_fetch(p, i, __ATOMIC_RELAXED);
-}
-
-static OF_INLINE int
-OFAtomicIntIncrease(volatile int *_Nonnull p)
-{
- return __atomic_add_fetch(p, 1, __ATOMIC_RELAXED);
-}
-
-static OF_INLINE int32_t
-OFAtomicInt32Increase(volatile int32_t *_Nonnull p)
-{
- return __atomic_add_fetch(p, 1, __ATOMIC_RELAXED);
-}
-
-static OF_INLINE int
-OFAtomicIntDecrease(volatile int *_Nonnull p)
-{
- return __atomic_sub_fetch(p, 1, __ATOMIC_RELAXED);
-}
-
-static OF_INLINE int32_t
-OFAtomicInt32Decrease(volatile int32_t *_Nonnull p)
-{
- return __atomic_sub_fetch(p, 1, __ATOMIC_RELAXED);
-}
-
-static OF_INLINE unsigned int
-OFAtomicIntOr(volatile unsigned int *_Nonnull p, unsigned int i)
-{
- return __atomic_or_fetch(p, i, __ATOMIC_RELAXED);
-}
-
-static OF_INLINE uint32_t
-OFAtomicInt32Or(volatile uint32_t *_Nonnull p, uint32_t i)
-{
- return __atomic_or_fetch(p, i, __ATOMIC_RELAXED);
-}
-
-static OF_INLINE unsigned int
-OFAtomicIntAnd(volatile unsigned int *_Nonnull p, unsigned int i)
-{
- return __atomic_and_fetch(p, i, __ATOMIC_RELAXED);
-}
-
-static OF_INLINE uint32_t
-OFAtomicInt32And(volatile uint32_t *_Nonnull p, uint32_t i)
-{
- return __atomic_and_fetch(p, i, __ATOMIC_RELAXED);
-}
-
-static OF_INLINE unsigned int
-OFAtomicIntXor(volatile unsigned int *_Nonnull p, unsigned int i)
-{
- return __atomic_xor_fetch(p, i, __ATOMIC_RELAXED);
-}
-
-static OF_INLINE uint32_t
-OFAtomicInt32Xor(volatile uint32_t *_Nonnull p, uint32_t i)
-{
- return __atomic_xor_fetch(p, i, __ATOMIC_RELAXED);
-}
-
-static OF_INLINE bool
-OFAtomicIntCompareAndSwap(volatile int *_Nonnull p, int o, int n)
-{
- return __atomic_compare_exchange(p, &o, &n, false,
- __ATOMIC_RELAXED, __ATOMIC_RELAXED);
-}
-
-static OF_INLINE bool
-OFAtomicInt32CompareAndSwap(volatile int32_t *_Nonnull p, int32_t o, int32_t n)
-{
- return __atomic_compare_exchange(p, &o, &n, false,
- __ATOMIC_RELAXED, __ATOMIC_RELAXED);
-}
-
-static OF_INLINE bool
-OFAtomicPointerCompareAndSwap(void *volatile _Nullable *_Nonnull p,
- void *_Nullable o, void *_Nullable n)
-{
- return __atomic_compare_exchange(p, &o, &n, false,
- __ATOMIC_RELAXED, __ATOMIC_RELAXED);
-}
-
-static OF_INLINE void
-OFMemoryBarrier(void)
-{
- __atomic_thread_fence(__ATOMIC_SEQ_CST);
-}
-
-static OF_INLINE void
-OFAcquireMemoryBarrier(void)
-{
- __atomic_thread_fence(__ATOMIC_ACQUIRE);
-}
-
-static OF_INLINE void
-OFReleaseMemoryBarrier(void)
-{
- __atomic_thread_fence(__ATOMIC_RELEASE);
-}
DELETED src/OFAtomic_no_threads.h
Index: src/OFAtomic_no_threads.h
==================================================================
--- src/OFAtomic_no_threads.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (c) 2008-2021 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.
- */
-
-static OF_INLINE int
-OFAtomicIntAdd(volatile int *_Nonnull p, int i)
-{
- return (*p += i);
-}
-
-static OF_INLINE int32_t
-OFAtomicInt32Add(volatile int32_t *_Nonnull p, int32_t i)
-{
- return (*p += i);
-}
-
-static OF_INLINE void *_Nullable
-OFAtomicPointerAdd(void *volatile _Nullable *_Nonnull p, intptr_t i)
-{
- return (*(char *volatile *)p += i);
-}
-
-static OF_INLINE int
-OFAtomicIntSubtract(volatile int *_Nonnull p, int i)
-{
- return (*p -= i);
-}
-
-static OF_INLINE int32_t
-OFAtomicInt32Subtract(volatile int32_t *_Nonnull p, int32_t i)
-{
- return (*p -= i);
-}
-
-static OF_INLINE void *_Nullable
-OFAtomicPointerSubtract(void *volatile _Nullable *_Nonnull p, intptr_t i)
-{
- return (*(char *volatile *)p -= i);
-}
-
-static OF_INLINE int
-OFAtomicIntIncrease(volatile int *_Nonnull p)
-{
- return ++*p;
-}
-
-static OF_INLINE int32_t
-OFAtomicInt32Increase(volatile int32_t *_Nonnull p)
-{
- return ++*p;
-}
-
-static OF_INLINE int
-OFAtomicIntDecrease(volatile int *_Nonnull p)
-{
- return --*p;
-}
-
-static OF_INLINE int32_t
-OFAtomicInt32Decrease(volatile int32_t *_Nonnull p)
-{
- return --*p;
-}
-
-static OF_INLINE unsigned int
-OFAtomicIntOr(volatile unsigned int *_Nonnull p, unsigned int i)
-{
- return (*p |= i);
-}
-
-static OF_INLINE uint32_t
-OFAtomicInt32Or(volatile uint32_t *_Nonnull p, uint32_t i)
-{
- return (*p |= i);
-}
-
-static OF_INLINE unsigned int
-OFAtomicIntAnd(volatile unsigned int *_Nonnull p, unsigned int i)
-{
- return (*p &= i);
-}
-
-static OF_INLINE uint32_t
-OFAtomicInt32And(volatile uint32_t *_Nonnull p, uint32_t i)
-{
- return (*p &= i);
-}
-
-static OF_INLINE unsigned int
-OFAtomicIntXor(volatile unsigned int *_Nonnull p, unsigned int i)
-{
- return (*p ^= i);
-}
-
-static OF_INLINE uint32_t
-OFAtomicInt32Xor(volatile uint32_t *_Nonnull p, uint32_t i)
-{
- return (*p ^= i);
-}
-
-static OF_INLINE bool
-OFAtomicIntCompareAndSwap(volatile int *_Nonnull p, int o, int n)
-{
- if (*p == o) {
- *p = n;
- return true;
- }
-
- return false;
-}
-
-static OF_INLINE bool
-OFAtomicInt32CompareAndSwap(volatile int32_t *_Nonnull p, int32_t o, int32_t n)
-{
- if (*p == o) {
- *p = n;
- return true;
- }
-
- return false;
-}
-
-static OF_INLINE bool
-OFAtomicPointerCompareAndSwap(void *volatile _Nullable *_Nonnull p,
- void *_Nullable o, void *_Nullable n)
-{
- if (*p == o) {
- *p = n;
- return true;
- }
-
- return false;
-}
-
-static OF_INLINE void
-OFMemoryBarrier(void)
-{
- /* nop */
-}
-
-static OF_INLINE void
-OFAcquireMemoryBarrier(void)
-{
- /* nop */
-}
-
-static OF_INLINE void
-OFReleaseMemoryBarrier(void)
-{
- /* nop */
-}
DELETED src/OFAtomic_osatomic.h
Index: src/OFAtomic_osatomic.h
==================================================================
--- src/OFAtomic_osatomic.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (c) 2008-2021 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
-
-static OF_INLINE int
-OFAtomicIntAdd(volatile int *_Nonnull p, int i)
-{
- return OSAtomicAdd32(i, p);
-}
-
-static OF_INLINE int32_t
-OFAtomicInt32Add(volatile int32_t *_Nonnull p, int32_t i)
-{
- return OSAtomicAdd32(i, p);
-}
-
-static OF_INLINE void *_Nullable
-OFAtomicPointerAdd(void *volatile _Nullable *_Nonnull p, intptr_t i)
-{
-#ifdef __LP64__
- return (void *)OSAtomicAdd64(i, (int64_t *)p);
-#else
- return (void *)OSAtomicAdd32(i, (int32_t *)p);
-#endif
-}
-
-static OF_INLINE int
-OFAtomicIntSubtract(volatile int *_Nonnull p, int i)
-{
- return OSAtomicAdd32(-i, p);
-}
-
-static OF_INLINE int32_t
-OFAtomicInt32Subtract(volatile int32_t *_Nonnull p, int32_t i)
-{
- return OSAtomicAdd32(-i, p);
-}
-
-static OF_INLINE void *_Nullable
-OFAtomicPointerSubtract(void *volatile _Nullable *_Nonnull p, intptr_t i)
-{
-#ifdef __LP64__
- return (void *)OSAtomicAdd64(-i, (int64_t *)p);
-#else
- return (void *)OSAtomicAdd32(-i, (int32_t *)p);
-#endif
-}
-
-static OF_INLINE int
-OFAtomicIntIncrease(volatile int *_Nonnull p)
-{
- return OSAtomicIncrement32(p);
-}
-
-static OF_INLINE int32_t
-OFAtomicInt32Increase(volatile int32_t *_Nonnull p)
-{
- return OSAtomicIncrement32(p);
-}
-
-static OF_INLINE int
-OFAtomicIntDecrease(volatile int *_Nonnull p)
-{
- return OSAtomicDecrement32(p);
-}
-
-static OF_INLINE int32_t
-OFAtomicInt32Decrease(volatile int32_t *_Nonnull p)
-{
- return OSAtomicDecrement32(p);
-}
-
-static OF_INLINE unsigned int
-OFAtomicIntOr(volatile unsigned int *_Nonnull p, unsigned int i)
-{
- return OSAtomicOr32(i, p);
-}
-
-static OF_INLINE uint32_t
-OFAtomicInt32Or(volatile uint32_t *_Nonnull p, uint32_t i)
-{
- return OSAtomicOr32(i, p);
-}
-
-static OF_INLINE unsigned int
-OFAtomicIntAnd(volatile unsigned int *_Nonnull p, unsigned int i)
-{
- return OSAtomicAnd32(i, p);
-}
-
-static OF_INLINE uint32_t
-OFAtomicInt32And(volatile uint32_t *_Nonnull p, uint32_t i)
-{
- return OSAtomicAnd32(i, p);
-}
-
-static OF_INLINE unsigned int
-OFAtomicIntXor(volatile unsigned int *_Nonnull p, unsigned int i)
-{
- return OSAtomicXor32(i, p);
-}
-
-static OF_INLINE uint32_t
-OFAtomicInt32Xor(volatile uint32_t *_Nonnull p, uint32_t i)
-{
- return OSAtomicXor32(i, p);
-}
-
-static OF_INLINE bool
-OFAtomicIntCompareAndSwap(volatile int *_Nonnull p, int o, int n)
-{
- return OSAtomicCompareAndSwapInt(o, n, p);
-}
-
-static OF_INLINE bool
-OFAtomicInt32CompareAndSwap(volatile int32_t *_Nonnull p, int32_t o, int32_t n)
-{
- return OSAtomicCompareAndSwap32(o, n, p);
-}
-
-static OF_INLINE bool
-OFAtomicPointerCompareAndSwap(void *volatile _Nullable *_Nonnull p,
- void *_Nullable o, void *_Nullable n)
-{
- return OSAtomicCompareAndSwapPtr(o, n, p);
-}
-
-static OF_INLINE void
-OFMemoryBarrier(void)
-{
- OSMemoryBarrier();
-}
-
-static OF_INLINE void
-OFAcquireMemoryBarrier(void)
-{
- OSMemoryBarrier();
-}
-
-static OF_INLINE void
-OFReleaseMemoryBarrier(void)
-{
- OSMemoryBarrier();
-}
DELETED src/OFAtomic_powerpc.h
Index: src/OFAtomic_powerpc.h
==================================================================
--- src/OFAtomic_powerpc.h
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Copyright (c) 2008-2021 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.
- */
-
-static OF_INLINE int
-OFAtomicIntAdd(volatile int *_Nonnull p, int i)
-{
- __asm__ __volatile__ (
- "0:\n\t"
- "lwarx %0, 0, %2\n\t"
- "add %0, %0, %1\n\t"
- "stwcx. %0, 0, %2\n\t"
- "bne- 0b"
- : "=&r"(i)
- : "r"(i), "r"(p)
- : "cc", "memory"
- );
-
- return i;
-}
-
-static OF_INLINE int32_t
-OFAtomicInt32Add(volatile int32_t *_Nonnull p, int32_t i)
-{
- __asm__ __volatile__ (
- "0:\n\t"
- "lwarx %0, 0, %2\n\t"
- "add %0, %0, %1\n\t"
- "stwcx. %0, 0, %2\n\t"
- "bne- 0b"
- : "=&r"(i)
- : "r"(i), "r"(p)
- : "cc", "memory"
- );
-
- return i;
-}
-
-static OF_INLINE void *_Nullable
-OFAtomicPointerAdd(void *volatile _Nullable *_Nonnull p, intptr_t i)
-{
- __asm__ __volatile__ (
- "0:\n\t"
- "lwarx %0, 0, %2\n\t"
- "add %0, %0, %1\n\t"
- "stwcx. %0, 0, %2\n\t"
- "bne- 0b"
- : "=&r"(i)
- : "r"(i), "r"(p)
- : "cc", "memory"
- );
-
- return (void *)i;
-}
-
-static OF_INLINE int
-OFAtomicIntSubtract(volatile int *_Nonnull p, int i)
-{
- __asm__ __volatile__ (
- "0:\n\t"
- "lwarx %0, 0, %2\n\t"
- "sub %0, %0, %1\n\t"
- "stwcx. %0, 0, %2\n\t"
- "bne- 0b"
- : "=&r"(i)
- : "r"(i), "r"(p)
- : "cc", "memory"
- );
-
- return i;
-}
-
-static OF_INLINE int32_t
-OFAtomicInt32Subtract(volatile int32_t *_Nonnull p, int32_t i)
-{
- __asm__ __volatile__ (
- "0:\n\t"
- "lwarx %0, 0, %2\n\t"
- "sub %0, %0, %1\n\t"
- "stwcx. %0, 0, %2\n\t"
- "bne- 0b"
- : "=&r"(i)
- : "r"(i), "r"(p)
- : "cc", "memory"
- );
-
- return i;
-}
-
-static OF_INLINE void *_Nullable
-OFAtomicPointerSubtract(void *volatile _Nullable *_Nonnull p, intptr_t i)
-{
- __asm__ __volatile__ (
- "0:\n\t"
- "lwarx %0, 0, %2\n\t"
- "sub %0, %0, %1\n\t"
- "stwcx. %0, 0, %2\n\t"
- "bne- 0b"
- : "=&r"(i)
- : "r"(i), "r"(p)
- : "cc", "memory"
- );
-
- return (void *)i;
-}
-
-static OF_INLINE int
-OFAtomicIntIncrease(volatile int *_Nonnull p)
-{
- int i;
-
- __asm__ __volatile__ (
- "0:\n\t"
- "lwarx %0, 0, %1\n\t"
- "addi %0, %0, 1\n\t"
- "stwcx. %0, 0, %1\n\t"
- "bne- 0b"
- : "=&r"(i)
- : "r"(p)
- : "cc", "memory"
- );
-
- return i;
-}
-
-static OF_INLINE int32_t
-OFAtomicInt32Increase(volatile int32_t *_Nonnull p)
-{
- int32_t i;
-
- __asm__ __volatile__ (
- "0:\n\t"
- "lwarx %0, 0, %1\n\t"
- "addi %0, %0, 1\n\t"
- "stwcx. %0, 0, %1\n\t"
- "bne- 0b"
- : "=&r"(i)
- : "r"(p)
- : "cc", "memory"
- );
-
- return i;
-}
-
-static OF_INLINE int
-OFAtomicIntDecrease(volatile int *_Nonnull p)
-{
- int i;
-
- __asm__ __volatile__ (
- "0:\n\t"
- "lwarx %0, 0, %1\n\t"
- "subi %0, %0, 1\n\t"
- "stwcx. %0, 0, %1\n\t"
- "bne- 0b"
- : "=&r"(i)
- : "r"(p)
- : "cc", "memory"
- );
-
- return i;
-}
-
-static OF_INLINE int32_t
-OFAtomicInt32Decrease(volatile int32_t *_Nonnull p)
-{
- int32_t i;
-
- __asm__ __volatile__ (
- "0:\n\t"
- "lwarx %0, 0, %1\n\t"
- "subi %0, %0, 1\n\t"
- "stwcx. %0, 0, %1\n\t"
- "bne- 0b"
- : "=&r"(i)
- : "r"(p)
- : "cc", "memory"
- );
-
- return i;
-}
-
-static OF_INLINE unsigned int
-OFAtomicIntOr(volatile unsigned int *_Nonnull p, unsigned int i)
-{
- __asm__ __volatile__ (
- "0:\n\t"
- "lwarx %0, 0, %2\n\t"
- "or %0, %0, %1\n\t"
- "stwcx. %0, 0, %2\n\t"
- "bne- 0b"
- : "=&r"(i)
- : "r"(i), "r"(p)
- : "cc", "memory"
- );
-
- return i;
-}
-
-static OF_INLINE uint32_t
-OFAtomicInt32Or(volatile uint32_t *_Nonnull p, uint32_t i)
-{
- __asm__ __volatile__ (
- "0:\n\t"
- "lwarx %0, 0, %2\n\t"
- "or %0, %0, %1\n\t"
- "stwcx. %0, 0, %2\n\t"
- "bne- 0b"
- : "=&r"(i)
- : "r"(i), "r"(p)
- : "cc", "memory"
- );
-
- return i;
-}
-
-static OF_INLINE unsigned int
-OFAtomicIntAnd(volatile unsigned int *_Nonnull p, unsigned int i)
-{
- __asm__ __volatile__ (
- "0:\n\t"
- "lwarx %0, 0, %2\n\t"
- "and %0, %0, %1\n\t"
- "stwcx. %0, 0, %2\n\t"
- "bne- 0b"
- : "=&r"(i)
- : "r"(i), "r"(p)
- : "cc", "memory"
- );
-
- return i;
-}
-
-static OF_INLINE uint32_t
-OFAtomicInt32And(volatile uint32_t *_Nonnull p, uint32_t i)
-{
- __asm__ __volatile__ (
- "0:\n\t"
- "lwarx %0, 0, %2\n\t"
- "and %0, %0, %1\n\t"
- "stwcx. %0, 0, %2\n\t"
- "bne- 0b"
- : "=&r"(i)
- : "r"(i), "r"(p)
- : "cc", "memory"
- );
-
- return i;
-}
-
-static OF_INLINE unsigned int
-OFAtomicIntXor(volatile unsigned int *_Nonnull p, unsigned int i)
-{
- __asm__ __volatile__ (
- "0:\n\t"
- "lwarx %0, 0, %2\n\t"
- "xor %0, %0, %1\n\t"
- "stwcx. %0, 0, %2\n\t"
- "bne- 0b"
- : "=&r"(i)
- : "r"(i), "r"(p)
- : "cc", "memory"
- );
-
- return i;
-}
-
-static OF_INLINE uint32_t
-OFAtomicInt32Xor(volatile uint32_t *_Nonnull p, uint32_t i)
-{
- __asm__ __volatile__ (
- "0:\n\t"
- "lwarx %0, 0, %2\n\t"
- "xor %0, %0, %1\n\t"
- "stwcx. %0, 0, %2\n\t"
- "bne- 0b"
- : "=&r"(i)
- : "r"(i), "r"(p)
- : "cc", "memory"
- );
-
- return i;
-}
-
-static OF_INLINE bool
-OFAtomicIntCompAndSwap(volatile int *_Nonnull p, int o, int n)
-{
- int r;
-
- __asm__ __volatile__ (
- "0:\n\t"
- "lwarx %0, 0, %3\n\t"
- "cmpw %0, %1\n\t"
- "bne 1f\n\t"
- "stwcx. %2, 0, %3\n\t"
- "bne- 0b\n\t"
- "li %0, 1\n\t"
- "b 2f\n\t"
- "1:\n\t"
- "stwcx. %0, 0, %3\n\t"
- "li %0, 0\n\t"
- "2:"
- : "=&r"(r)
- : "r"(o), "r"(n), "r"(p)
- : "cc", "memory"
- );
-
- return r;
-}
-
-static OF_INLINE bool
-OFAtomicInt32CompareAndSwap(volatile int32_t *_Nonnull p, int32_t o, int32_t n)
-{
- int r;
-
- __asm__ __volatile__ (
- "0:\n\t"
- "lwarx %0, 0, %3\n\t"
- "cmpw %0, %1\n\t"
- "bne 1f\n\t"
- "stwcx. %2, 0, %3\n\t"
- "bne- 0b\n\t"
- "li %0, 1\n\t"
- "b 2f\n\t"
- "1:\n\t"
- "stwcx. %0, 0, %3\n\t"
- "li %0, 0\n\t"
- "2:"
- : "=&r"(r)
- : "r"(o), "r"(n), "r"(p)
- : "cc", "memory"
- );
-
- return r;
-}
-
-static OF_INLINE bool
-OFAtomicPointerCompareAndSwap(void *volatile _Nullable *_Nonnull p,
- void *_Nullable o, void *_Nullable n)
-{
- int r;
-
- __asm__ __volatile__ (
- "0:\n\t"
- "lwarx %0, 0, %3\n\t"
- "cmpw %0, %1\n\t"
- "bne 1f\n\t"
- "stwcx. %2, 0, %3\n\t"
- "bne- 0b\n\t"
- "li %0, 1\n\t"
- "b 2f\n\t"
- "1:\n\t"
- "stwcx. %0, 0, %3\n\t"
- "li %0, 0\n\t"
- "2:"
- : "=&r"(r)
- : "r"(o), "r"(n), "r"(p)
- : "cc", "memory"
- );
-
- return r;
-}
-
-static OF_INLINE void
-OFMemoryBarrier(void)
-{
- __asm__ __volatile__ (
- ".long 0x7C2004AC /* lwsync */" ::: "memory"
- );
-}
-
-static OF_INLINE void
-OFAcquireMemoryBarrier(void)
-{
- __asm__ __volatile__ (
- ".long 0x7C2004AC /* lwsync */" ::: "memory"
- );
-}
-
-static OF_INLINE void
-OFReleaseMemoryBarrier(void)
-{
- __asm__ __volatile__ (
- ".long 0x7C2004AC /* lwsync */" ::: "memory"
- );
-}
DELETED src/OFAtomic_sync_builtins.h
Index: src/OFAtomic_sync_builtins.h
==================================================================
--- src/OFAtomic_sync_builtins.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (c) 2008-2021 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.
- */
-
-static OF_INLINE int
-OFAtomicIntAdd(volatile int *_Nonnull p, int i)
-{
- return __sync_add_and_fetch(p, i);
-}
-
-static OF_INLINE int32_t
-OFAtomicInt32Add(volatile int32_t *_Nonnull p, int32_t i)
-{
- return __sync_add_and_fetch(p, i);
-}
-
-static OF_INLINE void *_Nullable
-OFAtomicPointerAdd(void *volatile _Nullable *_Nonnull p, intptr_t i)
-{
- return __sync_add_and_fetch(p, (void *)i);
-}
-
-static OF_INLINE int
-OFAtomicIntSubtract(volatile int *_Nonnull p, int i)
-{
- return __sync_sub_and_fetch(p, i);
-}
-
-static OF_INLINE int32_t
-OFAtomicInt32Subtract(volatile int32_t *_Nonnull p, int32_t i)
-{
- return __sync_sub_and_fetch(p, i);
-}
-
-static OF_INLINE void *_Nullable
-OFAtomicPointerSubtract(void *volatile _Nullable *_Nonnull p, intptr_t i)
-{
- return __sync_sub_and_fetch(p, (void *)i);
-}
-
-static OF_INLINE int
-OFAtomicIntIncrease(volatile int *_Nonnull p)
-{
- return __sync_add_and_fetch(p, 1);
-}
-
-static OF_INLINE int32_t
-OFAtomicInt32Increase(volatile int32_t *_Nonnull p)
-{
- return __sync_add_and_fetch(p, 1);
-}
-
-static OF_INLINE int
-OFAtomicIntDecrease(volatile int *_Nonnull p)
-{
- return __sync_sub_and_fetch(p, 1);
-}
-
-static OF_INLINE int32_t
-OFAtomicInt32Decrease(volatile int32_t *_Nonnull p)
-{
- return __sync_sub_and_fetch(p, 1);
-}
-
-static OF_INLINE unsigned int
-OFAtomicIntOr(volatile unsigned int *_Nonnull p, unsigned int i)
-{
- return __sync_or_and_fetch(p, i);
-}
-
-static OF_INLINE uint32_t
-OFAtomicInt32Or(volatile uint32_t *_Nonnull p, uint32_t i)
-{
- return __sync_or_and_fetch(p, i);
-}
-
-static OF_INLINE unsigned int
-OFAtomicIntAnd(volatile unsigned int *_Nonnull p, unsigned int i)
-{
- return __sync_and_and_fetch(p, i);
-}
-
-static OF_INLINE uint32_t
-OFAtomicInt32And(volatile uint32_t *_Nonnull p, uint32_t i)
-{
- return __sync_and_and_fetch(p, i);
-}
-
-static OF_INLINE unsigned int
-OFAtomicIntXor(volatile unsigned int *_Nonnull p, unsigned int i)
-{
- return __sync_xor_and_fetch(p, i);
-}
-
-static OF_INLINE uint32_t
-OFAtomicInt32Xor(volatile uint32_t *_Nonnull p, uint32_t i)
-{
- return __sync_xor_and_fetch(p, i);
-}
-
-static OF_INLINE bool
-OFAtomicIntCompareAndSwap(volatile int *_Nonnull p, int o, int n)
-{
- return __sync_bool_compare_and_swap(p, o, n);
-}
-
-static OF_INLINE bool
-OFAtomicInt32CompAndSwap(volatile int32_t *_Nonnull p, int32_t o, int32_t n)
-{
- return __sync_bool_compare_and_swap(p, o, n);
-}
-
-static OF_INLINE bool
-OFAtomicPointerCompareAndSwap(void *volatile _Nullable *_Nonnull p,
- void *_Nullable o, void *_Nullable n)
-{
- return __sync_bool_compare_and_swap(p, o, n);
-}
-
-static OF_INLINE void
-OFMemoryBarrier(void)
-{
- __sync_synchronize();
-}
-
-static OF_INLINE void
-OFAcquireMemoryBarrier(void)
-{
- __sync_synchronize();
-}
-
-static OF_INLINE void
-OFReleaseMemoryBarrier(void)
-{
- __sync_synchronize();
-}
DELETED src/OFAtomic_x86.h
Index: src/OFAtomic_x86.h
==================================================================
--- src/OFAtomic_x86.h
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
- * Copyright (c) 2008-2021 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.
- */
-
-OF_ASSUME_NONNULL_BEGIN
-
-static OF_INLINE int
-OFAtomicIntAdd(volatile int *_Nonnull p, int i)
-{
- if (sizeof(int) == 4)
- __asm__ __volatile__ (
- "lock\n\t"
- "xaddl %0, %2\n\t"
- "addl %1, %0"
- : "+&r"(i)
- : "r"(i), "m"(*p)
- );
-#ifdef OF_X86_64
- else if (sizeof(int) == 8)
- __asm__ __volatile__ (
- "lock\n\t"
- "xaddq %0, %2\n\t"
- "addq %1, %0"
- : "+&r"(i)
- : "r"(i), "m"(*p)
- );
-#endif
- else
- abort();
-
- return i;
-}
-
-static OF_INLINE int32_t
-OFAtomicInt32Add(volatile int32_t *_Nonnull p, int32_t i)
-{
- __asm__ __volatile__ (
- "lock\n\t"
- "xaddl %0, %2\n\t"
- "addl %1, %0"
- : "+&r"(i)
- : "r"(i), "m"(*p)
- );
-
- return i;
-}
-
-static OF_INLINE void *_Nullable
-OFAtomicPointerAdd(void *volatile _Nullable *_Nonnull p, intptr_t i)
-{
-#if defined(OF_X86_64)
- __asm__ __volatile__ (
- "lock\n\t"
- "xaddq %0, %2\n\t"
- "addq %1, %0"
- : "+&r"(i)
- : "r"(i), "m"(*p)
- );
-
- return (void *)i;
-#elif defined(OF_X86)
- __asm__ __volatile__ (
- "lock\n\t"
- "xaddl %0, %2\n\t"
- "addl %1, %0"
- : "+&r"(i)
- : "r"(i), "m"(*p)
- );
-
- return (void *)i;
-#endif
-}
-
-static OF_INLINE int
-OFAtomicIntSubtract(volatile int *_Nonnull p, int i)
-{
- if (sizeof(int) == 4)
- __asm__ __volatile__ (
- "negl %0\n\t"
- "lock\n\t"
- "xaddl %0, %2\n\t"
- "subl %1, %0"
- : "+&r"(i)
- : "r"(i), "m"(*p)
- );
-#ifdef OF_X86_64
- else if (sizeof(int) == 8)
- __asm__ __volatile__ (
- "negq %0\n\t"
- "lock\n\t"
- "xaddq %0, %2\n\t"
- "subq %1, %0"
- : "+&r"(i)
- : "r"(i), "m"(*p)
- );
-#endif
- else
- abort();
-
- return i;
-}
-
-static OF_INLINE int32_t
-OFAtomicInt32Subtract(volatile int32_t *_Nonnull p, int32_t i)
-{
- __asm__ __volatile__ (
- "negl %0\n\t"
- "lock\n\t"
- "xaddl %0, %2\n\t"
- "subl %1, %0"
- : "+&r"(i)
- : "r"(i), "m"(*p)
- );
-
- return i;
-}
-
-static OF_INLINE void *_Nullable
-OFAtomicPointerSubtract(void *volatile _Nullable *_Nonnull p, intptr_t i)
-{
-#if defined(OF_X86_64)
- __asm__ __volatile__ (
- "negq %0\n\t"
- "lock\n\t"
- "xaddq %0, %2\n\t"
- "subq %1, %0"
- : "+&r"(i)
- : "r"(i), "m"(*p)
- );
-
- return (void *)i;
-#elif defined(OF_X86)
- __asm__ __volatile__ (
- "negl %0\n\t"
- "lock\n\t"
- "xaddl %0, %2\n\t"
- "subl %1, %0"
- : "+&r"(i)
- : "r"(i), "m"(*p)
- );
-
- return (void *)i;
-#endif
-}
-
-static OF_INLINE int
-OFAtomicIntIncrease(volatile int *_Nonnull p)
-{
- int i;
-
- if (sizeof(int) == 4)
- __asm__ __volatile__ (
- "xorl %0, %0\n\t"
- "incl %0\n\t"
- "lock\n\t"
- "xaddl %0, %1\n\t"
- "incl %0"
- : "=&r"(i)
- : "m"(*p)
- );
-#ifdef OF_X86_64
- else if (sizeof(int) == 8)
- __asm__ __volatile__ (
- "xorq %0, %0\n\t"
- "incq %0\n\t"
- "lock\n\t"
- "xaddq %0, %1\n\t"
- "incq %0"
- : "=&r"(i)
- : "m"(*p)
- );
-#endif
- else
- abort();
-
- return i;
-}
-
-static OF_INLINE int32_t
-OFAtomicInt32Increase(volatile int32_t *_Nonnull p)
-{
- int32_t i;
-
- __asm__ __volatile__ (
- "xorl %0, %0\n\t"
- "incl %0\n\t"
- "lock\n\t"
- "xaddl %0, %1\n\t"
- "incl %0"
- : "=&r"(i)
- : "m"(*p)
- );
-
- return i;
-}
-
-static OF_INLINE int
-OFAtomicIntDecrease(volatile int *_Nonnull p)
-{
- int i;
-
- if (sizeof(int) == 4)
- __asm__ __volatile__ (
- "xorl %0, %0\n\t"
- "decl %0\n\t"
- "lock\n\t"
- "xaddl %0, %1\n\t"
- "decl %0"
- : "=&r"(i)
- : "m"(*p)
- );
-#ifdef OF_X86_64
- else if (sizeof(int) == 8)
- __asm__ __volatile__ (
- "xorq %0, %0\n\t"
- "decq %0\n\t"
- "lock\n\t"
- "xaddq %0, %1\n\t"
- "decq %0"
- : "=&r"(i)
- : "m"(*p)
- );
-#endif
- else
- abort();
-
- return i;
-}
-
-static OF_INLINE int32_t
-OFAtomicInt32Decrease(volatile int32_t *_Nonnull p)
-{
- int32_t i;
-
- __asm__ __volatile__ (
- "xorl %0, %0\n\t"
- "decl %0\n\t"
- "lock\n\t"
- "xaddl %0, %1\n\t"
- "decl %0"
- : "=&r"(i)
- : "m"(*p)
- );
-
- return i;
-}
-
-static OF_INLINE unsigned int
-OFAtomicIntOr(volatile unsigned int *_Nonnull p, unsigned int i)
-{
- if (sizeof(int) == 4)
- __asm__ __volatile__ (
- "0:\n\t"
- "movl %2, %0\n\t"
- "movl %0, %%eax\n\t"
- "orl %1, %0\n\t"
- "lock\n\t"
- "cmpxchg %0, %2\n\t"
- "jne 0b"
- : "=&r"(i)
- : "r"(i), "m"(*p)
- : "eax", "cc"
- );
-#ifdef OF_X86_64
- else if (sizeof(int) == 8)
- __asm__ __volatile__ (
- "0:\n\t"
- "movq %2, %0\n\t"
- "movq %0, %%rax\n\t"
- "orq %1, %0\n\t"
- "lock\n\t"
- "cmpxchg %0, %2\n\t"
- "jne 0b"
- : "=&r"(i)
- : "r"(i), "m"(*p)
- : "rax", "cc"
- );
-#endif
- else
- abort();
-
- return i;
-}
-
-static OF_INLINE uint32_t
-OFAtomicInt32Or(volatile uint32_t *_Nonnull p, uint32_t i)
-{
- __asm__ __volatile__ (
- "0:\n\t"
- "movl %2, %0\n\t"
- "movl %0, %%eax\n\t"
- "orl %1, %0\n\t"
- "lock\n\t"
- "cmpxchg %0, %2\n\t"
- "jne 0b"
- : "=&r"(i)
- : "r"(i), "m"(*p)
- : "eax", "cc"
- );
-
- return i;
-}
-
-static OF_INLINE unsigned int
-OFAtomicIntAnd(volatile unsigned int *_Nonnull p, unsigned int i)
-{
- if (sizeof(int) == 4)
- __asm__ __volatile__ (
- "0:\n\t"
- "movl %2, %0\n\t"
- "movl %0, %%eax\n\t"
- "andl %1, %0\n\t"
- "lock\n\t"
- "cmpxchg %0, %2\n\t"
- "jne 0b"
- : "=&r"(i)
- : "r"(i), "m"(*p)
- : "eax", "cc"
- );
-#ifdef OF_X86_64
- else if (sizeof(int) == 8)
- __asm__ __volatile__ (
- "0:\n\t"
- "movq %2, %0\n\t"
- "movq %0, %%rax\n\t"
- "andq %1, %0\n\t"
- "lock\n\t"
- "cmpxchg %0, %2\n\t"
- "jne 0b"
- : "=&r"(i)
- : "r"(i), "m"(*p)
- : "rax", "cc"
- );
-#endif
- else
- abort();
-
- return i;
-}
-
-static OF_INLINE uint32_t
-OFAtomicInt32And(volatile uint32_t *_Nonnull p, uint32_t i)
-{
- __asm__ __volatile__ (
- "0:\n\t"
- "movl %2, %0\n\t"
- "movl %0, %%eax\n\t"
- "andl %1, %0\n\t"
- "lock\n\t"
- "cmpxchg %0, %2\n\t"
- "jne 0b"
- : "=&r"(i)
- : "r"(i), "m"(*p)
- : "eax", "cc"
- );
-
- return i;
-}
-
-static OF_INLINE unsigned int
-OFAtomicIntXor(volatile unsigned int *_Nonnull p, unsigned int i)
-{
- if (sizeof(int) == 4)
- __asm__ __volatile__ (
- "0:\n\t"
- "movl %2, %0\n\t"
- "movl %0, %%eax\n\t"
- "xorl %1, %0\n\t"
- "lock\n\t"
- "cmpxchg %0, %2\n\t"
- "jne 0b"
- : "=&r"(i)
- : "r"(i), "m"(*p)
- : "eax", "cc"
- );
-#ifdef OF_X86_64
- else if (sizeof(int) == 8)
- __asm__ __volatile__ (
- "0:\n\t"
- "movq %2, %0\n\t"
- "movq %0, %%rax\n\t"
- "xorq %1, %0\n\t"
- "lock\n\t"
- "cmpxchg %0, %2\n\t"
- "jne 0b"
- : "=&r"(i)
- : "r"(i), "m"(*p)
- : "rax", "cc"
- );
-#endif
- else
- abort();
-
- return i;
-}
-
-static OF_INLINE uint32_t
-OFAtomicInt32Xor(volatile uint32_t *_Nonnull p, uint32_t i)
-{
- __asm__ __volatile__ (
- "0:\n\t"
- "movl %2, %0\n\t"
- "movl %0, %%eax\n\t"
- "xorl %1, %0\n\t"
- "lock\n\t"
- "cmpxchgl %0, %2\n\t"
- "jne 0b"
- : "=&r"(i)
- : "r"(i), "m"(*p)
- : "eax", "cc"
- );
-
- return i;
-}
-
-static OF_INLINE bool
-OFAtomicIntCompareAndSwap(volatile int *_Nonnull p, int o, int n)
-{
- int r;
-
- __asm__ __volatile__ (
- "lock\n\t"
- "cmpxchg %2, %3\n\t"
- "sete %b0\n\t"
- "movzbl %b0, %0"
- : "=&d"(r), "+a"(o) /* use d instead of r to avoid a gcc bug */
- : "r"(n), "m"(*p)
- : "cc"
- );
-
- return r;
-}
-
-static OF_INLINE bool
-OFAtomicInt32CompareAndSwap(volatile int32_t *_Nonnull p, int32_t o, int32_t n)
-{
- int r;
-
- __asm__ __volatile__ (
- "lock\n\t"
- "cmpxchg %2, %3\n\t"
- "sete %b0\n\t"
- "movzbl %b0, %0"
- : "=&d"(r), "+a"(o) /* use d instead of r to avoid a gcc bug */
- : "r"(n), "m"(*p)
- : "cc"
- );
-
- return r;
-}
-
-static OF_INLINE bool
-OFAtomicPointerCompareAndSwap(void *volatile _Nullable *_Nonnull p,
- void *_Nullable o, void *_Nullable n)
-{
- int r;
-
- __asm__ __volatile__ (
- "lock\n\t"
- "cmpxchg %2, %3\n\t"
- "sete %b0\n\t"
- "movzbl %b0, %0"
- : "=&d"(r), "+a"(o) /* use d instead of r to avoid a gcc bug */
- : "r"(n), "m"(*p)
- : "cc"
- );
-
- return r;
-}
-
-static OF_INLINE void
-OFMemoryBarrier(void)
-{
- __asm__ __volatile__ (
- "mfence" ::: "memory"
- );
-}
-
-static OF_INLINE void
-OFAcquireMemoryBarrier(void)
-{
- __asm__ __volatile__ ("" ::: "memory");
-}
-
-static OF_INLINE void
-OFReleaseMemoryBarrier(void)
-{
- __asm__ __volatile__ ("" ::: "memory");
-}
-
-OF_ASSUME_NONNULL_END
Index: src/OFBase64.h
==================================================================
--- src/OFBase64.h
+++ src/OFBase64.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFBase64.m
==================================================================
--- src/OFBase64.m
+++ src/OFBase64.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFBitSetCharacterSet.h
==================================================================
--- src/OFBitSetCharacterSet.h
+++ src/OFBitSetCharacterSet.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFBitSetCharacterSet.m
==================================================================
--- src/OFBitSetCharacterSet.m
+++ src/OFBitSetCharacterSet.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFBlock.h
==================================================================
--- src/OFBlock.h
+++ src/OFBlock.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -40,12 +40,12 @@
@end
#ifdef __cplusplus
extern "C" {
#endif
-extern void *_Block_copy(const void *);
-extern void _Block_release(const void *);
+extern void *_Nullable _Block_copy(const void *_Nullable);
+extern void _Block_release(const void *_Nullable);
# if defined(OF_WINDOWS) && \
(defined(OF_NO_SHARED) || defined(OF_COMPILING_OBJFW))
/*
* Clang has implicit declarations for these, but they are dllimport. When
Index: src/OFBlock.m
==================================================================
--- src/OFBlock.m
+++ src/OFBlock.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFBytesValue.h
==================================================================
--- src/OFBytesValue.h
+++ src/OFBytesValue.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFBytesValue.m
==================================================================
--- src/OFBytesValue.m
+++ src/OFBytesValue.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFCRC16.h
==================================================================
--- src/OFCRC16.h
+++ src/OFCRC16.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFCRC16.m
==================================================================
--- src/OFCRC16.m
+++ src/OFCRC16.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFCRC32.h
==================================================================
--- src/OFCRC32.h
+++ src/OFCRC32.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFCRC32.m
==================================================================
--- src/OFCRC32.m
+++ src/OFCRC32.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFCharacterSet.h
==================================================================
--- src/OFCharacterSet.h
+++ src/OFCharacterSet.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFCharacterSet.m
==================================================================
--- src/OFCharacterSet.m
+++ src/OFCharacterSet.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFCollection.h
==================================================================
--- src/OFCollection.h
+++ src/OFCollection.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFColor.h
==================================================================
--- src/OFColor.h
+++ src/OFColor.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFColor.m
==================================================================
--- src/OFColor.m
+++ src/OFColor.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFCondition.h
==================================================================
--- src/OFCondition.h
+++ src/OFCondition.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFCondition.m
==================================================================
--- src/OFCondition.m
+++ src/OFCondition.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -104,11 +104,11 @@
#ifdef OF_AMIGAOS
- (bool)waitForTimeInterval: (OFTimeInterval)timeInterval
orExecSignal: (ULONG *)signalMask
{
- int error = OFPlainConditionTimedWaitExecOrSignal(&_condition, &_mutex,
+ int error = OFPlainConditionTimedWaitOrExecSignal(&_condition, &_mutex,
timeInterval, signalMask);
if (error == ETIMEDOUT)
return false;
Index: src/OFConstantString.h
==================================================================
--- src/OFConstantString.h
+++ src/OFConstantString.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFConstantString.m
==================================================================
--- src/OFConstantString.m
+++ src/OFConstantString.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -347,10 +347,16 @@
- (OFString *)stringByAppendingPathComponent: (OFString *)component
{
[self finishInitialization];
return [self stringByAppendingPathComponent: component];
}
+
+- (OFString *)stringByAppendingPathExtension: (OFString *)extension
+{
+ [self finishInitialization];
+ return [self stringByAppendingPathExtension: extension];
+}
- (OFString *)stringByPrependingString: (OFString *)string
{
[self finishInitialization];
return [self stringByPrependingString: string];
Index: src/OFCountedMapTableSet.h
==================================================================
--- src/OFCountedMapTableSet.h
+++ src/OFCountedMapTableSet.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFCountedMapTableSet.m
==================================================================
--- src/OFCountedMapTableSet.m
+++ src/OFCountedMapTableSet.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -41,11 +41,11 @@
@try {
void *pool = objc_autoreleasePoolPush();
if ([set isKindOfClass: [OFCountedSet class]]) {
- OFCountedSet *countedSet = (OFCountedSet *)countedSet;
+ OFCountedSet *countedSet = (OFCountedSet *)set;
for (id object in countedSet) {
size_t count =
[countedSet countForObject: object];
Index: src/OFCountedSet.h
==================================================================
--- src/OFCountedSet.h
+++ src/OFCountedSet.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFCountedSet.m
==================================================================
--- src/OFCountedSet.m
+++ src/OFCountedSet.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFCryptographicHash.h
==================================================================
--- src/OFCryptographicHash.h
+++ src/OFCryptographicHash.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -98,10 +98,15 @@
* @param buffer The buffer which should be included into the calculation
* @param length The length of the buffer
*/
- (void)updateWithBuffer: (const void *)buffer length: (size_t)length;
+/**
+ * @brief Performs the final calculation of the cryptographic hash.
+ */
+- (void)calculate;
+
/**
* @brief Resets all state so that a new hash can be calculated.
*
* @warning This invalidates any pointer previously returned by @ref digest. If
* you are still interested in the previous digest, you need to memcpy
Index: src/OFDNSQuery.h
==================================================================
--- src/OFDNSQuery.h
+++ src/OFDNSQuery.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFDNSQuery.m
==================================================================
--- src/OFDNSQuery.m
+++ src/OFDNSQuery.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFDNSResolver.h
==================================================================
--- src/OFDNSResolver.h
+++ src/OFDNSResolver.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFDNSResolver.m
==================================================================
--- src/OFDNSResolver.m
+++ src/OFDNSResolver.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -37,10 +37,11 @@
#import "OFDNSQueryFailedException.h"
#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFInvalidServerReplyException.h"
+#import "OFNotImplementedException.h"
#import "OFOutOfRangeException.h"
#import "OFTruncatedDataException.h"
#ifndef SOCK_DNS
# define SOCK_DNS 0
@@ -745,11 +746,15 @@
OFSocketAddressParseIPv6(@"::", 0);
_IPv6Socket = [[OFUDPSocket alloc] init];
[_IPv6Socket of_bindToAddress: &address
extraType: SOCK_DNS];
- _IPv6Socket.canBlock = false;
+ @try {
+ _IPv6Socket.canBlock = false;
+ } @catch (OFNotImplementedException *e) {
+ /* Can't do anything about it... */
+ }
_IPv6Socket.delegate = self;
}
sock = _IPv6Socket;
break;
@@ -760,11 +765,15 @@
OFSocketAddressParseIPv4(@"0.0.0.0", 0);
_IPv4Socket = [[OFUDPSocket alloc] init];
[_IPv4Socket of_bindToAddress: &address
extraType: SOCK_DNS];
- _IPv4Socket.canBlock = false;
+ @try {
+ _IPv4Socket.canBlock = false;
+ } @catch (OFNotImplementedException *e) {
+ /* Can't do anything about it... */
+ }
_IPv4Socket.delegate = self;
}
sock = _IPv4Socket;
break;
Index: src/OFDNSResolverSettings.h
==================================================================
--- src/OFDNSResolverSettings.h
+++ src/OFDNSResolverSettings.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFDNSResolverSettings.m
==================================================================
--- src/OFDNSResolverSettings.m
+++ src/OFDNSResolverSettings.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -64,15 +64,21 @@
# define RESOLV_CONF_PATH @"AmiTCP:db/resolv.conf"
#else
# define HOSTS_PATH @"/etc/hosts"
# define RESOLV_CONF_PATH @"/etc/resolv.conf"
#endif
+
+#ifndef HOST_NAME_MAX
+# define HOST_NAME_MAX 255
+#endif
#ifndef OF_WII
static OFString *
domainFromHostname(OFString *hostname)
{
+ OFString *ret;
+
if (hostname == nil)
return nil;
@try {
OFSocketAddressParseIP(hostname, 0);
@@ -79,30 +85,32 @@
/*
* If we are still here, the host name is a valid IP address.
* We can't use that as local domain.
*/
- return nil;
+ ret = nil;
} @catch (OFInvalidFormatException *e) {
/* Not an IP address -> we can use it if it contains a dot. */
size_t pos = [hostname rangeOfString: @"."].location;
- if (pos == OFNotFound)
- return nil;
-
- return [hostname substringFromIndex: pos + 1];
+ if (pos != OFNotFound)
+ ret = [hostname substringFromIndex: pos + 1];
+ else
+ ret = nil;
}
+
+ return ret;
}
#endif
#if !defined(OF_WII) && !defined(OF_MORPHOS)
static OFString *
obtainHostname(void)
{
- char hostname[256];
+ char hostname[HOST_NAME_MAX + 1];
- if (gethostname(hostname, 256) != 0)
+ if (gethostname(hostname, HOST_NAME_MAX + 1) != 0)
return nil;
return [OFString stringWithCString: hostname
encoding: [OFLocale encoding]];
}
Index: src/OFDNSResourceRecord.h
==================================================================
--- src/OFDNSResourceRecord.h
+++ src/OFDNSResourceRecord.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -618,14 +618,41 @@
@end
#ifdef __cplusplus
extern "C" {
#endif
+/**
+ * @brief Returns the name for the specified OFDNSClass.
+ *
+ * @param DNSClass The OFDNSClass to return the name for
+ * @return The name for the specified OFDNSClass
+ */
extern OFString *_Nonnull OFDNSClassName(OFDNSClass DNSClass);
+
+/**
+ * @brief Returns the name for the specified OFDNSRecordType.
+ *
+ * @param recordType The OFDNSRecordType to return the name for
+ * @return The name for the specified OFDNSRecordType
+ */
extern OFString *_Nonnull OFDNSRecordTypeName(OFDNSRecordType recordType);
+
+/**
+ * @brief Parses the specified string as an @ref OFDNSClass.
+ *
+ * @param string The string to parse as an @ref OFDNSClass
+ * @return The parsed OFDNSClass
+ */
extern OFDNSClass OFDNSClassParseName(OFString *_Nonnull string);
+
+/**
+ * @brief Parses the specified string as an @ref OFDNSRecordType.
+ *
+ * @param string The string to parse as an @ref OFDNSRecordType
+ * @return The parsed OFDNSRecordType
+ */
extern OFDNSRecordType OFDNSRecordTypeParseName(OFString *_Nonnull string);
#ifdef __cplusplus
}
#endif
OF_ASSUME_NONNULL_END
Index: src/OFDNSResourceRecord.m
==================================================================
--- src/OFDNSResourceRecord.m
+++ src/OFDNSResourceRecord.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFDNSResponse.h
==================================================================
--- src/OFDNSResponse.h
+++ src/OFDNSResponse.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFDNSResponse.m
==================================================================
--- src/OFDNSResponse.m
+++ src/OFDNSResponse.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -54,11 +54,11 @@
}
return self;
}
-- (instancetype)init OF_UNAVAILABLE
+- (instancetype)init
{
OF_INVALID_INIT_METHOD
}
- (void)dealloc
Index: src/OFData+CryptographicHashing.h
==================================================================
--- src/OFData+CryptographicHashing.h
+++ src/OFData+CryptographicHashing.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFData+CryptographicHashing.m
==================================================================
--- src/OFData+CryptographicHashing.m
+++ src/OFData+CryptographicHashing.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -39,10 +39,11 @@
const unsigned char *digest;
char cString[digestSize * 2];
[hash updateWithBuffer: self->_items
length: self->_count * self->_itemSize];
+ [hash calculate];
digest = hash.digest;
for (size_t i = 0; i < digestSize; i++) {
uint8_t high, low;
Index: src/OFData+MessagePackParsing.h
==================================================================
--- src/OFData+MessagePackParsing.h
+++ src/OFData+MessagePackParsing.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFData+MessagePackParsing.m
==================================================================
--- src/OFData+MessagePackParsing.m
+++ src/OFData+MessagePackParsing.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFData.h
==================================================================
--- src/OFData.h
+++ src/OFData.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -43,15 +43,15 @@
* for OFData with item size 1.
*/
@interface OFData: OFObject
{
- unsigned char *_items;
+ unsigned char *_Nullable _items;
size_t _count, _itemSize;
bool _freeWhenDone;
@private
- OFData *_parentData;
+ OFData *_Nullable _parentData;
OF_RESERVE_IVARS(OFData, 4)
}
/**
* @brief The size of a single item in the OFData in bytes.
@@ -66,11 +66,12 @@
/**
* @brief All elements of the OFData as a C array.
*
* @warning The pointer is only valid until the OFData is changed!
*/
-@property (readonly, nonatomic) const void *items OF_RETURNS_INNER_POINTER;
+@property OF_NULLABLE_PROPERTY (readonly, nonatomic) const void *items
+ OF_RETURNS_INNER_POINTER;
/**
* @brief The first item of the OFData or `NULL`.
*/
@property OF_NULLABLE_PROPERTY (readonly, nonatomic) const void *firstItem
@@ -118,10 +119,13 @@
itemSize: (size_t)itemSize;
/**
* @brief Creates a new OFData with the specified `count` items of size 1 by
* taking over ownership of the specified items pointer.
+ *
+ * If initialization fails for whatever reason, the passed memory is *not*
+ * free'd if `freeWhenDone` is true.
*
* @param items The items to store in the OFData
* @param count The number of items
* @param freeWhenDone Whether to free the pointer when it is no longer needed
* by the OFData
@@ -132,10 +136,13 @@
freeWhenDone: (bool)freeWhenDone;
/**
* @brief Creates a new OFData with the specified `count` items of the
* specified size by taking ownership of the specified items pointer.
+ *
+ * If initialization fails for whatever reason, the passed memory is *not*
+ * free'd if `freeWhenDone` is true.
*
* @param items The items to store in the OFData
* @param count The number of items
* @param itemSize The item size of a single item in bytes
* @param freeWhenDone Whether to free the pointer when it is no longer needed
@@ -167,13 +174,13 @@
*/
+ (instancetype)dataWithContentsOfURL: (OFURL *)URL;
/**
* @brief Creates a new OFData with an item size of 1, containing the data of
- * the string representation.
+ * the hex string representation.
*
- * @param string The string representation of the data
+ * @param string The hex string representation of the data
* @return A new autoreleased OFData
*/
+ (instancetype)dataWithStringRepresentation: (OFString *)string;
/**
@@ -184,21 +191,21 @@
* @return A new autoreleased OFData
*/
+ (instancetype)dataWithBase64EncodedString: (OFString *)string;
/**
- * @brief Initialized an already allocated OFData with the specified `count`
+ * @brief Initializes an already allocated OFData with the specified `count`
* items of size 1.
*
* @param items The items to store in the OFData
* @param count The number of items
* @return An initialized OFData
*/
- (instancetype)initWithItems: (const void *)items count: (size_t)count;
/**
- * @brief Initialized an already allocated OFData with the specified `count`
+ * @brief Initializes an already allocated OFData with the specified `count`
* items of the specified size.
*
* @param items The items to store in the OFData
* @param count The number of items
* @param itemSize The item size of a single item in bytes
@@ -210,10 +217,13 @@
/**
* @brief Initializes an already allocated OFData with the specified `count`
* items of size 1 by taking over ownership of the specified items
* pointer.
+ *
+ * If initialization fails for whatever reason, the passed memory is *not*
+ * free'd if `freeWhenDone` is true.
*
* @param items The items to store in the OFData
* @param count The number of items
* @param freeWhenDone Whether to free the pointer when it is no longer needed
* by the OFData
@@ -225,10 +235,13 @@
/**
* @brief Initializes an already allocated OFData with the specified `count`
* items of the specified size by taking ownership of the specified
* items pointer.
+ *
+ * If initialization fails for whatever reason, the passed memory is *not*
+ * free'd if `freeWhenDone` is true.
*
* @param items The items to store in the OFData
* @param count The number of items
* @param itemSize The item size of a single item in bytes
* @param freeWhenDone Whether to free the pointer when it is no longer needed
@@ -260,13 +273,13 @@
*/
- (instancetype)initWithContentsOfURL: (OFURL *)URL;
/**
* @brief Initializes an already allocated OFData with an item size of 1,
- * containing the data of the string representation.
+ * containing the data of the hex string representation.
*
- * @param string The string representation of the data
+ * @param string The hex string representation of the data
* @return A new autoreleased OFData
*/
- (instancetype)initWithStringRepresentation: (OFString *)string;
/**
Index: src/OFData.m
==================================================================
--- src/OFData.m
+++ src/OFData.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFDatagramSocket.h
==================================================================
--- src/OFDatagramSocket.h
+++ src/OFDatagramSocket.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -39,18 +39,15 @@
const OFSocketAddress *_Nonnull sender, id _Nullable exception);
/**
* @brief A block which is called when a packet has been sent.
*
- * @param data The data which was sent
- * @param receiver The receiver for the packet
* @param exception An exception which occurred while reading or `nil` on
* success
* @return The data to repeat the send with or nil if it should not repeat
*/
typedef OFData *_Nullable (^OFDatagramSocketAsyncSendDataBlock)(
- OFData *_Nonnull data, const OFSocketAddress *_Nonnull receiver,
id _Nullable exception);
#endif
/**
* @protocol OFDatagramSocketDelegate OFDatagramSocket.h \
Index: src/OFDatagramSocket.m
==================================================================
--- src/OFDatagramSocket.m
+++ src/OFDatagramSocket.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -116,11 +116,11 @@
@throw [OFSetOptionFailedException exceptionWithObject: self
errNo: errno];
_canBlock = canBlock;
#elif defined(OF_WINDOWS)
- u_long v = canBlock;
+ u_long v = !canBlock;
if (ioctlsocket(_socket, FIONBIO, &v) == SOCKET_ERROR)
@throw [OFSetOptionFailedException
exceptionWithObject: self
errNo: OFSocketErrNo()];
@@ -175,35 +175,40 @@
sender->length = (socklen_t)sizeof(sender->sockaddr);
#ifndef OF_WINDOWS
if ((ret = recvfrom(_socket, buffer, length, 0,
- &sender->sockaddr.sockaddr, &sender->length)) < 0)
+ (struct sockaddr *)&sender->sockaddr, &sender->length)) < 0)
@throw [OFReadFailedException
exceptionWithObject: self
requestedLength: length
errNo: OFSocketErrNo()];
#else
if (length > INT_MAX)
@throw [OFOutOfRangeException exception];
if ((ret = recvfrom(_socket, buffer, (int)length, 0,
- &sender->sockaddr.sockaddr, &sender->length)) < 0)
+ (struct sockaddr *)&sender->sockaddr, &sender->length)) < 0)
@throw [OFReadFailedException
exceptionWithObject: self
requestedLength: length
errNo: OFSocketErrNo()];
#endif
- switch (sender->sockaddr.sockaddr.sa_family) {
+ switch (((struct sockaddr *)&sender->sockaddr)->sa_family) {
case AF_INET:
sender->family = OFSocketAddressFamilyIPv4;
break;
#ifdef OF_HAVE_IPV6
case AF_INET6:
sender->family = OFSocketAddressFamilyIPv6;
break;
+#endif
+#ifdef OF_HAVE_UNIX_SOCKETS
+ case AF_UNIX:
+ sender->family = OFSocketAddressFamilyUNIX;
+ break;
#endif
#ifdef OF_HAVE_IPX
case AF_IPX:
sender->family = OFSocketAddressFamilyIPX;
break;
@@ -274,12 +279,11 @@
if (length > SSIZE_MAX)
@throw [OFOutOfRangeException exception];
if ((bytesWritten = sendto(_socket, (void *)buffer, length, 0,
- (struct sockaddr *)&receiver->sockaddr.sockaddr,
- receiver->length)) < 0)
+ (struct sockaddr *)&receiver->sockaddr, receiver->length)) < 0)
@throw [OFWriteFailedException
exceptionWithObject: self
requestedLength: length
bytesWritten: 0
errNo: OFSocketErrNo()];
@@ -288,11 +292,11 @@
if (length > INT_MAX)
@throw [OFOutOfRangeException exception];
if ((bytesWritten = sendto(_socket, buffer, (int)length, 0,
- &receiver->sockaddr.sockaddr, receiver->length)) < 0)
+ (struct sockaddr *)&receiver->sockaddr, receiver->length)) < 0)
@throw [OFWriteFailedException
exceptionWithObject: self
requestedLength: length
bytesWritten: 0
errNo: OFSocketErrNo()];
Index: src/OFDate.h
==================================================================
--- src/OFDate.h
+++ src/OFDate.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFDate.m
==================================================================
--- src/OFDate.m
+++ src/OFDate.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -39,12 +39,12 @@
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"
-#ifdef OF_AMIGAOS_M68K
-/* amiga-gcc does not have trunc() */
+#if defined(OF_AMIGAOS_M68K) || defined(OF_MINT)
+/* amiga-gcc and freemint-gcc do not have trunc() */
# define trunc(x) ((int64_t)(x))
#endif
@interface OFDate ()
+ (instancetype)of_alloc;
Index: src/OFDictionary.h
==================================================================
--- src/OFDictionary.h
+++ src/OFDictionary.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -32,12 +32,36 @@
OF_ASSUME_NONNULL_BEGIN
@class OFArray OF_GENERIC(ObjectType);
#ifdef OF_HAVE_BLOCKS
+/**
+ * @brief A block for enumerating an OFDictionary.
+ *
+ * @param key The current key
+ * @param object The object for the current key
+ * @param stop A pointer to a variable that can be set to true to stop the
+ * enumeration.
+ */
typedef void (^OFDictionaryEnumerationBlock)(id key, id object, bool *stop);
+
+/**
+ * @brief A block for filtering an OFDictionary.
+ *
+ * @param key The key to inspect
+ * @param object The object for the key to inspect
+ * @return Whether the object should be in the filtered dictionary.
+ */
typedef bool (^OFDictionaryFilterBlock)(id key, id object);
+
+/**
+ * @brief A block for mapping keys to objects in an OFDictionary.
+ *
+ * @param key The key to map
+ * @param object The current object for the key
+ * @return The object to map the key to
+ */
typedef id _Nonnull (^OFDictionaryMapBlock)(id key, id object);
#endif
/**
* @class OFDictionary OFDictionary.h ObjFW/OFDictionary.h
@@ -104,13 +128,12 @@
*
* @param keys An array of keys
* @param objects An array of objects
* @return A new autoreleased OFDictionary
*/
-+ (instancetype)
- dictionaryWithObjects: (OFArray OF_GENERIC(ObjectType) *)objects
- forKeys: (OFArray OF_GENERIC(KeyType) *)keys;
++ (instancetype)dictionaryWithObjects: (OFArray OF_GENERIC(ObjectType) *)objects
+ forKeys: (OFArray OF_GENERIC(KeyType) *)keys;
/**
* @brief Creates a new OFDictionary with the specified keys and objects.
*
* @param keys An array of keys
Index: src/OFDictionary.m
==================================================================
--- src/OFDictionary.m
+++ src/OFDictionary.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
ADDED src/OFEmbeddedFileURLHandler.h
Index: src/OFEmbeddedFileURLHandler.h
==================================================================
--- /dev/null
+++ src/OFEmbeddedFileURLHandler.h
@@ -0,0 +1,23 @@
+/*
+ * 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 "OFURLHandler.h"
+
+OF_ASSUME_NONNULL_BEGIN
+
+@interface OFEmbeddedFileURLHandler: OFURLHandler
+@end
+
+OF_ASSUME_NONNULL_END
ADDED src/OFEmbeddedFileURLHandler.m
Index: src/OFEmbeddedFileURLHandler.m
==================================================================
--- /dev/null
+++ src/OFEmbeddedFileURLHandler.m
@@ -0,0 +1,117 @@
+/*
+ * 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
+#include
+#include
+
+#import "OFEmbeddedFileURLHandler.h"
+#import "OFMemoryStream.h"
+#import "OFURL.h"
+
+#import "OFInvalidArgumentException.h"
+#import "OFOpenItemFailedException.h"
+
+#ifdef OF_HAVE_THREADS
+# import "OFOnce.h"
+# import "OFPlainMutex.h"
+#endif
+
+struct EmbeddedFile {
+ const char *name;
+ const uint8_t *bytes;
+ size_t size;
+} *embeddedFiles = NULL;
+size_t numEmbeddedFiles = 0;
+#ifdef OF_HAVE_THREADS
+static OFPlainMutex mutex;
+
+static void
+init(void)
+{
+ OFEnsure(OFPlainMutexNew(&mutex) == 0);
+}
+#endif
+
+void
+OFRegisterEmbeddedFile(const char *name, const uint8_t *bytes, size_t size)
+{
+#ifdef OF_HAVE_THREADS
+ static OFOnceControl onceControl = OFOnceControlInitValue;
+ OFOnce(&onceControl, init);
+
+ OFEnsure(OFPlainMutexLock(&mutex) == 0);
+#endif
+
+ embeddedFiles = realloc(embeddedFiles,
+ sizeof(*embeddedFiles) * (numEmbeddedFiles + 1));
+ OFEnsure(embeddedFiles != NULL);
+
+ embeddedFiles[numEmbeddedFiles].name = name;
+ embeddedFiles[numEmbeddedFiles].bytes = bytes;
+ embeddedFiles[numEmbeddedFiles].size = size;
+ numEmbeddedFiles++;
+
+#ifdef OF_HAVE_THREADS
+ OFEnsure(OFPlainMutexUnlock(&mutex) == 0);
+#endif
+}
+
+@implementation OFEmbeddedFileURLHandler
+- (OFStream *)openItemAtURL: (OFURL *)URL mode: (OFString *)mode
+{
+ const char *path;
+
+ if (![URL.scheme isEqual: @"objfw-embedded"] || URL.host != nil ||
+ URL.port != nil || URL.user != nil || URL.password != nil ||
+ URL.query != nil || URL.fragment != nil)
+ @throw [OFInvalidArgumentException exception];
+
+ if (![mode isEqual: @"r"])
+ @throw [OFOpenItemFailedException exceptionWithURL: URL
+ mode: mode
+ errNo: EROFS];
+
+ if ((path = URL.path.UTF8String) == NULL) {
+ @throw [OFInvalidArgumentException exception];
+ }
+
+#ifdef OF_HAVE_THREADS
+ OFEnsure(OFPlainMutexLock(&mutex) == 0);
+ @try {
+#endif
+ for (size_t i = 0; i < numEmbeddedFiles; i++) {
+ if (strcmp(embeddedFiles[i].name, path) != 0)
+ continue;
+
+ return [OFMemoryStream
+ streamWithMemoryAddress: (void *)
+ embeddedFiles[i].bytes
+ size: embeddedFiles[i].size
+ writable: false];
+ }
+#ifdef OF_HAVE_THREADS
+ } @finally {
+ OFEnsure(OFPlainMutexUnlock(&mutex) == 0);
+ }
+#endif
+
+ @throw [OFOpenItemFailedException exceptionWithURL: URL
+ mode: mode
+ errNo: ENOENT];
+}
+@end
Index: src/OFEnumerator.h
==================================================================
--- src/OFEnumerator.h
+++ src/OFEnumerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -48,12 +48,10 @@
/**
* @struct OFFastEnumerationState OFEnumerator.h ObjFW/OFEnumerator.h
*
* @brief State information for fast enumerations.
*/
-#define OFFastEnumerationState NSFastEnumerationState
-#ifndef NSINTEGER_DEFINED
typedef struct {
/** Arbitrary state information for the enumeration */
unsigned long state;
/** Pointer to a C array of objects to return */
id __unsafe_unretained _Nullable *_Nullable itemsPtr;
@@ -60,10 +58,12 @@
/** Arbitrary state information to detect mutations */
unsigned long *_Nullable mutationsPtr;
/** Additional arbitrary state information */
unsigned long extra[5];
} OFFastEnumerationState;
+#ifndef NSINTEGER_DEFINED
+typedef OFFastEnumerationState NSFastEnumerationState;
#endif
/**
* @protocol OFFastEnumeration OFEnumerator.h ObjFW/OFEnumerator.h
*
Index: src/OFEnumerator.m
==================================================================
--- src/OFEnumerator.m
+++ src/OFEnumerator.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFEpollKernelEventObserver.h
==================================================================
--- src/OFEpollKernelEventObserver.h
+++ src/OFEpollKernelEventObserver.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFEpollKernelEventObserver.m
==================================================================
--- src/OFEpollKernelEventObserver.m
+++ src/OFEpollKernelEventObserver.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFFile.h
==================================================================
--- src/OFFile.h
+++ src/OFFile.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -63,30 +63,10 @@
* `a+` | Read-write, create or append
* @return A new autoreleased OFFile
*/
+ (instancetype)fileWithPath: (OFString *)path mode: (OFString *)mode;
-/**
- * @brief Creates a new OFFile with the specified URL and mode.
- *
- * @param URL The URL to the file to open
- * @param mode The mode in which the file should be opened.@n
- * Possible modes are:
- * Mode | Description
- * ---------------|-------------------------------------
- * `r` | Read-only
- * `r+` | Read-write
- * `w` | Write-only, create or truncate
- * `wx` | Write-only, create or fail, exclusive
- * `w+` | Read-write, create or truncate
- * `w+x` | Read-write, create or fail, exclusive
- * `a` | Write-only, create or append
- * `a+` | Read-write, create or append
- * @return A new autoreleased OFFile
- */
-+ (instancetype)fileWithURL: (OFURL *)URL mode: (OFString *)mode;
-
/**
* @brief Creates a new OFFile with the specified native file handle.
*
* @param handle A native file handle. If OF_FILE_HANDLE_IS_FD is defined, this
* is a file descriptor. The handle is closed when the OFFile
@@ -93,12 +73,10 @@
* object is deallocated!
* @return A new autoreleased OFFile
*/
+ (instancetype)fileWithHandle: (OFFileHandle)handle;
-- (instancetype)init OF_UNAVAILABLE;
-
/**
* @brief Initializes an already allocated OFFile.
*
* @param path The path to the file to open as a string
* @param mode The mode in which the file should be opened.@n
@@ -122,38 +100,16 @@
- (instancetype)initWithPath: (OFString *)path mode: (OFString *)mode;
/**
* @brief Initializes an already allocated OFFile.
*
- * @param URL The URL to the file to open
- * @param mode The mode in which the file should be opened.@n
- * Possible modes are:
- * Mode | Description
- * ---------------|-------------------------------------
- * `r` | read-only
- * `rb` | read-only, binary
- * `r+` | read-write
- * `rb+` or `r+b` | read-write, binary
- * `w` | write-only, create, truncate
- * `wb` | write-only, create, truncate, binary
- * `w` | read-write, create, truncate
- * `wb+` or `w+b` | read-write, create, truncate, binary
- * `a` | write-only, create, append
- * `ab` | write-only, create, append, binary
- * `a+` | read-write, create, append
- * `ab+` or `a+b` | read-write, create, append, binary
- * @return An initialized OFFile
- */
-- (instancetype)initWithURL: (OFURL *)URL mode: (OFString *)mode;
-
-/**
- * @brief Initializes an already allocated OFFile.
- *
* @param handle A native file handle. If OF_FILE_HANDLE_IS_FD is defined, this
* is a file descriptor. The handle is closed when the OFFile
* object is deallocated!
* @return An initialized OFFile
*/
- (instancetype)initWithHandle: (OFFileHandle)handle OF_DESIGNATED_INITIALIZER;
+
+- (instancetype)init OF_UNAVAILABLE;
@end
OF_ASSUME_NONNULL_END
Index: src/OFFile.m
==================================================================
--- src/OFFile.m
+++ src/OFFile.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -46,10 +46,15 @@
#import "OFWriteFailedException.h"
#ifdef OF_WINDOWS
# include
#endif
+
+#ifdef OF_AMIGAOS
+# include
+# include
+#endif
#ifdef OF_WII
# include
#endif
@@ -56,13 +61,14 @@
#ifdef OF_NINTENDO_DS
# include
# include
#endif
-#ifdef OF_AMIGAOS
-# include
-# include
+#ifdef OF_NINTENDO_SWITCH
+# define id nx_id
+# include
+# undef id
#endif
#ifndef O_BINARY
# define O_BINARY 0
#endif
@@ -77,28 +83,32 @@
#endif
#ifndef OF_AMIGAOS
# define closeHandle(h) close(h)
#else
-static struct _OFFileHandle
+static struct _OFFileHandle {
struct _OFFileHandle *previous, *next;
BPTR handle;
bool append;
} *firstHandle = NULL;
static void
closeHandle(OFFileHandle handle)
{
Close(handle->handle);
+
+ Forbid();
if (handle->previous != NULL)
handle->previous->next = handle->next;
if (handle->next != NULL)
handle->next->previous = handle->previous;
if (firstHandle == handle)
firstHandle = handle->next;
+
+ Permit();
OFFreeMemory(handle);
}
OF_DESTRUCTOR()
@@ -178,32 +188,31 @@
#ifdef OF_NINTENDO_DS
if (!nitroFSInit(NULL))
@throw [OFInitializationFailedException
exceptionWithClass: self];
#endif
+
+#ifdef OF_NINTENDO_SWITCH
+ if (R_SUCCEEDED(romfsInit()))
+ /*
+ * Errors are intentionally ignored, as it's possible we just
+ * have no romfs.
+ */
+ atexit((void (*)(void))romfsExit);
+#endif
}
+ (instancetype)fileWithPath: (OFString *)path mode: (OFString *)mode
{
return [[[self alloc] initWithPath: path mode: mode] autorelease];
}
-+ (instancetype)fileWithURL: (OFURL *)URL mode: (OFString *)mode
-{
- return [[[self alloc] initWithURL: URL mode: mode] autorelease];
-}
-
+ (instancetype)fileWithHandle: (OFFileHandle)handle
{
return [[[self alloc] initWithHandle: handle] autorelease];
}
-- (instancetype)init
-{
- OF_INVALID_INIT_METHOD
-}
-
- (instancetype)initWithPath: (OFString *)path mode: (OFString *)mode
{
OFFileHandle handle;
@try {
@@ -289,18 +298,22 @@
exceptionWithPath: path
mode: mode
errNo: EIO];
}
}
+
+ Forbid();
handle->previous = NULL;
handle->next = firstHandle;
if (firstHandle != NULL)
firstHandle->previous = handle;
firstHandle = handle;
+
+ Permit();
} @catch (id e) {
OFFreeMemory(handle);
@throw e;
}
#endif
@@ -319,37 +332,23 @@
}
return self;
}
-- (instancetype)initWithURL: (OFURL *)URL mode: (OFString *)mode
-{
- void *pool = objc_autoreleasePoolPush();
- OFString *fileSystemRepresentation;
-
- @try {
- fileSystemRepresentation = URL.fileSystemRepresentation;
- } @catch (id e) {
- [self release];
- @throw e;
- }
-
- self = [self initWithPath: fileSystemRepresentation mode: mode];
-
- objc_autoreleasePoolPop(pool);
-
- return self;
-}
-
- (instancetype)initWithHandle: (OFFileHandle)handle
{
self = [super init];
_handle = handle;
return self;
}
+
+- (instancetype)init
+{
+ OF_INVALID_INIT_METHOD
+}
- (bool)lowlevelIsAtEndOfStream
{
if (_handle == OFInvalidFileHandle)
@throw [OFNotOpenException exceptionWithObject: self];
Index: src/OFFileManager.h
==================================================================
--- src/OFFileManager.h
+++ src/OFFileManager.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -407,10 +407,21 @@
* @return An array with the URLs of the items in the specified directory
*/
- (OFArray OF_GENERIC(OFURL *) *)contentsOfDirectoryAtURL: (OFURL *)URL;
#ifdef OF_HAVE_FILES
+/**
+ * @brief Returns an array with all subpaths of the specified directory.
+ *
+ * @note `.` and `..` (of the directory itself or any subdirectory) are not
+ * part of the returned array.
+ *
+ * @param path The path to the directory whose subpaths should be returned
+ * @return An array of OFString with the subpaths of the specified directory
+ */
+- (OFArray OF_GENERIC(OFString *) *)subpathsOfDirectoryAtPath: (OFString *)path;
+
/**
* @brief Changes the current working directory.
*
* @param path The new directory to change to
*/
Index: src/OFFileManager.m
==================================================================
--- src/OFFileManager.m
+++ src/OFFileManager.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -65,43 +65,23 @@
#ifdef OF_AMIGAOS
# include
# include
#endif
+
+#ifdef OF_MINT
+# include
+#endif
@interface OFDefaultFileManager: OFFileManager
@end
-const OFFileAttributeKey OFFileSize = @"OFFileSize";
-const OFFileAttributeKey OFFileType = @"OFFileType";
-const OFFileAttributeKey OFFilePOSIXPermissions = @"OFFilePOSIXPermissions";
-const OFFileAttributeKey OFFileOwnerAccountID = @"OFFileOwnerAccountID";
-const OFFileAttributeKey OFFileGroupOwnerAccountID =
- @"OFFileGroupOwnerAccountID";
-const OFFileAttributeKey OFFileOwnerAccountName = @"OFFileOwnerAccountName";
-const OFFileAttributeKey OFFileGroupOwnerAccountName =
- @"OFFileGroupOwnerAccountName";
-const OFFileAttributeKey OFFileLastAccessDate = @"OFFileLastAccessDate";
-const OFFileAttributeKey OFFileModificationDate = @"OFFileModificationDate";
-const OFFileAttributeKey OFFileStatusChangeDate = @"OFFileStatusChangeDate";
-const OFFileAttributeKey OFFileCreationDate = @"OFFileCreationDate";
-const OFFileAttributeKey OFFileSymbolicLinkDestination =
- @"OFFileSymbolicLinkDestination";
-
-const OFFileAttributeType OFFileTypeRegular = @"OFFileTypeRegular";
-const OFFileAttributeType OFFileTypeDirectory = @"OFFileTypeDirectory";
-const OFFileAttributeType OFFileTypeSymbolicLink = @"OFFileTypeSymbolicLink";
-const OFFileAttributeType OFFileTypeFIFO = @"OFFileTypeFIFO";
-const OFFileAttributeType OFFileTypeCharacterSpecial =
- @"OFFileTypeCharacterSpecial";
-const OFFileAttributeType OFFileTypeBlockSpecial = @"OFFileTypeBlockSpecial";
-const OFFileAttributeType OFFileTypeSocket = @"OFFileTypeSocket";
-const OFFileAttributeType OFFileTypeUnknown = @"OFFileTypeUnknown";
-
#ifdef OF_AMIGAOS4
# define CurrentDir(lock) SetCurrentDir(lock)
#endif
+
+#include "OFFileManagerConstants.inc"
static OFFileManager *defaultManager;
#ifdef OF_AMIGAOS
static bool dirChanged = false;
@@ -470,10 +450,41 @@
ret = [OFMutableArray arrayWithCapacity: URLs.count];
for (OFURL *URL in URLs)
[ret addObject: URL.lastPathComponent];
+ [ret makeImmutable];
+ [ret retain];
+
+ objc_autoreleasePoolPop(pool);
+
+ return [ret autorelease];
+}
+
+- (OFArray OF_GENERIC(OFString *) *)subpathsOfDirectoryAtPath: (OFString *)path
+{
+ void *pool = objc_autoreleasePoolPush();
+ OFMutableArray OF_GENERIC(OFString *) *ret =
+ [OFMutableArray arrayWithObject: path];
+
+ for (OFString *subpath in [self contentsOfDirectoryAtPath: path]) {
+ void *pool2 = objc_autoreleasePoolPush();
+ OFString *fullSubpath =
+ [path stringByAppendingPathComponent: subpath];
+ OFFileAttributes attributes =
+ [self attributesOfItemAtPath: fullSubpath];
+
+ if ([attributes.fileType isEqual: OFFileTypeDirectory])
+ [ret addObjectsFromArray:
+ [self subpathsOfDirectoryAtPath: fullSubpath]];
+ else
+ [ret addObject: fullSubpath];
+
+ objc_autoreleasePoolPop(pool2);
+ }
+
+ [ret makeImmutable];
[ret retain];
objc_autoreleasePoolPop(pool);
return [ret autorelease];
ADDED src/OFFileManagerConstants.inc
Index: src/OFFileManagerConstants.inc
==================================================================
--- /dev/null
+++ src/OFFileManagerConstants.inc
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+const OFFileAttributeKey OFFileSize = @"OFFileSize";
+const OFFileAttributeKey OFFileType = @"OFFileType";
+const OFFileAttributeKey OFFilePOSIXPermissions = @"OFFilePOSIXPermissions";
+const OFFileAttributeKey OFFileOwnerAccountID = @"OFFileOwnerAccountID";
+const OFFileAttributeKey OFFileGroupOwnerAccountID =
+ @"OFFileGroupOwnerAccountID";
+const OFFileAttributeKey OFFileOwnerAccountName = @"OFFileOwnerAccountName";
+const OFFileAttributeKey OFFileGroupOwnerAccountName =
+ @"OFFileGroupOwnerAccountName";
+const OFFileAttributeKey OFFileLastAccessDate = @"OFFileLastAccessDate";
+const OFFileAttributeKey OFFileModificationDate = @"OFFileModificationDate";
+const OFFileAttributeKey OFFileStatusChangeDate = @"OFFileStatusChangeDate";
+const OFFileAttributeKey OFFileCreationDate = @"OFFileCreationDate";
+const OFFileAttributeKey OFFileSymbolicLinkDestination =
+ @"OFFileSymbolicLinkDestination";
+
+const OFFileAttributeType OFFileTypeRegular = @"OFFileTypeRegular";
+const OFFileAttributeType OFFileTypeDirectory = @"OFFileTypeDirectory";
+const OFFileAttributeType OFFileTypeSymbolicLink = @"OFFileTypeSymbolicLink";
+const OFFileAttributeType OFFileTypeFIFO = @"OFFileTypeFIFO";
+const OFFileAttributeType OFFileTypeCharacterSpecial =
+ @"OFFileTypeCharacterSpecial";
+const OFFileAttributeType OFFileTypeBlockSpecial = @"OFFileTypeBlockSpecial";
+const OFFileAttributeType OFFileTypeSocket = @"OFFileTypeSocket";
+const OFFileAttributeType OFFileTypeUnknown = @"OFFileTypeUnknown";
Index: src/OFFileURLHandler.h
==================================================================
--- src/OFFileURLHandler.h
+++ src/OFFileURLHandler.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFFileURLHandler.m
==================================================================
--- src/OFFileURLHandler.m
+++ src/OFFileURLHandler.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFGZIPStream.h
==================================================================
--- src/OFGZIPStream.h
+++ src/OFGZIPStream.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFGZIPStream.m
==================================================================
--- src/OFGZIPStream.m
+++ src/OFGZIPStream.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFHMAC.h
==================================================================
--- src/OFHMAC.h
+++ src/OFHMAC.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -101,10 +101,15 @@
* @param buffer The buffer which should be included into the calculation
* @param length The length of the buffer
*/
- (void)updateWithBuffer: (const void *)buffer length: (size_t)length;
+/**
+ * @brief Performs the final calculation of the HMAC.
+ */
+- (void)calculate;
+
/**
* @brief Resets the HMAC so that it can be calculated for a new message.
*
* @note This does not reset the key so that a new HMAC with the same key can
* be calculated efficiently. If you want to reset both, use
Index: src/OFHMAC.m
==================================================================
--- src/OFHMAC.m
+++ src/OFHMAC.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -17,10 +17,11 @@
#import "OFHMAC.h"
#import "OFSecureData.h"
#import "OFHashAlreadyCalculatedException.h"
+#import "OFHashNotCalculatedException.h"
#import "OFInvalidArgumentException.h"
@implementation OFHMAC
@synthesize hashClass = _hashClass;
@synthesize allowsSwappableMemory = _allowsSwappableMemory;
@@ -82,10 +83,11 @@
if (length > blockSize) {
id hash = [_hashClass
hashWithAllowsSwappableMemory:
_allowsSwappableMemory];
[hash updateWithBuffer: key length: length];
+ [hash calculate];
length = hash.digestSize;
if OF_UNLIKELY (length > blockSize)
length = blockSize;
@@ -138,21 +140,30 @@
exceptionWithObject: self];
[_innerHash updateWithBuffer: buffer length: length];
}
-- (const unsigned char *)digest
+- (void)calculate
{
+ if (_calculated)
+ @throw [OFHashAlreadyCalculatedException
+ exceptionWithObject: self];
+
if (_outerHash == nil || _innerHash == nil)
@throw [OFInvalidArgumentException exception];
- if (_calculated)
- return _outerHash.digest;
-
+ [_innerHash calculate];
[_outerHash updateWithBuffer: _innerHash.digest
length: _innerHash.digestSize];
+ [_outerHash calculate];
_calculated = true;
+}
+
+- (const unsigned char *)digest
+{
+ if (!_calculated)
+ @throw [OFHashNotCalculatedException exceptionWithObject: self];
return _outerHash.digest;
}
- (size_t)digestSize
Index: src/OFHTTPClient.h
==================================================================
--- src/OFHTTPClient.h
+++ src/OFHTTPClient.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -25,10 +25,11 @@
@class OFHTTPClient;
@class OFHTTPRequest;
@class OFHTTPResponse;
@class OFStream;
@class OFTCPSocket;
+@class OFTLSStream;
@class OFURL;
/**
* @protocol OFHTTPClientDelegate OFHTTPClient.h ObjFW/OFHTTPClient.h
*
@@ -48,24 +49,36 @@
response: (nullable OFHTTPResponse *)response
exception: (nullable id)exception;
@optional
/**
- * @brief A callback which is called when an OFHTTPClient creates a socket.
- *
- * This is useful if the connection is using HTTPS and the server requires a
- * client certificate. This callback can then be used to tell the TLS socket
- * about the certificate. Another use case is to tell the socket about a SOCKS5
- * proxy it should use for this connection.
- *
- * @param client The OFHTTPClient that created a socket
- * @param socket The socket created by the OFHTTPClient
- * @param request The request for which the socket was created
- */
-- (void)client: (OFHTTPClient *)client
- didCreateSocket: (OFTCPSocket *)socket
- request: (OFHTTPRequest *)request;
+ * @brief A callback which is called when an OFHTTPClient creates a TCP socket.
+ *
+ * This can be used to tell the socket about a SOCKS5 proxy it should use for
+ * this connection.
+ *
+ * @param client The OFHTTPClient that created a TCP socket
+ * @param TCPSocket The socket created by the OFHTTPClient
+ * @param request The request for which the TCP socket was created
+ */
+- (void)client: (OFHTTPClient *)client
+ didCreateTCPSocket: (OFTCPSocket *)TCPSocket
+ request: (OFHTTPRequest *)request;
+
+/**
+ * @brief A callback which is called when an OFHTTPClient creates a TLS stream.
+ *
+ * This can be used to tell the TLS stream about a client certificate it should
+ * use before performing the TLS handshake.
+ *
+ * @param client The OFHTTPClient that created a TLS stream
+ * @param TLSStream The TLS stream created by the OFHTTPClient
+ * @param request The request for which the TLS stream was created
+ */
+- (void)client: (OFHTTPClient *)client
+ didCreateTLSStream: (OFTLSStream *)TLSStream
+ request: (OFHTTPRequest *)request;
/**
* @brief A callback which is called when an OFHTTPClient wants to send the
* body for a request.
*
@@ -134,11 +147,11 @@
#ifdef OF_HTTPCLIENT_M
@public
#endif
OFObject *_Nullable _delegate;
bool _allowsInsecureRedirects, _inProgress;
- OFTCPSocket *_Nullable _socket;
+ OFStream *_Nullable _stream;
OFURL *_Nullable _lastURL;
bool _lastWasHEAD;
OFHTTPResponse *_Nullable _lastResponse;
}
Index: src/OFHTTPClient.m
==================================================================
--- src/OFHTTPClient.m
+++ src/OFHTTPClient.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -26,13 +26,13 @@
#import "OFHTTPRequest.h"
#import "OFHTTPResponse.h"
#import "OFKernelEventObserver.h"
#import "OFNumber.h"
#import "OFRunLoop.h"
-#import "OFSocket+Private.h"
#import "OFString.h"
#import "OFTCPSocket.h"
+#import "OFTLSStream.h"
#import "OFURL.h"
#import "OFAlreadyConnectedException.h"
#import "OFHTTPRequestFailedException.h"
#import "OFInvalidArgumentException.h"
@@ -49,11 +49,12 @@
#import "OFWriteFailedException.h"
static const unsigned int defaultRedirects = 10;
OF_DIRECT_MEMBERS
-@interface OFHTTPClientRequestHandler: OFObject
+@interface OFHTTPClientRequestHandler: OFObject
{
@public
OFHTTPClient *_client;
OFHTTPRequest *_request;
unsigned int _redirects;
@@ -72,32 +73,32 @@
OF_DIRECT_MEMBERS
@interface OFHTTPClientRequestBodyStream: OFStream
{
OFHTTPClientRequestHandler *_handler;
- OFTCPSocket *_socket;
+ OFStream *_stream;
bool _chunked;
unsigned long long _toWrite;
bool _atEndOfStream;
}
- (instancetype)initWithHandler: (OFHTTPClientRequestHandler *)handler
- socket: (OFTCPSocket *)sock;
+ stream: (OFStream *)stream;
@end
OF_DIRECT_MEMBERS
@interface OFHTTPClientResponse: OFHTTPResponse
{
- OFTCPSocket *_socket;
+ OFStream *_stream;
bool _hasContentLength, _chunked, _keepAlive;
bool _atEndOfStream, _setAtEndOfStream;
long long _toRead;
}
@property (nonatomic, setter=of_setKeepAlive:) bool of_keepAlive;
-- (instancetype)initWithSocket: (OFTCPSocket *)sock;
+- (instancetype)initWithStream: (OFStream *)stream;
@end
OF_DIRECT_MEMBERS
@interface OFHTTPClientSyncPerformer: OFObject
{
@@ -293,20 +294,20 @@
didPerformRequest: _request
response: nil
exception: exception];
}
-- (void)createResponseWithSocketOrThrow: (OFTCPSocket *)sock
+- (void)createResponseWithStreamOrThrow: (OFStream *)stream
{
OFURL *URL = _request.URL;
OFHTTPClientResponse *response;
OFString *connectionHeader;
bool keepAlive;
OFString *location;
id exception;
- response = [[[OFHTTPClientResponse alloc] initWithSocket: sock]
+ response = [[[OFHTTPClientResponse alloc] initWithStream: stream]
autorelease];
response.protocolVersionString = _version;
response.statusCode = _status;
response.headers = _serverHeaders;
@@ -325,11 +326,11 @@
}
if (keepAlive) {
response.of_keepAlive = true;
- _client->_socket = [sock retain];
+ _client->_stream = [stream retain];
_client->_lastURL = [URL copy];
_client->_lastWasHEAD =
(_request.method == OFHTTPRequestMethodHead);
_client->_lastResponse = [response retain];
}
@@ -429,14 +430,14 @@
withObject: response
withObject: exception
afterDelay: 0];
}
-- (void)createResponseWithSocket: (OFTCPSocket *)sock
+- (void)createResponseWithStream: (OFStream *)stream
{
@try {
- [self createResponseWithSocketOrThrow: sock];
+ [self createResponseWithStreamOrThrow: stream];
} @catch (id e) {
[self raiseException: e];
}
}
@@ -471,11 +472,11 @@
_status = (short)status;
return true;
}
-- (bool)handleServerHeader: (OFString *)line socket: (OFTCPSocket *)sock
+- (bool)handleServerHeader: (OFString *)line stream: (OFStream *)stream
{
OFString *key, *value, *old;
const char *lineC, *tmp;
char *keyC;
@@ -490,14 +491,14 @@
[_client->_delegate client: _client
didReceiveHeaders: _serverHeaders
statusCode: _status
request: _request];
- sock.delegate = nil;
+ stream.delegate = nil;
- [self performSelector: @selector(createResponseWithSocket:)
- withObject: sock
+ [self performSelector: @selector(createResponseWithStream:)
+ withObject: stream
afterDelay: 0];
return false;
}
@@ -532,11 +533,11 @@
[_serverHeaders setObject: value forKey: key];
return true;
}
-- (bool)stream: (OFStream *)sock
+- (bool)stream: (OFStream *)stream
didReadLine: (OFString *)line
exception: (id)exception
{
bool ret;
@@ -552,12 +553,11 @@
@try {
if (_firstLine) {
_firstLine = false;
ret = [self handleFirstLine: line];
} else
- ret = [self handleServerHeader: line
- socket: (OFTCPSocket *)sock];
+ ret = [self handleServerHeader: line stream: stream];
} @catch (id e) {
[self raiseException: e];
ret = false;
}
@@ -594,12 +594,11 @@
if (chunked || [headers objectForKey: @"Content-Length"] != nil) {
stream.delegate = nil;
OFStream *requestBody = [[[OFHTTPClientRequestBodyStream alloc]
- initWithHandler: self
- socket: (OFTCPSocket *)stream] autorelease];
+ initWithHandler: self stream: stream] autorelease];
if ([_client->_delegate respondsToSelector:
@selector(client:wantsRequestBody:request:)])
[_client->_delegate client: _client
wantsRequestBody: requestBody
@@ -608,23 +607,23 @@
[stream asyncReadLine];
return nil;
}
-- (void)handleSocket: (OFTCPSocket *)sock
+- (void)handleStream: (OFStream *)stream
{
/*
* As a work around for a bug with split packets in lighttpd when using
* HTTPS, we construct the complete request in a buffer string and then
* send it all at once.
*
- * We do not use the socket's write buffer in case we need to resend
+ * We do not use the streams's write buffer in case we need to resend
* the entire request (e.g. in case a keep-alive connection timed out).
*/
@try {
- [sock asyncWriteString: constructRequestString(_request)];
+ [stream asyncWriteString: constructRequestString(_request)];
} @catch (id e) {
[self raiseException: e];
return;
}
}
@@ -632,58 +631,95 @@
- (void)socket: (OFTCPSocket *)sock
didConnectToHost: (OFString *)host
port: (uint16_t)port
exception: (id)exception
{
- sock.delegate = self;
+ if (exception != nil) {
+ [self raiseException: exception];
+ return;
+ }
+ sock.canBlock = false;
+
+ if ([_client->_delegate respondsToSelector:
+ @selector(client:didCreateTCPSocket:request:)])
+ [_client->_delegate client: _client
+ didCreateTCPSocket: sock
+ request: _request];
+
+ if ([_request.URL.scheme caseInsensitiveCompare: @"https"] ==
+ OFOrderedSame) {
+ OFTLSStream *stream;
+ @try {
+ stream = [OFTLSStream streamWithStream: sock];
+ } @catch (OFNotImplementedException *e) {
+ [self raiseException:
+ [OFUnsupportedProtocolException
+ exceptionWithURL: _request.URL]];
+ return;
+ }
+
+ if ([_client->_delegate respondsToSelector:
+ @selector(client:didCreateTLSStream:request:)])
+ [_client->_delegate client: _client
+ didCreateTLSStream: stream
+ request: _request];
+
+ stream.delegate = self;
+ [stream asyncPerformClientHandshakeWithHost: _request.URL.host];
+ } else {
+ sock.delegate = self;
+ [self performSelector: @selector(handleStream:)
+ withObject: sock
+ afterDelay: 0];
+ }
+}
+
+- (void)stream: (OFTLSStream *)stream
+ didPerformClientHandshakeWithHost: (OFString *)host
+ exception: (id)exception
+{
if (exception != nil) {
[self raiseException: exception];
return;
}
- if ([_client->_delegate respondsToSelector:
- @selector(client:didCreateSocket:request:)])
- [_client->_delegate client: _client
- didCreateSocket: sock
- request: _request];
-
- [self performSelector: @selector(handleSocket:)
- withObject: sock
+ [self performSelector: @selector(handleStream:)
+ withObject: stream
afterDelay: 0];
}
- (void)start
{
OFURL *URL = _request.URL;
- OFTCPSocket *sock;
+ OFStream *stream;
/* Can we reuse the last socket? */
- if (_client->_socket != nil && !_client->_socket.atEndOfStream &&
+ if (_client->_stream != nil && !_client->_stream.atEndOfStream &&
[_client->_lastURL.scheme isEqual: URL.scheme] &&
[_client->_lastURL.host isEqual: URL.host] &&
(_client->_lastURL.port == URL.port ||
[_client->_lastURL.port isEqual: URL.port]) &&
(_client->_lastWasHEAD || _client->_lastResponse.atEndOfStream)) {
/*
- * Set _socket to nil, so that in case of an error it won't be
- * reused. If everything is successful, we set _socket again
+ * Set _stream to nil, so that in case of an error it won't be
+ * reused. If everything is successful, we set _stream again
* at the end.
*/
- sock = [_client->_socket autorelease];
- _client->_socket = nil;
+ stream = [_client->_stream autorelease];
+ _client->_stream = nil;
[_client->_lastURL release];
_client->_lastURL = nil;
[_client->_lastResponse release];
_client->_lastResponse = nil;
- sock.delegate = self;
+ stream.delegate = self;
- [self performSelector: @selector(handleSocket:)
- withObject: sock
+ [self performSelector: @selector(handleStream:)
+ withObject: stream
afterDelay: 0];
} else
[self closeAndReconnect];
}
@@ -694,23 +730,18 @@
OFTCPSocket *sock;
uint16_t port;
OFNumber *URLPort;
[_client close];
+
+ sock = [OFTCPSocket socket];
if ([URL.scheme caseInsensitiveCompare: @"https"] ==
- OFOrderedSame) {
- if (OFTLSSocketClass == Nil)
- @throw [OFUnsupportedProtocolException
- exceptionWithURL: URL];
-
- sock = [[[OFTLSSocketClass alloc] init] autorelease];
+ OFOrderedSame)
port = 443;
- } else {
- sock = [OFTCPSocket socket];
+ else
port = 80;
- }
URLPort = URL.port;
if (URLPort != nil)
port = URLPort.unsignedShortValue;
@@ -722,20 +753,20 @@
}
@end
@implementation OFHTTPClientRequestBodyStream
- (instancetype)initWithHandler: (OFHTTPClientRequestHandler *)handler
- socket: (OFTCPSocket *)sock
+ stream: (OFStream *)stream
{
self = [super init];
@try {
OFDictionary OF_GENERIC(OFString *, OFString *) *headers;
OFString *transferEncoding, *contentLengthString;
_handler = [handler retain];
- _socket = [sock retain];
+ _stream = [stream retain];
headers = _handler->_request.headers;
transferEncoding = [headers objectForKey: @"Transfer-Encoding"];
_chunked = [transferEncoding isEqual: @"chunked"];
@@ -757,25 +788,23 @@
return self;
}
- (void)dealloc
{
- if (_socket != nil)
+ if (_stream != nil)
[self close];
[_handler release];
[super dealloc];
}
-- (size_t)lowlevelWriteBuffer: (const void *)buffer
- length: (size_t)length
+- (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length
{
- size_t requestedLength = length;
- size_t ret;
+ /* TODO: Use non-blocking writes */
- if (_socket == nil)
+ if (_stream == nil)
@throw [OFNotOpenException exceptionWithObject: self];
/*
* We must not send a chunk of size 0, as that would end the body. We
* always ignore writing 0 bytes to still allow writing 0 bytes after
@@ -783,90 +812,80 @@
*/
if (length == 0)
return 0;
if (_atEndOfStream)
- @throw [OFWriteFailedException
- exceptionWithObject: self
- requestedLength: requestedLength
- bytesWritten: 0
- errNo: 0];
+ @throw [OFWriteFailedException exceptionWithObject: self
+ requestedLength: length
+ bytesWritten: 0
+ errNo: ENOTCONN];
if (_chunked)
- [_socket writeFormat: @"%zX\r\n", length];
+ [_stream writeFormat: @"%zX\r\n", length];
else if (length > _toWrite)
- length = (size_t)_toWrite;
+ @throw [OFOutOfRangeException exception];
- ret = [_socket writeBuffer: buffer length: length];
+ [_stream writeBuffer: buffer length: length];
if (_chunked)
- [_socket writeString: @"\r\n"];
-
- if (ret > length)
- @throw [OFOutOfRangeException exception];
+ [_stream writeString: @"\r\n"];
if (!_chunked) {
- _toWrite -= ret;
+ _toWrite -= length;
if (_toWrite == 0)
_atEndOfStream = true;
}
- if (requestedLength > length)
- @throw [OFWriteFailedException
- exceptionWithObject: self
- requestedLength: requestedLength
- bytesWritten: ret
- errNo: 0];
-
- return ret;
+ return length;
}
- (bool)lowlevelIsAtEndOfStream
{
return _atEndOfStream;
}
- (void)close
{
- if (_socket == nil)
+ if (_stream == nil)
@throw [OFNotOpenException exceptionWithObject: self];
if (_chunked)
- [_socket writeString: @"0\r\n\r\n"];
+ [_stream writeString: @"0\r\n\r\n"];
else if (_toWrite > 0)
@throw [OFTruncatedDataException exception];
- _socket.delegate = _handler;
- [_socket asyncReadLine];
+ _stream.delegate = _handler;
+ [_stream asyncReadLine];
- [_socket release];
- _socket = nil;
+ [_stream release];
+ _stream = nil;
[super close];
}
- (int)fileDescriptorForWriting
{
- return _socket.fileDescriptorForWriting;
+ return ((OFStream *)_stream)
+ .fileDescriptorForWriting;
}
@end
@implementation OFHTTPClientResponse
@synthesize of_keepAlive = _keepAlive;
-- (instancetype)initWithSocket: (OFTCPSocket *)sock
+- (instancetype)initWithStream: (OFStream *)stream
{
self = [super init];
- _socket = [sock retain];
+ _stream = [stream retain];
return self;
}
- (void)dealloc
{
- if (_socket != nil)
+ if (_stream != nil)
[self close];
[super dealloc];
}
@@ -900,30 +919,30 @@
}
}
- (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length
{
- if (_socket == nil)
+ if (_stream == nil)
@throw [OFNotOpenException exceptionWithObject: self];
if (_atEndOfStream)
return 0;
if (!_hasContentLength && !_chunked)
- return [_socket readIntoBuffer: buffer length: length];
+ return [_stream readIntoBuffer: buffer length: length];
- if (_socket.atEndOfStream)
+ if (_stream.atEndOfStream)
@throw [OFTruncatedDataException exception];
/* Content-Length */
if (!_chunked) {
size_t ret;
if (length > (unsigned long long)_toRead)
length = (size_t)_toRead;
- ret = [_socket readIntoBuffer: buffer length: length];
+ ret = [_stream readIntoBuffer: buffer length: length];
if (ret > length)
@throw [OFOutOfRangeException exception];
_toRead -= ret;
@@ -935,11 +954,11 @@
/* Chunked */
if (_toRead == -2) {
char tmp[2];
- switch ([_socket readIntoBuffer: tmp length: 2]) {
+ switch ([_stream readIntoBuffer: tmp length: 2]) {
case 2:
_toRead++;
if (tmp[1] != '\n')
@throw [OFInvalidServerReplyException
exception];
@@ -955,11 +974,11 @@
return 0;
} else if (_toRead == -1) {
char tmp;
- if ([_socket readIntoBuffer: &tmp length: 1] == 1) {
+ if ([_stream readIntoBuffer: &tmp length: 1] == 1) {
_toRead++;
if (tmp != '\n')
@throw [OFInvalidServerReplyException
exception];
}
@@ -970,11 +989,11 @@
return 0;
} else if (_toRead > 0) {
if (length > (unsigned long long)_toRead)
length = (size_t)_toRead;
- length = [_socket readIntoBuffer: buffer length: length];
+ length = [_stream readIntoBuffer: buffer length: length];
_toRead -= length;
if (_toRead == 0)
_toRead = -2;
@@ -983,11 +1002,11 @@
void *pool = objc_autoreleasePoolPush();
OFString *line;
size_t pos;
@try {
- line = [_socket tryReadLine];
+ line = [_stream tryReadLine];
} @catch (OFInvalidEncodingException *e) {
@throw [OFInvalidServerReplyException exception];
}
if (line == nil)
@@ -997,14 +1016,14 @@
if (pos != OFNotFound)
line = [line substringToIndex: pos];
if (line.length < 1) {
/*
- * We have read the empty string because the socket is
+ * We have read the empty string because the stream is
* at end of stream.
*/
- if (_socket.atEndOfStream && pos == OFNotFound)
+ if (_stream.atEndOfStream && pos == OFNotFound)
@throw [OFTruncatedDataException exception];
else
@throw [OFInvalidServerReplyException
exception];
}
@@ -1035,41 +1054,42 @@
- (bool)lowlevelIsAtEndOfStream
{
if (_atEndOfStream)
return true;
- if (_socket == nil)
+ if (_stream == nil)
@throw [OFNotOpenException exceptionWithObject: self];
if (!_hasContentLength && !_chunked)
- return _socket.atEndOfStream;
+ return _stream.atEndOfStream;
return _atEndOfStream;
}
- (int)fileDescriptorForReading
{
- if (_socket == nil)
+ if (_stream == nil)
return -1;
- return _socket.fileDescriptorForReading;
+ return ((OFStream *)_stream)
+ .fileDescriptorForReading;
}
- (bool)hasDataInReadBuffer
{
- return (super.hasDataInReadBuffer || _socket.hasDataInReadBuffer);
+ return (super.hasDataInReadBuffer || _stream.hasDataInReadBuffer);
}
- (void)close
{
- if (_socket == nil)
+ if (_stream == nil)
@throw [OFNotOpenException exceptionWithObject: self];
_atEndOfStream = false;
- [_socket release];
- _socket = nil;
+ [_stream release];
+ _stream = nil;
[super close];
}
@end
@@ -1132,19 +1152,30 @@
didPerformRequest: request
response: response
exception: nil];
}
-- (void)client: (OFHTTPClient *)client
- didCreateSocket: (OFTCPSocket *)sock
- request: (OFHTTPRequest *)request
+- (void)client: (OFHTTPClient *)client
+ didCreateTCPSocket: (OFTCPSocket *)TCPSocket
+ request: (OFHTTPRequest *)request
+{
+ if ([_delegate respondsToSelector:
+ @selector(client:didCreateTCPSocket:request:)])
+ [_delegate client: client
+ didCreateTCPSocket: TCPSocket
+ request: request];
+}
+
+- (void)client: (OFHTTPClient *)client
+ didCreateTLSStream: (OFTLSStream *)TLSStream
+ request: (OFHTTPRequest *)request
{
if ([_delegate respondsToSelector:
- @selector(client:didCreateSocket:request:)])
- [_delegate client: client
- didCreateSocket: sock
- request: request];
+ @selector(client:didCreateTLSStream:request:)])
+ [_delegate client: client
+ didCreateTLSStream: TLSStream
+ request: request];
}
- (void)client: (OFHTTPClient *)client
wantsRequestBody: (OFStream *)body
request: (OFHTTPRequest *)request
@@ -1255,15 +1286,15 @@
objc_autoreleasePoolPop(pool);
}
- (void)close
{
- [_socket release];
- _socket = nil;
+ [_stream release];
+ _stream = nil;
[_lastURL release];
_lastURL = nil;
[_lastResponse release];
_lastResponse = nil;
}
@end
Index: src/OFHTTPCookie.h
==================================================================
--- src/OFHTTPCookie.h
+++ src/OFHTTPCookie.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFHTTPCookie.m
==================================================================
--- src/OFHTTPCookie.m
+++ src/OFHTTPCookie.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFHTTPCookieManager.h
==================================================================
--- src/OFHTTPCookieManager.h
+++ src/OFHTTPCookieManager.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFHTTPCookieManager.m
==================================================================
--- src/OFHTTPCookieManager.m
+++ src/OFHTTPCookieManager.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFHTTPRequest.h
==================================================================
--- src/OFHTTPRequest.h
+++ src/OFHTTPRequest.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -107,17 +107,10 @@
*
* @note The setter creates a copy of the remote address.
*/
@property OF_NULLABLE_PROPERTY (nonatomic) const OFSocketAddress *remoteAddress;
-/**
- * @brief Creates a new OFHTTPRequest.
- *
- * @return A new, autoreleased OFHTTPRequest
- */
-+ (instancetype)request;
-
/**
* @brief Creates a new OFHTTPRequest with the specified URL.
*
* @param URL The URL for the request
* @return A new, autoreleased OFHTTPRequest
@@ -129,10 +122,12 @@
*
* @param URL The URL for the request
* @return An initialized OFHTTPRequest
*/
- (instancetype)initWithURL: (OFURL *)URL;
+
+- (instancetype)init OF_UNAVAILABLE;
@end
#ifdef __cplusplus
extern "C" {
#endif
Index: src/OFHTTPRequest.m
==================================================================
--- src/OFHTTPRequest.m
+++ src/OFHTTPRequest.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -78,44 +78,36 @@
}
@implementation OFHTTPRequest
@synthesize URL = _URL, method = _method, headers = _headers;
-+ (instancetype)request
-{
- return [[[self alloc] init] autorelease];
-}
-
+ (instancetype)requestWithURL: (OFURL *)URL
{
return [[[self alloc] initWithURL: URL] autorelease];
}
-- (instancetype)init
+- (instancetype)initWithURL: (OFURL *)URL
{
self = [super init];
- _method = OFHTTPRequestMethodGet;
- _protocolVersion.major = 1;
- _protocolVersion.minor = 1;
-
- return self;
-}
-
-- (instancetype)initWithURL: (OFURL *)URL
-{
- self = [self init];
-
@try {
_URL = [URL copy];
+ _method = OFHTTPRequestMethodGet;
+ _protocolVersion.major = 1;
+ _protocolVersion.minor = 1;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
+
+- (instancetype)init
+{
+ OF_INVALID_INIT_METHOD
+}
- (void)dealloc
{
[_URL release];
[_headers release];
@@ -139,16 +131,15 @@
return NULL;
}
- (id)copy
{
- OFHTTPRequest *copy = [[OFHTTPRequest alloc] init];
+ OFHTTPRequest *copy = [[OFHTTPRequest alloc] initWithURL: _URL];
@try {
copy->_method = _method;
copy->_protocolVersion = _protocolVersion;
- copy.URL = _URL;
copy.headers = _headers;
copy.remoteAddress = self.remoteAddress;
} @catch (id e) {
[copy release];
@throw e;
Index: src/OFHTTPResponse.h
==================================================================
--- src/OFHTTPResponse.h
+++ src/OFHTTPResponse.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -22,11 +22,11 @@
@class OFArray OF_GENERIC(ObjectType);
/**
* @class OFHTTPResponse OFHTTPResponse.h ObjFW/OFHTTPResponse.h
*
- * @brief A class for representing an HTTP request reply as a stream.
+ * @brief A class for representing an HTTP request response as a stream.
*/
@interface OFHTTPResponse: OFStream
{
OFHTTPRequestProtocolVersion _protocolVersion;
short _statusCode;
@@ -33,42 +33,45 @@
OFDictionary OF_GENERIC(OFString *, OFString *) *_headers;
OF_RESERVE_IVARS(OFHTTPResponse, 4)
}
/**
- * @brief The protocol version of the HTTP request reply.
+ * @brief The protocol version of the HTTP request response.
*/
@property (nonatomic) OFHTTPRequestProtocolVersion protocolVersion;
/**
- * @brief The protocol version of the HTTP request reply as a string.
+ * @brief The protocol version of the HTTP request response as a string.
*/
@property (copy, nonatomic) OFString *protocolVersionString;
/**
- * @brief The status code of the reply to the HTTP request.
+ * @brief The status code of the response to the HTTP request.
*/
@property (nonatomic) short statusCode;
/**
- * @brief The headers of the reply to the HTTP request.
+ * @brief The headers of the response to the HTTP request.
*/
@property (copy, nonatomic) OFDictionary OF_GENERIC(OFString *, OFString *)
*headers;
/**
- * @brief The reply as a string, trying to detect the encoding.
+ * @brief Read the response as a string, trying to detect the encoding and
+ * falling back to the specified encoding if not detectable.
+ *
+ * @return The response as a string
*/
-@property (readonly, nonatomic) OFString *string;
+- (OFString *)readString;
/**
- * @brief Returns the reply as a string, trying to detect the encoding and
+ * @brief Rread the response as a string, trying to detect the encoding and
* falling back to the specified encoding if not detectable.
*
- * @return The reply as a string
+ * @return The response as a string
*/
-- (OFString *)stringWithEncoding: (OFStringEncoding)encoding;
+- (OFString *)readStringWithEncoding: (OFStringEncoding)encoding;
@end
#ifdef __cplusplus
extern "C" {
#endif
Index: src/OFHTTPResponse.m
==================================================================
--- src/OFHTTPResponse.m
+++ src/OFHTTPResponse.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -294,16 +294,16 @@
return [OFString stringWithFormat: @"%hhu.%hhu",
_protocolVersion.major,
_protocolVersion.minor];
}
-- (OFString *)string
+- (OFString *)readString
{
- return [self stringWithEncoding: OFStringEncodingAutodetect];
+ return [self readStringWithEncoding: OFStringEncodingAutodetect];
}
-- (OFString *)stringWithEncoding: (OFStringEncoding)encoding
+- (OFString *)readStringWithEncoding: (OFStringEncoding)encoding
{
void *pool = objc_autoreleasePoolPush();
OFString *contentType, *contentLengthString, *ret;
OFData *data;
Index: src/OFHTTPServer.h
==================================================================
--- src/OFHTTPServer.h
+++ src/OFHTTPServer.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -62,11 +62,12 @@
*/
- (bool)server: (OFHTTPServer *)server
didReceiveExceptionOnListeningSocket: (id)exception;
/**
- * @brief This method is called when a client socket encountered an exception.
+ * @brief This method is called when a socket for a client encountered an
+ * exception.
*
* This can happen when the OFHTTPServer tries to properly close the
* connection. If no headers have been sent yet, it will send headers, and if
* chunked transfer encoding was used, it will send a chunk of size 0. However,
* if the other end already closed the connection before that, this will raise
@@ -91,13 +92,10 @@
OF_SUBCLASSING_RESTRICTED
@interface OFHTTPServer: OFObject
{
OFString *_Nullable _host;
uint16_t _port;
- bool _usesTLS;
- OFString *_Nullable _certificateFile, *_Nullable _privateKeyFile;
- const char *_Nullable _privateKeyPassphrase;
id _Nullable _delegate;
OFString *_Nullable _name;
OFTCPSocket *_Nullable _listeningSocket;
#ifdef OF_HAVE_THREADS
size_t _numberOfThreads, _nextThreadIndex;
@@ -119,46 +117,10 @@
* Setting this after @ref start has been called raises an
* @ref OFAlreadyConnectedException.
*/
@property (nonatomic) uint16_t port;
-/**
- * @brief Whether the HTTP server uses TLS.
- *
- * Setting this after @ref start has been called raises an
- * @ref OFAlreadyConnectedException.
- */
-@property (nonatomic) bool usesTLS;
-
-/**
- * @brief The path to the X.509 certificate file to use for TLS.
- *
- * Setting this after @ref start has been called raises an
- * @ref OFAlreadyConnectedException.
- */
-@property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *certificateFile;
-
-/**
- * @brief The path to the PKCS#8 private key file to use for TLS.
- *
- * Setting this after @ref start has been called raises an
- * @ref OFAlreadyConnectedException.
- */
-@property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *privateKeyFile;
-
-/**
- * @brief The passphrase to decrypt the PKCS#8 private key file for TLS.
- *
- * @warning You have to ensure that this is in secure memory protected from
- * swapping! This is also the reason why this is not an OFString.
- *
- * Setting this after @ref start has been called raises an
- * @ref OFAlreadyConnectedException.
- */
-@property OF_NULLABLE_PROPERTY (assign, nonatomic)
- const char *privateKeyPassphrase;
-
/**
* @brief The delegate for the HTTP server.
*/
@property OF_NULLABLE_PROPERTY (assign, nonatomic)
id delegate;
Index: src/OFHTTPServer.m
==================================================================
--- src/OFHTTPServer.m
+++ src/OFHTTPServer.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
@@ -13,10 +13,11 @@
* file.
*/
#include "config.h"
+#include
#include
#include
#import "OFHTTPServer.h"
#import "OFArray.h"
@@ -26,11 +27,10 @@
#import "OFHTTPRequest.h"
#import "OFHTTPResponse.h"
#import "OFNumber.h"
#import "OFSocket+Private.h"
#import "OFTCPSocket.h"
-#import "OFTLSSocket.h"
#import "OFThread.h"
#import "OFTimer.h"
#import "OFURL.h"
#import "OFAlreadyConnectedException.h"
@@ -114,16 +114,17 @@
@interface OFHTTPServerThread: OFThread
- (void)stop;
@end
#endif
-static OF_INLINE OFString *
+static OFString *
normalizedKey(OFString *key)
{
char *cString = OFStrDup(key.UTF8String);
unsigned char *tmp = (unsigned char *)cString;
bool firstLetter = true;
+ OFString *ret;
while (*tmp != '\0') {
if (!OFASCIIIsAlpha(*tmp)) {
firstLetter = true;
tmp++;
@@ -136,16 +137,18 @@
firstLetter = false;
tmp++;
}
@try {
- return [OFString stringWithUTF8StringNoCopy: cString
- freeWhenDone: true];
+ ret = [OFString stringWithUTF8StringNoCopy: cString
+ freeWhenDone: true];
} @catch (id e) {
OFFreeMemory(cString);
@throw e;
}
+
+ return ret;
}
@implementation OFHTTPServerResponse
- (instancetype)initWithSocket: (OFStreamSocket *)sock
server: (OFHTTPServer *)server
@@ -223,12 +226,22 @@
@throw [OFNotOpenException exceptionWithObject: self];
if (!_headersSent)
[self of_sendHeaders];
- if (!_chunked)
- return [_socket writeBuffer: buffer length: length];
+ if (!_chunked) {
+ @try {
+ [_socket writeBuffer: buffer length: length];
+ } @catch (OFWriteFailedException *e) {
+ if (e.errNo == EWOULDBLOCK || e.errNo == EAGAIN)
+ return e.bytesWritten;
+
+ @throw e;
+ }
+
+ return length;
+ }
pool = objc_autoreleasePoolPush();
[_socket writeString: [OFString stringWithFormat: @"%zX\r\n", length]];
objc_autoreleasePoolPop(pool);
@@ -523,20 +536,27 @@
URL.scheme = @"http";
URL.host = _host;
if (_port != 80)
URL.port = [OFNumber numberWithUnsignedShort: _port];
- if ((pos = [_path rangeOfString: @"?"].location) != OFNotFound) {
- OFString *path, *query;
-
- path = [_path substringToIndex: pos];
- query = [_path substringFromIndex: pos + 1];
-
- URL.URLEncodedPath = path;
- URL.URLEncodedQuery = query;
- } else
- URL.URLEncodedPath = _path;
+ @try {
+ if ((pos = [_path rangeOfString: @"?"].location) !=
+ OFNotFound) {
+ OFString *path, *query;
+
+ path = [_path substringToIndex: pos];
+ query = [_path substringFromIndex: pos + 1];
+
+ URL.URLEncodedPath = path;
+ URL.URLEncodedQuery = query;
+ } else
+ URL.URLEncodedPath = _path;
+ } @catch (OFInvalidFormatException *e) {
+ objc_autoreleasePoolPop(pool);
+ [self sendErrorAndClose: 400];
+ return;
+ }
[URL makeImmutable];
request = [OFHTTPRequest requestWithURL: URL];
request.method = _method;
@@ -806,70 +826,10 @@
- (uint16_t)port
{
return _port;
}
-- (void)setUsesTLS: (bool)usesTLS
-{
- if (_listeningSocket != nil)
- @throw [OFAlreadyConnectedException exception];
-
- _usesTLS = usesTLS;
-}
-
-- (bool)usesTLS
-{
- return _usesTLS;
-}
-
-- (void)setCertificateFile: (OFString *)certificateFile
-{
- OFString *old;
-
- if (_listeningSocket != nil)
- @throw [OFAlreadyConnectedException exception];
-
- old = _certificateFile;
- _certificateFile = [certificateFile copy];
- [old release];
-}
-
-- (OFString *)certificateFile
-{
- return _certificateFile;
-}
-
-- (void)setPrivateKeyFile: (OFString *)privateKeyFile
-{
- OFString *old;
-
- if (_listeningSocket != nil)
- @throw [OFAlreadyConnectedException exception];
-
- old = _privateKeyFile;
- _privateKeyFile = [privateKeyFile copy];
- [old release];
-}
-
-- (OFString *)privateKeyFile
-{
- return _privateKeyFile;
-}
-
-- (void)setPrivateKeyPassphrase: (const char *)privateKeyPassphrase
-{
- if (_listeningSocket != nil)
- @throw [OFAlreadyConnectedException exception];
-
- _privateKeyPassphrase = privateKeyPassphrase;
-}
-
-- (const char *)privateKeyPassphrase
-{
- return _privateKeyPassphrase;
-}
-
#ifdef OF_HAVE_THREADS
- (void)setNumberOfThreads: (size_t)numberOfThreads
{
if (numberOfThreads == 0)
@throw [OFInvalidArgumentException exception];
@@ -894,25 +854,11 @@
@throw [OFInvalidArgumentException exception];
if (_listeningSocket != nil)
@throw [OFAlreadyConnectedException exception];
- if (_usesTLS) {
- OFTCPSocket *TLSSocket;
-
- if (OFTLSSocketClass == Nil)
- @throw [OFUnsupportedProtocolException exception];
-
- TLSSocket = [[OFTLSSocketClass alloc] init];
- _listeningSocket = TLSSocket;
-
- TLSSocket.certificateFile = _certificateFile;
- TLSSocket.privateKeyFile = _privateKeyFile;
- TLSSocket.privateKeyPassphrase = _privateKeyPassphrase;
- } else
- _listeningSocket = [[OFTCPSocket alloc] init];
-
+ _listeningSocket = [[OFTCPSocket alloc] init];
_port = [_listeningSocket bindToHost: _host port: _port];
[_listeningSocket listen];
#ifdef OF_HAVE_THREADS
if (_numberOfThreads > 1) {
Index: src/OFHTTPURLHandler.h
==================================================================
--- src/OFHTTPURLHandler.h
+++ src/OFHTTPURLHandler.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer
+ * 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
Index: src/OFHTTPURLHandler.m
==================================================================
--- src/OFHTTPURLHandler.m
+++ src/OFHTTPURLHandler.m
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008-2021 Jonathan Schleifer