mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
Merge branch 'master' into android-assets-directory-improvements
This commit is contained in:
commit
daadfe7a6d
18 changed files with 328 additions and 191 deletions
202
.travis.yml
202
.travis.yml
|
@ -1,73 +1,141 @@
|
|||
---
|
||||
os: linux
|
||||
language: cpp
|
||||
dist: xenial
|
||||
compiler:
|
||||
- clang
|
||||
- gcc
|
||||
env:
|
||||
- LIBRARY_COMBO=gnu-gnu-gnu
|
||||
- LIBRARY_COMBO=ng-gnu-gnu RUNTIME_VERSION=gnustep-1.9
|
||||
- LIBRARY_COMBO=ng-gnu-gnu BASE_ABI=--disable-mixedabi RUNTIME_VERSION=gnustep-1.9
|
||||
- LIBRARY_COMBO=ng-gnu-gnu RUNTIME_VERSION=gnustep-2.0
|
||||
- LIBRARY_COMBO=ng-gnu-gnu BASE_ABI=--disable-mixedabi RUNTIME_VERSION=gnustep-2.0
|
||||
jobs:
|
||||
exclude:
|
||||
- compiler: gcc
|
||||
env: LIBRARY_COMBO=ng-gnu-gnu RUNTIME_VERSION=gnustep-1.9
|
||||
- compiler: gcc
|
||||
env: LIBRARY_COMBO=ng-gnu-gnu BASE_ABI=--disable-mixedabi RUNTIME_VERSION=gnustep-1.9
|
||||
- compiler: gcc
|
||||
env: LIBRARY_COMBO=ng-gnu-gnu RUNTIME_VERSION=gnustep-2.0
|
||||
- compiler: gcc
|
||||
env: LIBRARY_COMBO=ng-gnu-gnu BASE_ABI=--disable-mixedabi RUNTIME_VERSION=gnustep-2.0
|
||||
- compiler: clang
|
||||
include:
|
||||
- name: "Linux GCC"
|
||||
os: linux
|
||||
compiler: gcc
|
||||
env: LIBRARY_COMBO=gnu-gnu-gnu
|
||||
before_install:
|
||||
- sudo apt-get -qq update
|
||||
- sudo apt-get install -y cmake pkg-config libgnutls28-dev libgmp-dev libffi-dev libicu-dev libxml2-dev libxslt1-dev libssl-dev libavahi-client-dev zlib1g-dev
|
||||
- >
|
||||
if [ $LIBRARY_COMBO = 'gnu-gnu-gnu' ];
|
||||
then
|
||||
if [ $CC = 'gcc' ];
|
||||
then
|
||||
sudo apt-get install -y gobjc;
|
||||
fi;
|
||||
sudo apt-get install -y libobjc-4.8-dev libblocksruntime-dev;
|
||||
else
|
||||
curl -s -o - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -;
|
||||
sudo apt-add-repository "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main" && sudo apt-get update -qq;
|
||||
sudo apt-get install -y clang-9 libkqueue-dev libpthread-workqueue-dev;
|
||||
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-9 10 \
|
||||
--slave /usr/bin/clang++ clang++ /usr/bin/clang++-9;
|
||||
export PATH=$(echo "$PATH" | sed -e 's/:\/usr\/local\/clang-7.0.0\/bin//');
|
||||
if [ "$RUNTIME_VERSION" = "gnustep-2.0" ];
|
||||
then
|
||||
sudo update-alternatives --install "/usr/bin/ld" "ld" "/usr/bin/ld.gold" 10;
|
||||
fi;
|
||||
fi;
|
||||
# libdispatch requires a fairly recent version of cmake
|
||||
- >
|
||||
if [ $LIBRARY_COMBO = 'ng-gnu-gnu' ];
|
||||
then
|
||||
curl -LO https://cmake.org/files/v3.15/cmake-3.15.5-Linux-x86_64.tar.gz;
|
||||
tar xf cmake-3.15.5-Linux-x86_64.tar.gz;
|
||||
mv cmake-3.15.5-Linux-x86_64 $HOME/cmake;
|
||||
export PATH=$HOME/cmake/:$HOME/cmake/bin:$PATH
|
||||
fi;
|
||||
- name: "Linux Clang gnustep-1.9"
|
||||
os: linux
|
||||
compiler: clang
|
||||
env: LIBRARY_COMBO=ng-gnu-gnu RUNTIME_VERSION=gnustep-1.9
|
||||
- name: "Linux Clang gnustep-1.9 disable-mixedabi"
|
||||
os: linux
|
||||
compiler: clang
|
||||
env: LIBRARY_COMBO=ng-gnu-gnu RUNTIME_VERSION=gnustep-1.9 BASE_ABI=--disable-mixedabi
|
||||
- name: "Linux Clang gnustep-2.0"
|
||||
os: linux
|
||||
compiler: clang
|
||||
env: LIBRARY_COMBO=ng-gnu-gnu RUNTIME_VERSION=gnustep-2.0
|
||||
- name: "Linux Clang gnustep-2.0 disable-mixedabi"
|
||||
os: linux
|
||||
compiler: clang
|
||||
env: LIBRARY_COMBO=ng-gnu-gnu RUNTIME_VERSION=gnustep-2.0 BASE_ABI=--disable-mixedabi
|
||||
- name: "Windows GCC MinGW-w64 i686"
|
||||
os: windows
|
||||
compiler: gcc
|
||||
env: LIBRARY_COMBO=gnu-gnu-gnu MSYSTEM=mingw32 ARCH=i686
|
||||
- name: "Windows GCC MinGW-w64 x86_64"
|
||||
os: windows
|
||||
compiler: gcc
|
||||
env: LIBRARY_COMBO=gnu-gnu-gnu MSYSTEM=mingw64 ARCH=x86_64
|
||||
# allow Windows builds to fail (remove once all tests are passing on Windows)
|
||||
allow_failures:
|
||||
- os: windows
|
||||
before_install: |
|
||||
case $TRAVIS_OS_NAME in
|
||||
linux)
|
||||
sudo apt-get -qq update
|
||||
sudo apt-get install -y cmake pkg-config libgnutls28-dev libgmp-dev libffi-dev libicu-dev libxml2-dev libxslt1-dev libssl-dev libavahi-client-dev zlib1g-dev
|
||||
case $LIBRARY_COMBO in
|
||||
gnu-gnu-gnu)
|
||||
if [ $CC = 'gcc' ]; then
|
||||
sudo apt-get install -y gobjc
|
||||
fi
|
||||
sudo apt-get install -y libobjc-4.8-dev libblocksruntime-dev
|
||||
;;
|
||||
ng-gnu-gnu)
|
||||
curl -s -o - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
|
||||
sudo apt-add-repository "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main" && sudo apt-get update -qq
|
||||
sudo apt-get install -y clang-9 libkqueue-dev libpthread-workqueue-dev
|
||||
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-9 10 \
|
||||
--slave /usr/bin/clang++ clang++ /usr/bin/clang++-9
|
||||
export PATH=$(echo "$PATH" | sed -e 's/:\/usr\/local\/clang-7.0.0\/bin//')
|
||||
if [ "$RUNTIME_VERSION" = "gnustep-2.0" ]; then
|
||||
sudo update-alternatives --install "/usr/bin/ld" "ld" "/usr/bin/ld.gold" 10
|
||||
fi;
|
||||
## libdispatch requires a fairly recent version of cmake
|
||||
curl -LO https://cmake.org/files/v3.15/cmake-3.15.5-Linux-x86_64.tar.gz
|
||||
tar xf cmake-3.15.5-Linux-x86_64.tar.gz
|
||||
mv cmake-3.15.5-Linux-x86_64 $HOME/cmake
|
||||
export PATH=$HOME/cmake/:$HOME/cmake/bin:$PATH
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
windows)
|
||||
## from https://docs.travis-ci.com/user/reference/windows/#how-do-i-use-msys2
|
||||
[[ ! -f C:/tools/msys64/msys2_shell.cmd ]] && rm -rf C:/tools/msys64
|
||||
choco uninstall -y mingw
|
||||
choco upgrade --no-progress -y msys2
|
||||
export msys2='cmd //C RefreshEnv.cmd '
|
||||
export msys2+='& set MSYS=winsymlinks:nativestrict '
|
||||
export msys2+='& C:\\tools\\msys64\\msys2_shell.cmd -defterm -no-start'
|
||||
export mingw="$msys2 -$MSYSTEM -full-path -here -c "\"\$@"\" --"
|
||||
export msys2+=" -msys2 -c "\"\$@"\" --"
|
||||
## Install MSYS2 packages required by GNUstep
|
||||
$msys2 pacman --sync --noconfirm --needed \
|
||||
mingw-w64-$ARCH-gcc-objc \
|
||||
make \
|
||||
pkg-config \
|
||||
libxml2-devel \
|
||||
libxslt-devel \
|
||||
libffi-devel \
|
||||
libgnutls-devel \
|
||||
icu-devel \
|
||||
mingw-w64-$ARCH-pkg-config \
|
||||
mingw-w64-$ARCH-libxml2 \
|
||||
mingw-w64-$ARCH-libxslt \
|
||||
mingw-w64-$ARCH-libffi \
|
||||
mingw-w64-$ARCH-gnutls \
|
||||
mingw-w64-$ARCH-icu \
|
||||
##
|
||||
taskkill //IM gpg-agent.exe //F # https://travis-ci.community/t/4967
|
||||
export PATH=/C/tools/msys64/$MSYSTEM/bin:$PATH
|
||||
## disable conversion to native-form paths when configuring GNUstep Make in travis-deps.sh
|
||||
## https://www.msys2.org/wiki/Porting/#filesystem-namespaces
|
||||
export MSYS2_ARG_CONV_EXCL="--prefix="
|
||||
;;
|
||||
esac
|
||||
install: ./travis-deps.sh
|
||||
before_script: >
|
||||
export LIBRARY_PATH=$HOME/staging/lib:$HOME/staging/lib64:$LIBRARY_PATH;
|
||||
export LD_LIBRARY_PATH=$HOME/staging/lib:$HOME/staging/lib64:$LD_LIBRARY_PATH;
|
||||
if [ $LIBRARY_COMBO = 'ng-gnu-gnu' ];
|
||||
then
|
||||
export CPATH=$HOME/staging/include;
|
||||
else
|
||||
export CPATH=/usr/lib/gcc/x86_64-linux-gnu/4.8/include;
|
||||
fi;
|
||||
export PATH=$HOME/staging/bin:$PATH;
|
||||
export GNUSTEP_MAKEFILES=$HOME/staging/share/GNUstep/Makefiles;
|
||||
. $HOME/staging/share/GNUstep/Makefiles/GNUstep.sh;
|
||||
script: >
|
||||
./configure $BASE_ABI || (cat config.log && false);
|
||||
make && make install && make check || (cat Tests/tests.log && false);
|
||||
before_script: |
|
||||
case $TRAVIS_OS_NAME in
|
||||
linux)
|
||||
DEP_ROOT=$HOME/staging
|
||||
export PATH=$DEP_ROOT/bin:$PATH
|
||||
;;
|
||||
windows)
|
||||
DEP_ROOT=/c/staging
|
||||
setx -m PATH "C:\staging;%PATH%"
|
||||
;;
|
||||
esac
|
||||
export LIBRARY_PATH=$DEP_ROOT/lib:$DEP_ROOT/lib64:$LIBRARY_PATH
|
||||
export LD_LIBRARY_PATH=$DEP_ROOT/lib:$DEP_ROOT/lib64:$LD_LIBRARY_PATH
|
||||
case $LIBRARY_COMBO in
|
||||
gnu-gnu-gnu)
|
||||
export CPATH=/usr/lib/gcc/x86_64-linux-gnu/4.8/include
|
||||
;;
|
||||
ng-gnu-gnu)
|
||||
export CPATH=$DEP_ROOT/include
|
||||
;;
|
||||
esac
|
||||
export GNUSTEP_MAKEFILES=$DEP_ROOT/share/GNUstep/Makefiles
|
||||
. $GNUSTEP_MAKEFILES/GNUstep.sh
|
||||
script:
|
||||
# configure and make need to be executed via MinGW shell on Windows ($mingw is undefined on Linux)
|
||||
- $mingw ./configure $BASE_ABI || (cat config.log && false)
|
||||
- $mingw make && $mingw make install && $mingw make check || (cat Tests/tests.log && false)
|
||||
|
||||
# set up packages cache (currently used on Windows only)
|
||||
before_cache: |
|
||||
case $TRAVIS_OS_NAME in
|
||||
windows)
|
||||
# https://unix.stackexchange.com/a/137322/107554
|
||||
$msys2 pacman --sync --clean --noconfirm
|
||||
;;
|
||||
esac
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/AppData/Local/Temp/chocolatey
|
||||
- /C/tools/msys64
|
||||
|
|
30
ChangeLog
30
ChangeLog
|
@ -1,9 +1,29 @@
|
|||
2020-05-20 Frederik Seiffert <frederik@algoriddim.com>
|
||||
2020-06-06 Frederik Seiffert <frederik@algoriddim.com>
|
||||
|
||||
* Source/NSBundle.m: Extend NSBundle resources support to handle
|
||||
directories in Android assets.
|
||||
* Source/NSFileManager.m: Fix NSFileManager -isReadableFileAtPath:
|
||||
to also support directories in Android assets.
|
||||
* Source/NSBundle.m: Extend NSBundle resources support to handle
|
||||
directories in Android assets.
|
||||
* Source/NSFileManager.m: Fix NSFileManager -isReadableFileAtPath:
|
||||
to also support directories in Android assets.
|
||||
|
||||
2020-06-05 Frederik Seiffert <frederik@algoriddim.com>
|
||||
|
||||
* Tests/base/NSMapTable/weakObjects.m,
|
||||
* Source/NSConcreteMapTable.m:
|
||||
Add test for and fix replacing an existing value in a weak objects map
|
||||
table.
|
||||
|
||||
2020-05-25 Frederik Seiffert <frederik@algoriddim.com>
|
||||
|
||||
* Source/NSUserDefaults.m:
|
||||
Store NSNumber instead of NSString for NSUserDefaults -setBool:forKey:.
|
||||
|
||||
2020-05-23 Frederik Seiffert <frederik@algoriddim.com>
|
||||
|
||||
* Headers/GNUstepBase/GSConfig.h.in,
|
||||
* Source/GSNetwork.h,
|
||||
* Source/win32/GSFileHandle.m,
|
||||
* config/config.reuseaddr.c:
|
||||
Include winsock2.h before windows.h, as required by MSYS2/MinGW-w64.
|
||||
|
||||
2020-05-14 Frederik Seiffert <frederik@algoriddim.com>
|
||||
|
||||
|
|
|
@ -59,7 +59,9 @@
|
|||
* implementation of longjmp in mingw-w64 sometimes crashes in msvcrt.dll
|
||||
* but the builtin version provided by gcc seems to work.
|
||||
*/
|
||||
#undef setjmp
|
||||
#define setjmp(X) __builtin_setjmp(X)
|
||||
#undef longjmp
|
||||
#define longjmp(X,Y) __builtin_longjmp(X,Y)
|
||||
#endif
|
||||
|
||||
|
|
|
@ -39,11 +39,16 @@ DEFINE_BLOCK_TYPE(GSFilePresentedItemChangesWithCompletionHandler, void, NSError
|
|||
|
||||
@protocol NSFilePresenter <NSObject>
|
||||
|
||||
// @required
|
||||
- (NSURL *) presentedItemURL;
|
||||
- (NSOperationQueue *) presentedItemOperationQueue;
|
||||
|
||||
// @optional
|
||||
#if GS_PROTOCOLS_HAVE_OPTIONAL
|
||||
@optional
|
||||
#else
|
||||
@end
|
||||
@interface NSObject (NSFilePresenter)
|
||||
#endif
|
||||
|
||||
- (NSURL *) primaryPresentedItemURL;
|
||||
- (NSString *) observedPresentedItemUbiquityAttributes;
|
||||
|
||||
|
|
|
@ -306,12 +306,17 @@ typedef struct {
|
|||
#define WINVER Windows2000
|
||||
#endif
|
||||
|
||||
#if defined(__WIN64__)
|
||||
#include <winsock2.h>
|
||||
// Trick to distinguish between MSYS/MinGW and MSYS2/MinGW32, the latter defines
|
||||
// __MINGW32_MAJOR_VERSION and __MINGW32_MINOR_VERSION for compatibility
|
||||
// but to a lower version than older MSYS/MinGW, but not the compound version
|
||||
//
|
||||
#if defined(__MINGW32_VERSION)
|
||||
#define __USE_W32_SOCKETS
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#undef __OBJC_BOOL
|
||||
|
|
|
@ -40,12 +40,8 @@
|
|||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#if defined(__WIN64__)
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#include <io.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <wininet.h>
|
||||
#if !defined(EAFNOSUPPORT)
|
||||
|
|
|
@ -1392,7 +1392,7 @@ const NSMapTableValueCallBacks NSOwnedPointerMapValueCallBacks =
|
|||
if (GSI_MAP_READ_VALUE(self, &node->value).obj != anObject)
|
||||
{
|
||||
GSI_MAP_RELEASE_VAL(self, node->value);
|
||||
node->value.obj = anObject;
|
||||
GSI_MAP_WRITE_VAL(self, &node->value, (GSIMapVal)anObject);
|
||||
GSI_MAP_RETAIN_VAL(self, node->value);
|
||||
version++;
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ static NSArray *empty = nil;
|
|||
+ (void) initialize
|
||||
{
|
||||
empty = [NSArray new];
|
||||
[[NSObject leakAt: &empty] release];
|
||||
RELEASE([NSObject leakAt: &empty]);
|
||||
}
|
||||
|
||||
- (void) addDependency: (NSOperation *)op
|
||||
|
@ -430,8 +430,9 @@ static NSArray *empty = nil;
|
|||
|
||||
- (void) start
|
||||
{
|
||||
NSAutoreleasePool *pool = [NSAutoreleasePool new];
|
||||
double prio = [NSThread threadPriority];
|
||||
ENTER_POOL
|
||||
|
||||
double prio = [NSThread threadPriority];
|
||||
|
||||
AUTORELEASE(RETAIN(self)); // Make sure we exist while running.
|
||||
[internal->lock lock];
|
||||
|
@ -486,7 +487,7 @@ static NSArray *empty = nil;
|
|||
NS_ENDHANDLER;
|
||||
|
||||
[self _finish];
|
||||
[pool release];
|
||||
LEAVE_POOL
|
||||
}
|
||||
|
||||
- (double) threadPriority
|
||||
|
@ -507,7 +508,7 @@ static NSArray *empty = nil;
|
|||
/* retain while finishing so that we don't get deallocated when our
|
||||
* queue removes and releases us.
|
||||
*/
|
||||
[self retain];
|
||||
RETAIN(self);
|
||||
[internal->lock lock];
|
||||
if (NO == internal->finished)
|
||||
{
|
||||
|
@ -532,7 +533,7 @@ static NSArray *empty = nil;
|
|||
}
|
||||
}
|
||||
[internal->lock unlock];
|
||||
[self release];
|
||||
RELEASE(self);
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -540,15 +541,20 @@ static NSArray *empty = nil;
|
|||
|
||||
@implementation NSBlockOperation
|
||||
|
||||
// Initialize
|
||||
- (id) init
|
||||
+ (instancetype) blockOperationWithBlock: (GSBlockOperationBlock)block
|
||||
{
|
||||
self = [super init];
|
||||
if(self != nil)
|
||||
{
|
||||
_executionBlocks = [[NSMutableArray alloc] initWithCapacity: 1];
|
||||
}
|
||||
return self;
|
||||
NSBlockOperation *op = [[self alloc] init];
|
||||
|
||||
[op addExecutionBlock: block];
|
||||
return AUTORELEASE(op);
|
||||
}
|
||||
|
||||
- (void) addExecutionBlock: (GSBlockOperationBlock)block
|
||||
{
|
||||
GSBlockOperationBlock blockCopy = [block copy];
|
||||
|
||||
[_executionBlocks addObject: blockCopy];
|
||||
RELEASE(blockCopy);
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
|
@ -557,29 +563,27 @@ static NSArray *empty = nil;
|
|||
[super dealloc];
|
||||
}
|
||||
|
||||
// Managing the blocks in the Operation
|
||||
+ (instancetype)blockOperationWithBlock: (GSBlockOperationBlock)block
|
||||
{
|
||||
NSBlockOperation *op = [[self alloc] init];
|
||||
[op addExecutionBlock: block];
|
||||
return op;
|
||||
}
|
||||
|
||||
- (void)addExecutionBlock: (GSBlockOperationBlock)block
|
||||
{
|
||||
[_executionBlocks addObject: block];
|
||||
}
|
||||
|
||||
- (NSArray *) executionBlocks
|
||||
{
|
||||
return _executionBlocks;
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
self = [super init];
|
||||
if (self != nil)
|
||||
{
|
||||
_executionBlocks = [[NSMutableArray alloc] initWithCapacity: 1];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) main
|
||||
{
|
||||
NSEnumerator *en = [[self executionBlocks] objectEnumerator];
|
||||
NSEnumerator *en = [[self executionBlocks] objectEnumerator];
|
||||
GSBlockOperationBlock theBlock;
|
||||
while((theBlock = [en nextObject]) != NULL)
|
||||
|
||||
while ((theBlock = [en nextObject]) != NULL)
|
||||
{
|
||||
CALL_BLOCK_NO_ARGS(theBlock);
|
||||
}
|
||||
|
@ -836,9 +840,9 @@ static NSOperationQueue *mainQueue = nil;
|
|||
internal->name
|
||||
= [[NSString alloc] initWithFormat: @"NSOperation %p", self];
|
||||
}
|
||||
s = [internal->name retain];
|
||||
s = RETAIN(internal->name);
|
||||
[internal->lock unlock];
|
||||
return [s autorelease];
|
||||
return AUTORELEASE(s);
|
||||
}
|
||||
|
||||
- (NSUInteger) operationCount
|
||||
|
@ -888,7 +892,7 @@ static NSOperationQueue *mainQueue = nil;
|
|||
if (NO == [internal->name isEqual: s])
|
||||
{
|
||||
[self willChangeValueForKey: @"name"];
|
||||
[internal->name release];
|
||||
RELEASE(internal->name);
|
||||
internal->name = [s copy];
|
||||
[self didChangeValueForKey: @"name"];
|
||||
}
|
||||
|
@ -915,10 +919,10 @@ static NSOperationQueue *mainQueue = nil;
|
|||
[internal->lock lock];
|
||||
while ((op = [internal->operations lastObject]) != nil)
|
||||
{
|
||||
[op retain];
|
||||
RETAIN(op);
|
||||
[internal->lock unlock];
|
||||
[op waitUntilFinished];
|
||||
[op release];
|
||||
RELEASE(op);
|
||||
[internal->lock lock];
|
||||
}
|
||||
[internal->lock unlock];
|
||||
|
@ -979,7 +983,7 @@ static NSOperationQueue *mainQueue = nil;
|
|||
|
||||
- (void) _thread
|
||||
{
|
||||
NSAutoreleasePool *pool = [NSAutoreleasePool new];
|
||||
ENTER_POOL
|
||||
|
||||
[[[NSThread currentThread] threadDictionary] setObject: self
|
||||
forKey: threadKey];
|
||||
|
@ -1022,11 +1026,10 @@ static NSOperationQueue *mainQueue = nil;
|
|||
{
|
||||
NS_DURING
|
||||
{
|
||||
NSAutoreleasePool *opPool = [NSAutoreleasePool new];
|
||||
|
||||
ENTER_POOL
|
||||
[NSThread setThreadPriority: [op threadPriority]];
|
||||
[op start];
|
||||
RELEASE(opPool);
|
||||
LEAVE_POOL
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
|
@ -1043,7 +1046,7 @@ static NSOperationQueue *mainQueue = nil;
|
|||
[internal->lock lock];
|
||||
internal->threadCount--;
|
||||
[internal->lock unlock];
|
||||
RELEASE(pool);
|
||||
LEAVE_POOL
|
||||
[NSThread exit];
|
||||
}
|
||||
|
||||
|
|
|
@ -1140,7 +1140,7 @@ scalarSize(char type)
|
|||
return;
|
||||
case 4:
|
||||
*(int32_t*)address = (int32_t)big;
|
||||
if (big > 2147483647 || big < -2147483648)
|
||||
if (big > 2147483647 || big + 2147483648 < 0)
|
||||
{
|
||||
NSLog(@"Lost information converting decoded value to int32_t");
|
||||
}
|
||||
|
|
|
@ -763,6 +763,7 @@ GSCurrentThreadDictionary(void)
|
|||
static void
|
||||
gnustep_base_thread_callback(void)
|
||||
{
|
||||
static pthread_mutex_t threadLock = PTHREAD_MUTEX_INITIALIZER;
|
||||
/*
|
||||
* Protect this function with locking ... to avoid any possibility
|
||||
* of multiple threads registering with the system simultaneously,
|
||||
|
@ -771,9 +772,10 @@ gnustep_base_thread_callback(void)
|
|||
*/
|
||||
if (entered_multi_threaded_state == NO)
|
||||
{
|
||||
[gnustep_global_lock lock];
|
||||
pthread_mutex_lock(&threadLock);
|
||||
if (entered_multi_threaded_state == NO)
|
||||
{
|
||||
ENTER_POOL
|
||||
/*
|
||||
* For apple compatibility ... and to make things easier for
|
||||
* code called indirectly within a will-become-multi-threaded
|
||||
|
@ -814,8 +816,9 @@ gnustep_base_thread_callback(void)
|
|||
fflush(stderr);
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
LEAVE_POOL
|
||||
}
|
||||
[gnustep_global_lock unlock];
|
||||
pthread_mutex_unlock(&threadLock);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -860,15 +863,9 @@ unregisterActiveThread(NSThread *thread)
|
|||
{
|
||||
if (thread->_active == YES)
|
||||
{
|
||||
/*
|
||||
* Set the thread to be inactive to avoid any possibility of recursion.
|
||||
*/
|
||||
thread->_active = NO;
|
||||
thread->_finished = YES;
|
||||
|
||||
/*
|
||||
* Let observers know this thread is exiting.
|
||||
/* Let observers know this thread is exiting.
|
||||
*/
|
||||
ENTER_POOL
|
||||
if (nc == nil)
|
||||
{
|
||||
nc = RETAIN([NSNotificationCenter defaultCenter]);
|
||||
|
@ -877,7 +874,14 @@ unregisterActiveThread(NSThread *thread)
|
|||
object: thread
|
||||
userInfo: nil];
|
||||
|
||||
/* Set the thread to be finished *after* notification it will exit.
|
||||
* This is the order OSX 10.15.4 does it (May 2020).
|
||||
*/
|
||||
thread->_active = NO;
|
||||
thread->_finished = YES;
|
||||
|
||||
[(GSRunLoopThreadInfo*)thread->_runLoopInfo invalidate];
|
||||
LEAVE_POOL
|
||||
RELEASE(thread);
|
||||
pthread_setspecific(thread_object_key, nil);
|
||||
}
|
||||
|
|
|
@ -1398,7 +1398,7 @@ scalarSize(char type)
|
|||
return;
|
||||
case 4:
|
||||
*(int32_t*)address = (int32_t)big;
|
||||
if (big > 2147483647 || big < -2147483648)
|
||||
if (big > 2147483647 || big + 2147483648 < 0)
|
||||
{
|
||||
NSLog(@"Lost information converting decoded value to int32_t");
|
||||
}
|
||||
|
|
|
@ -1354,24 +1354,23 @@ newLanguages(NSArray *oldNames)
|
|||
|
||||
- (id) objectForKey: (NSString*)defaultName
|
||||
{
|
||||
NSEnumerator *enumerator;
|
||||
IMP nImp;
|
||||
id object = nil;
|
||||
id dN;
|
||||
IMP pImp;
|
||||
IMP tImp;
|
||||
id object = nil;
|
||||
|
||||
[_lock lock];
|
||||
NS_DURING
|
||||
{
|
||||
enumerator = [_searchList objectEnumerator];
|
||||
nImp = [enumerator methodForSelector: nextObjectSel];
|
||||
object = nil;
|
||||
NSUInteger count = [_searchList count];
|
||||
IMP pImp;
|
||||
IMP tImp;
|
||||
NSUInteger index;
|
||||
GS_BEGINITEMBUF(items, count, NSObject*)
|
||||
|
||||
pImp = [_persDomains methodForSelector: objectForKeySel];
|
||||
tImp = [_tempDomains methodForSelector: objectForKeySel];
|
||||
|
||||
while ((dN = (*nImp)(enumerator, nextObjectSel)) != nil)
|
||||
{
|
||||
[_searchList getObjects: items];
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
NSObject *dN = items[index];
|
||||
GSPersistentDomain *pd;
|
||||
NSDictionary *td;
|
||||
|
||||
|
@ -1383,6 +1382,7 @@ newLanguages(NSArray *oldNames)
|
|||
break;
|
||||
}
|
||||
RETAIN(object);
|
||||
GS_ENDITEMBUF();
|
||||
[_lock unlock];
|
||||
}
|
||||
NS_HANDLER
|
||||
|
@ -1420,14 +1420,9 @@ newLanguages(NSArray *oldNames)
|
|||
|
||||
- (void) setBool: (BOOL)value forKey: (NSString*)defaultName
|
||||
{
|
||||
if (value == YES)
|
||||
{
|
||||
[self setObject: @"YES" forKey: defaultName];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self setObject: @"NO" forKey: defaultName];
|
||||
}
|
||||
NSNumber *n = [NSNumberClass numberWithBool: value];
|
||||
|
||||
[self setObject: n forKey: defaultName];
|
||||
}
|
||||
|
||||
- (void) setDouble: (double)value forKey: (NSString*)defaultName
|
||||
|
|
|
@ -22,15 +22,6 @@
|
|||
Boston, MA 02111 USA.
|
||||
*/
|
||||
|
||||
#if defined(__WIN64__)
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
/* mingw32 wants winsock2.h before windows.h */
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
#define EXPOSE_NSFileHandle_IVARS 1
|
||||
#define EXPOSE_GSFileHandle_IVARS 1
|
||||
|
|
|
@ -19,9 +19,14 @@ int main()
|
|||
|
||||
NSAutoreleasePool *arp2 = [NSAutoreleasePool new];
|
||||
|
||||
id testObj = [[[NSObject alloc] init] autorelease];
|
||||
[mapTable setObject:testObj forKey:@"test"];
|
||||
PASS([mapTable objectForKey:@"test"] != nil, "Table retains active weak reference");
|
||||
id testObj1 = [[[NSObject alloc] init] autorelease];
|
||||
id testObj2 = [[[NSObject alloc] init] autorelease];
|
||||
|
||||
[mapTable setObject:testObj1 forKey:@"test"];
|
||||
PASS([mapTable objectForKey:@"test"] == testObj1, "Table retains first active weak reference");
|
||||
|
||||
[mapTable setObject:testObj2 forKey:@"test"];
|
||||
PASS([mapTable objectForKey:@"test"] == testObj2, "Table retains second active weak reference");
|
||||
|
||||
[arp2 release]; arp2 = nil;
|
||||
|
||||
|
|
|
@ -15,13 +15,13 @@
|
|||
BOOL deallocated;
|
||||
}
|
||||
|
||||
- (void)onThreadExit: (NSNotification*)n;
|
||||
- (BOOL)isDone;
|
||||
- (void) onThreadExit: (NSNotification*)n;
|
||||
- (BOOL) isDone;
|
||||
@end
|
||||
|
||||
@implementation ThreadExpectation
|
||||
|
||||
- (id)init
|
||||
- (id) init
|
||||
{
|
||||
if (nil == (self = [super init]))
|
||||
{
|
||||
|
@ -33,26 +33,36 @@
|
|||
|
||||
|
||||
|
||||
- (void)inThread: (NSThread*)thread
|
||||
- (void) inThread: (NSThread*)thread
|
||||
{
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
|
||||
/* We explicitly don't retain this so that we can check that it actually says
|
||||
* alive until the notification is sent. That check is implicit since
|
||||
* PASS_EQUAL in the -onThreadExit method will throw or crash if that isn't
|
||||
* the case.
|
||||
*/
|
||||
origThread = thread;
|
||||
[[NSNotificationCenter defaultCenter] addObserver: self
|
||||
selector: @selector(onThreadExit:)
|
||||
name: NSThreadWillExitNotification
|
||||
object: thread];
|
||||
[nc addObserver: self
|
||||
selector: @selector(onThreadExit:)
|
||||
name: NSThreadWillExitNotification
|
||||
object: thread];
|
||||
}
|
||||
|
||||
- (void)onThreadExit: (NSNotification*)thr
|
||||
- (void) onThreadExit: (NSNotification*)thr
|
||||
{
|
||||
NSThread *current = [NSThread currentThread];
|
||||
NSThread *current = [NSThread currentThread];
|
||||
NSThread *passed = [thr object];
|
||||
|
||||
PASS_EQUAL(passed, origThread,
|
||||
"NSThreadWillExitNotification passes expected thread")
|
||||
PASS_EQUAL(origThread, current,
|
||||
"Correct thread reference can be obtained on exit")
|
||||
PASS([passed isExecuting],
|
||||
"exiting thread is still executing at point of notification")
|
||||
PASS(![passed isFinished],
|
||||
"exiting thread is not finished at point of notification")
|
||||
|
||||
PASS_EQUAL(origThread,current,
|
||||
"Correct thread reference can be obtained on exit");
|
||||
[[NSNotificationCenter defaultCenter] removeObserver: self];
|
||||
origThread = nil;
|
||||
[condition lock];
|
||||
|
@ -61,27 +71,27 @@
|
|||
[condition unlock];
|
||||
}
|
||||
|
||||
- (BOOL)isDone
|
||||
- (BOOL) isDone
|
||||
{
|
||||
return done;
|
||||
}
|
||||
|
||||
- (void)waitUntilDate: (NSDate*)date
|
||||
- (void) waitUntilDate: (NSDate*)date
|
||||
{
|
||||
[condition waitUntilDate: date];
|
||||
}
|
||||
|
||||
- (void)lock
|
||||
- (void) lock
|
||||
{
|
||||
[condition lock];
|
||||
}
|
||||
|
||||
- (void)unlock
|
||||
- (void) unlock
|
||||
{
|
||||
[condition unlock];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
- (void) dealloc
|
||||
{
|
||||
DESTROY(condition);
|
||||
[super dealloc];
|
||||
|
@ -108,7 +118,6 @@ int main(void)
|
|||
{
|
||||
pthread_t thr;
|
||||
pthread_attr_t attr;
|
||||
void *ret;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
NSAutoreleasePool *arp = [NSAutoreleasePool new];
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#import <Foundation/NSAutoreleasePool.h>
|
||||
#import <Foundation/NSNotification.h>
|
||||
#import <Foundation/NSUserDefaults.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSValue.h>
|
||||
#import "ObjectTesting.h"
|
||||
|
||||
@interface Observer : NSObject
|
||||
|
@ -40,27 +42,39 @@ int main()
|
|||
[defs setBool: YES forKey: @"Test Suite Bool"];
|
||||
PASS([defs boolForKey: @"Test Suite Bool"],
|
||||
"NSUserDefaults can set/get a BOOL");
|
||||
PASS([[defs objectForKey: @"Test Suite Bool"] isKindOfClass:[NSNumber class]],
|
||||
"NSUserDefaults returns NSNumber for a BOOL");
|
||||
|
||||
PASS_EQUAL([obs count], @"1", "setting a boolean causes notification");
|
||||
|
||||
[defs setInteger: 34 forKey: @"Test Suite Int"];
|
||||
PASS([defs integerForKey: @"Test Suite Int"] == 34,
|
||||
"NSUserDefaults can set/get an int");
|
||||
PASS([[defs objectForKey: @"Test Suite Int"] isKindOfClass:[NSNumber class]],
|
||||
"NSUserDefaults returns NSNumber for an int");
|
||||
|
||||
PASS_EQUAL([obs count], @"2", "setting an integer causes notification");
|
||||
|
||||
[defs setObject: @"SetString" forKey: @"Test Suite Str"];
|
||||
PASS([[defs stringForKey: @"Test Suite Str"] isEqual: @"SetString"],
|
||||
"NSUserDefaults can set/get a string");
|
||||
|
||||
PASS([[defs objectForKey: @"Test Suite Str"] isKindOfClass:[NSString class]],
|
||||
"NSUserDefaults returns NSString for a string");
|
||||
|
||||
PASS_EQUAL([obs count], @"3", "setting a string causes notification");
|
||||
|
||||
[defs removeObjectForKey: @"Test Suite Bool"];
|
||||
PASS(nil == [defs objectForKey: @"Test Suite Bool"],
|
||||
"NSUserDefaults can use -removeObjectForKey: to remove a bool");
|
||||
|
||||
PASS_EQUAL([obs count], @"4", "removing a key causes notification");
|
||||
|
||||
[defs setObject: nil forKey: @"Test Suite Int"];
|
||||
PASS(nil == [defs objectForKey: @"Test Suite Int"],
|
||||
"NSUserDefaults can use -setObject:forKey: to remove an int");
|
||||
|
||||
PASS_EQUAL([obs count], @"5", "setting nil object causes notification");
|
||||
|
||||
[arp release]; arp = nil;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
notice and this notice are preserved.
|
||||
*/
|
||||
#if defined(__MINGW32__) || defined(__MINGW64__)
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
|
|
@ -3,7 +3,15 @@
|
|||
set -ex
|
||||
|
||||
DEP_SRC=$HOME/dependency_source/
|
||||
DEP_ROOT=$HOME/staging
|
||||
|
||||
case $TRAVIS_OS_NAME in
|
||||
linux)
|
||||
DEP_ROOT=$HOME/staging
|
||||
;;
|
||||
windows)
|
||||
DEP_ROOT=/c/staging
|
||||
;;
|
||||
esac
|
||||
|
||||
install_gnustep_make() {
|
||||
cd $DEP_SRC
|
||||
|
@ -15,9 +23,9 @@ install_gnustep_make() {
|
|||
else
|
||||
WITH_RUNTIME_ABI=""
|
||||
fi
|
||||
./configure --prefix=$DEP_ROOT --with-library-combo=$LIBRARY_COMBO $WITH_RUNTIME_ABI
|
||||
make install
|
||||
echo Objective-C build flags: `$HOME/staging/bin/gnustep-config --objc-flags`
|
||||
$mingw ./configure --prefix=$DEP_ROOT --with-library-combo=$LIBRARY_COMBO $WITH_RUNTIME_ABI
|
||||
$mingw make install
|
||||
echo Objective-C build flags: `$DEP_ROOT/bin/gnustep-config --objc-flags`
|
||||
}
|
||||
|
||||
install_ng_runtime() {
|
||||
|
@ -33,7 +41,12 @@ install_ng_runtime() {
|
|||
export CC="clang"
|
||||
export CXX="clang++"
|
||||
export CXXFLAGS="-std=c++11"
|
||||
cmake -DTESTS=off -DCMAKE_BUILD_TYPE=RelWithDebInfo -DGNUSTEP_INSTALL_TYPE=NONE -DCMAKE_INSTALL_PREFIX:PATH=$DEP_ROOT ../
|
||||
cmake \
|
||||
-DTESTS=off \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DGNUSTEP_INSTALL_TYPE=NONE \
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=$DEP_ROOT \
|
||||
../
|
||||
make install
|
||||
}
|
||||
|
||||
|
@ -48,7 +61,14 @@ install_libdispatch() {
|
|||
export LIBRARY_PATH=$DEP_ROOT/lib;
|
||||
export LD_LIBRARY_PATH=$DEP_ROOT/lib:$LD_LIBRARY_PATH;
|
||||
export CPATH=$DEP_ROOT/include;
|
||||
cmake -DBUILD_TESTING=off -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX:PATH=$HOME/staging -DINSTALL_PRIVATE_HEADERS=1 -DBlocksRuntime_INCLUDE_DIR=$DEP_ROOT/include -DBlocksRuntime_LIBRARIES=$DEP_ROOT/lib/libobjc.so ../
|
||||
cmake \
|
||||
-DBUILD_TESTING=off \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=$DEP_ROOT \
|
||||
-DINSTALL_PRIVATE_HEADERS=1 \
|
||||
-DBlocksRuntime_INCLUDE_DIR=$DEP_ROOT/include \
|
||||
-DBlocksRuntime_LIBRARIES=$DEP_ROOT/lib/libobjc.so \
|
||||
../
|
||||
make install
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue