Merge branch 'master' into android-assets-directory-improvements

This commit is contained in:
rfm 2020-06-06 12:13:43 +01:00 committed by GitHub
commit daadfe7a6d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 328 additions and 191 deletions

View file

@ -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

View file

@ -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>

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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)

View file

@ -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++;
}

View file

@ -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];
}

View file

@ -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");
}

View file

@ -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);
}

View file

@ -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");
}

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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];

View file

@ -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;
}

View file

@ -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>

View file

@ -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
}