mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-30 00:11:26 +00:00
Changes made in Rochester. See ChangeLog
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1650 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
a88ace74a6
commit
52441fecef
55 changed files with 935 additions and 342 deletions
|
@ -29,10 +29,10 @@
|
|||
#include <gnustep/base/MallocAddress.h>
|
||||
#include <Foundation/NSException.h>
|
||||
#include <math.h>
|
||||
#ifndef WIN32
|
||||
#ifndef __WIN32__
|
||||
#include <values.h> // This gets BITSPERBYTE on Solaris
|
||||
#include <netinet/in.h> // for byte-conversion
|
||||
#endif /* !WIN32 */
|
||||
#endif /* !__WIN32__ */
|
||||
|
||||
#define DEFAULT_FORMAT_VERSION 0
|
||||
|
||||
|
|
|
@ -244,7 +244,7 @@
|
|||
|
||||
- (void) dealloc
|
||||
{
|
||||
if (*return_type == _C_ID)
|
||||
if (return_retained && *return_type == _C_ID)
|
||||
[*(id*)return_value release];
|
||||
OBJC_FREE(return_type);
|
||||
[super dealloc];
|
||||
|
@ -457,7 +457,7 @@ my_method_get_next_argument (arglist_t argframe,
|
|||
while ((datum = my_method_get_next_argument(argframe, &tmptype)))
|
||||
{
|
||||
tmptype = objc_skip_type_qualifiers (tmptype);
|
||||
if (*tmptype == _C_ID)
|
||||
if (args_retained && *tmptype == _C_ID)
|
||||
[*(id*)datum release];
|
||||
}
|
||||
[self _deallocArgframe];
|
||||
|
|
|
@ -392,6 +392,7 @@ NSThread.m \
|
|||
NSTimer.m \
|
||||
NSTimeZone.m \
|
||||
NSUser.m \
|
||||
NSUserDefaults.m \
|
||||
NSValue.m \
|
||||
NSZone.m
|
||||
|
||||
|
@ -461,6 +462,7 @@ include/NSSet.h \
|
|||
include/NSString.h \
|
||||
include/NSThread.h \
|
||||
include/NSTimer.h \
|
||||
include/NSUserDefaults.h \
|
||||
include/NSUtilities.h \
|
||||
include/NSValue.h \
|
||||
include/NSZone.h \
|
||||
|
@ -472,8 +474,9 @@ OBJS_INSTALL = @OBJS_INSTALL@
|
|||
OBJS_INSTALL_PIC = $(OBJS_INSTALL:${OEXT}=_pic${OEXT})
|
||||
|
||||
DIST_FILES = \
|
||||
Makefile.in AUTHORS \
|
||||
Makefile.in AUTHORS Makefile.sed.nt\
|
||||
include/config.h.in include/preface.h.in \
|
||||
include/config-win32.h include/config-win32.sed \
|
||||
$(GNU_MFILES) \
|
||||
$(GNU_CFILES) \
|
||||
$(GNU_HEADERS) \
|
||||
|
@ -509,6 +512,7 @@ lib$(LIBRARY_NAME)$(LIBEXT): $(HEADERS_INSTALL) $(OBJS_INSTALL)
|
|||
|
||||
# Local links to the include files
|
||||
gnustep/base:
|
||||
rm -f gnustep base
|
||||
ln -s . gnustep
|
||||
ln -s ./include base
|
||||
# Make necessary links to source headers if compiling in seperate dir
|
||||
|
@ -546,7 +550,6 @@ install: installdirs all
|
|||
done
|
||||
$(INSTALL_DATA) include/config.h $(includedir)/gnustep/base/config.h
|
||||
cd $(includedir); rm -f Foundation; ln -s ./gnustep/base ./Foundation
|
||||
cd $(includedir); rm -f objc; ln -s ./gnustep/base ./objc
|
||||
cd $(includedir)/objc; rm -f README; ln -s ../include/README .
|
||||
|
||||
installdirs:
|
||||
|
|
|
@ -25,32 +25,28 @@
|
|||
#include <Foundation/NSAutoreleasePool.h>
|
||||
#include <gnustep/base/objc-malloc.h>
|
||||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSThread.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* TODO:
|
||||
Doesn't work multi-threaded.
|
||||
*/
|
||||
|
||||
/* The current, default NSAutoreleasePool; the one that will hold
|
||||
objects that are arguments to [NSAutoreleasePool +addObject:]. */
|
||||
static NSAutoreleasePool *current_pool = nil;
|
||||
|
||||
/* When this is `NO', autoreleased objects are never actually recorded
|
||||
in an NSAutoreleasePool, and are not sent a `release' message.
|
||||
Thus memory for objects use grows, and grows, and... */
|
||||
static BOOL autorelease_enabled = YES;
|
||||
|
||||
/* When the _released_count of the current pool gets over this value,
|
||||
we raise an exception. This can be adjusted with -setPoolCountThreshhold */
|
||||
/* When the _released_count of a pool gets over this value, we raise
|
||||
an exception. This can be adjusted with -setPoolCountThreshhold */
|
||||
static unsigned pool_count_warning_threshhold = UINT_MAX;
|
||||
|
||||
/* The total number of objects autoreleased since the program was
|
||||
started, or since -resetTotalAutoreleasedObjects was called. */
|
||||
static unsigned total_autoreleased_objects_count = 0;
|
||||
|
||||
/* The size of the first _released array. */
|
||||
#define BEGINNING_POOL_SIZE 32
|
||||
|
||||
/* Easy access to the thread variables belonging to NSAutoreleasePool. */
|
||||
#define ARP_THREAD_VARS (&([NSThread currentThread]->_autorelease_vars))
|
||||
|
||||
|
||||
@interface NSAutoreleasePool (Private)
|
||||
- _parentAutoreleasePool;
|
||||
|
@ -61,28 +57,37 @@ static unsigned total_autoreleased_objects_count = 0;
|
|||
- (void) _setChildPool: pool;
|
||||
@end
|
||||
|
||||
/* A cache of NSAutoreleasePool's already alloc'ed. Caching old pools
|
||||
instead of deallocating and re-allocating them will save time. */
|
||||
static id *autorelease_pool_cache;
|
||||
static int autorelease_pool_cache_size = 32;
|
||||
static int autorelease_pool_cache_count = 0;
|
||||
|
||||
/* Functions for managing a per-thread cache of NSAutoreleasedPool's
|
||||
already alloc'ed. The cache is kept in the autorelease_thread_var
|
||||
structure, which is an ivar of NSThread. */
|
||||
|
||||
static inline void
|
||||
init_pool_cache (struct autorelease_thread_vars *tv)
|
||||
{
|
||||
tv->pool_cache_size = 32;
|
||||
tv->pool_cache_count = 0;
|
||||
OBJC_MALLOC (tv->pool_cache, id, tv->pool_cache_size);
|
||||
}
|
||||
|
||||
static void
|
||||
push_pool_to_cache (id p)
|
||||
push_pool_to_cache (struct autorelease_thread_vars *tv, id p)
|
||||
{
|
||||
if (autorelease_pool_cache_count == autorelease_pool_cache_size)
|
||||
if (!tv->pool_cache)
|
||||
init_pool_cache (tv);
|
||||
else if (tv->pool_cache_count == tv->pool_cache_size)
|
||||
{
|
||||
autorelease_pool_cache_size *= 2;
|
||||
OBJC_REALLOC (autorelease_pool_cache, id, autorelease_pool_cache_size);
|
||||
tv->pool_cache_size *= 2;
|
||||
OBJC_REALLOC (tv->pool_cache, id, tv->pool_cache_size);
|
||||
}
|
||||
autorelease_pool_cache[autorelease_pool_cache_count++] = p;
|
||||
tv->pool_cache[tv->pool_cache_count++] = p;
|
||||
}
|
||||
|
||||
static id
|
||||
pop_pool_from_cache ()
|
||||
pop_pool_from_cache (struct autorelease_thread_vars *tv)
|
||||
{
|
||||
assert (autorelease_pool_cache_count);
|
||||
return autorelease_pool_cache[--autorelease_pool_cache_count];
|
||||
assert (tv->pool_cache_count);
|
||||
return tv->pool_cache[--(tv->pool_cache_count)];
|
||||
}
|
||||
|
||||
|
||||
|
@ -91,17 +96,18 @@ pop_pool_from_cache ()
|
|||
+ (void) initialize
|
||||
{
|
||||
if (self == [NSAutoreleasePool class])
|
||||
OBJC_MALLOC (autorelease_pool_cache, id, autorelease_pool_cache_size);
|
||||
; // Anything to put here?
|
||||
}
|
||||
|
||||
+ allocWithZone: (NSZone*)z
|
||||
+ allocWithZone: (NSZone*)zone
|
||||
{
|
||||
/* If there is an already-allocated NSAutoreleasePool available,
|
||||
save time by just returning that, rather than allocating a new one. */
|
||||
if (autorelease_pool_cache_count)
|
||||
return pop_pool_from_cache ();
|
||||
struct autorelease_thread_vars *tv = ARP_THREAD_VARS;
|
||||
if (tv->pool_cache_count)
|
||||
return pop_pool_from_cache (tv);
|
||||
|
||||
return NSAllocateObject (self, 0, z);
|
||||
return NSAllocateObject (self, 0, zone);
|
||||
}
|
||||
|
||||
- init
|
||||
|
@ -130,10 +136,13 @@ pop_pool_from_cache ()
|
|||
_released_count = 0;
|
||||
|
||||
/* Install ourselves as the current pool. */
|
||||
_parent = current_pool;
|
||||
_child = nil;
|
||||
[current_pool _setChildPool: self];
|
||||
current_pool = self;
|
||||
{
|
||||
struct autorelease_thread_vars *tv = ARP_THREAD_VARS;
|
||||
_parent = tv->current_pool;
|
||||
_child = nil;
|
||||
[tv->current_pool _setChildPool: self];
|
||||
tv->current_pool = self;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
@ -181,10 +190,12 @@ pop_pool_from_cache ()
|
|||
}
|
||||
|
||||
/* This method not in OpenStep */
|
||||
/* xxx This count should be made for *all* threads, but currently is
|
||||
only madefor the current thread! */
|
||||
+ (unsigned) autoreleaseCountForObject: anObject
|
||||
{
|
||||
unsigned count = 0;
|
||||
id pool = current_pool;
|
||||
id pool = ARP_THREAD_VARS->current_pool;
|
||||
while (pool)
|
||||
{
|
||||
count += [pool autoreleaseCountForObject: anObject];
|
||||
|
@ -195,12 +206,12 @@ pop_pool_from_cache ()
|
|||
|
||||
+ currentPool
|
||||
{
|
||||
return current_pool;
|
||||
return ARP_THREAD_VARS->current_pool;
|
||||
}
|
||||
|
||||
+ (void) addObject: anObj
|
||||
{
|
||||
[current_pool addObject: anObj];
|
||||
[ARP_THREAD_VARS->current_pool addObject: anObj];
|
||||
}
|
||||
|
||||
- (void) addObject: anObj
|
||||
|
@ -246,7 +257,7 @@ pop_pool_from_cache ()
|
|||
|
||||
/* Keep track of the total number of objects autoreleased across all
|
||||
pools. */
|
||||
total_autoreleased_objects_count++;
|
||||
ARP_THREAD_VARS->total_objects_count++;
|
||||
|
||||
/* Keep track of the total number of objects autoreleased in this pool */
|
||||
_released_count++;
|
||||
|
@ -303,13 +314,32 @@ pop_pool_from_cache ()
|
|||
}
|
||||
}
|
||||
|
||||
/* Uninstall ourselves as the current pool; install our parent pool. */
|
||||
current_pool = _parent;
|
||||
if (current_pool)
|
||||
current_pool->_child = nil;
|
||||
{
|
||||
struct autorelease_thread_vars *tv;
|
||||
NSAutoreleasePool **cp;
|
||||
|
||||
/* Don't deallocate ourself, just save us for later use. */
|
||||
push_pool_to_cache (self);
|
||||
/* Uninstall ourselves as the current pool; install our parent pool. */
|
||||
tv = ARP_THREAD_VARS;
|
||||
cp = &(tv->current_pool);
|
||||
*cp = _parent;
|
||||
if (*cp)
|
||||
(*cp)->_child = nil;
|
||||
|
||||
/* Don't deallocate ourself, just save us for later use. */
|
||||
push_pool_to_cache (tv, self);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) reallyDealloc
|
||||
{
|
||||
struct autorelease_array_list *a;
|
||||
for (a = _released_head; a; )
|
||||
{
|
||||
void *n = a->next;
|
||||
(*objc_free) (a);
|
||||
a = n;
|
||||
}
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- autorelease
|
||||
|
@ -321,12 +351,12 @@ pop_pool_from_cache ()
|
|||
|
||||
+ (void) resetTotalAutoreleasedObjects
|
||||
{
|
||||
total_autoreleased_objects_count = 0;
|
||||
ARP_THREAD_VARS->total_objects_count = 0;
|
||||
}
|
||||
|
||||
+ (unsigned) totalAutoreleasedObjects
|
||||
{
|
||||
return total_autoreleased_objects_count;
|
||||
return ARP_THREAD_VARS->total_objects_count;
|
||||
}
|
||||
|
||||
+ (void) enableRelease: (BOOL)enable
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef __WIN32__
|
||||
#include <unistd.h>
|
||||
#include <sys/param.h> /* Needed by sys/stat */
|
||||
#endif
|
||||
|
|
|
@ -29,12 +29,14 @@
|
|||
|
||||
#include <Foundation/NSDate.h>
|
||||
#include <Foundation/NSString.h>
|
||||
#ifndef __WIN32__
|
||||
#include <time.h>
|
||||
#endif /* !__WIN32__ */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef WIN32
|
||||
#ifndef __WIN32__
|
||||
#include <sys/time.h>
|
||||
#endif /* WIN32 */
|
||||
#endif /* !__WIN32__ */
|
||||
|
||||
/* The number of seconds between 1/1/2001 and 1/1/1970 = -978307200. */
|
||||
/* This number comes from:
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include <Foundation/NSInvocation.h>
|
||||
#include <Foundation/NSAutoreleasePool.h>
|
||||
#include <Foundation/NSString.h>
|
||||
#include <Foundation/NSMapTable.h>
|
||||
#include <gnustep/base/o_map.h>
|
||||
#include <Foundation/NSException.h>
|
||||
#include <limits.h>
|
||||
|
||||
|
@ -39,20 +39,29 @@ extern void (*_objc_error)(id object, const char *format, va_list);
|
|||
|
||||
/* Reference count management */
|
||||
|
||||
/* Doesn't handle multi-threaded stuff.
|
||||
Doesn't handle exceptions. */
|
||||
/* Handles multi-threaded access.
|
||||
?? Doesn't handle exceptions. */
|
||||
|
||||
/* The hashtable of retain counts on objects */
|
||||
static NSMapTable *retain_counts = NULL;
|
||||
/* The maptable of retain counts on objects */
|
||||
static o_map_t *retain_counts = NULL;
|
||||
/* The mutex lock to protect multi-threaded use of `retain_counts' */
|
||||
static _objc_mutex_t retain_counts_gate = NULL;
|
||||
|
||||
/* The Class responsible for handling autorelease's */
|
||||
/* The mutex lock to protect RETAIN_COUNTS. */
|
||||
static _objc_mutex_t retain_counts_gate;
|
||||
|
||||
/* The Class responsible for handling autorelease's. This does not
|
||||
need mutex protection, since it is simply a pointer that gets read
|
||||
and set. */
|
||||
static id autorelease_class = nil;
|
||||
|
||||
/* When this is `YES', every call to release/autorelease, checks to make sure
|
||||
isn't being set up to release itself too many times. */
|
||||
/* When this is `YES', every call to release/autorelease, checks to
|
||||
make sure isn't being set up to release itself too many times.
|
||||
This does not need mutex protection. */
|
||||
static BOOL double_release_check_enabled = NO;
|
||||
|
||||
BOOL NSShouldRetainWithZone(NSObject *anObject, NSZone *requestedZone)
|
||||
BOOL
|
||||
NSShouldRetainWithZone (NSObject *anObject, NSZone *requestedZone)
|
||||
{
|
||||
if (!requestedZone || [anObject zone] == requestedZone)
|
||||
return YES;
|
||||
|
@ -60,58 +69,52 @@ BOOL NSShouldRetainWithZone(NSObject *anObject, NSZone *requestedZone)
|
|||
return NO;
|
||||
}
|
||||
|
||||
void NSIncrementExtraRefCount (id anObject)
|
||||
void
|
||||
NSIncrementExtraRefCount (id anObject)
|
||||
{
|
||||
unsigned c = (unsigned) NSMapGet (retain_counts, anObject);
|
||||
NSMapInsert (retain_counts, anObject, (void*)c+1);
|
||||
o_map_node_t *node;
|
||||
extern o_map_node_t *o_map_node_for_key (o_map_t *m, const void *k);
|
||||
|
||||
/* xxx Make this more efficient like it was before: */
|
||||
#if 0
|
||||
coll_node_ptr n;
|
||||
|
||||
n = coll_hash_node_for_key(retain_counts, anObject);
|
||||
if (n)
|
||||
(n->value.unsigned_int_u)++;
|
||||
objc_mutex_lock (retain_counts_gate);
|
||||
node = o_map_node_for_key (retain_counts, anObject);
|
||||
if (node)
|
||||
((int)(node->value))++;
|
||||
else
|
||||
coll_hash_add(&retain_counts, anObject, (unsigned)1);
|
||||
#endif
|
||||
o_map_at_key_put_value_known_absent (retain_counts, anObject, (void*)1);
|
||||
objc_mutex_unlock (retain_counts_gate);
|
||||
}
|
||||
|
||||
BOOL NSDecrementExtraRefCountWasZero (id anObject)
|
||||
BOOL
|
||||
NSDecrementExtraRefCountWasZero (id anObject)
|
||||
{
|
||||
unsigned c = (unsigned) NSMapGet (retain_counts, anObject);
|
||||
o_map_node_t *node;
|
||||
extern o_map_node_t *o_map_node_for_key (o_map_t *m, const void *k);
|
||||
extern void o_map_remove_node (o_map_node_t *node);
|
||||
|
||||
if (!c)
|
||||
return YES;
|
||||
|
||||
c--;
|
||||
if (c)
|
||||
NSMapInsert (retain_counts, anObject, (void*)c);
|
||||
else
|
||||
NSMapRemove (retain_counts, anObject);
|
||||
objc_mutex_lock (retain_counts_gate);
|
||||
node = o_map_node_for_key (retain_counts, anObject);
|
||||
if (!node)
|
||||
{
|
||||
objc_mutex_unlock (retain_counts_gate);
|
||||
return YES;
|
||||
}
|
||||
assert ((int)(node->value) > 0);
|
||||
if (!--((int)(node->value)))
|
||||
o_map_remove_node (node);
|
||||
objc_mutex_unlock (retain_counts_gate);
|
||||
return NO;
|
||||
|
||||
/* xxx Make this more efficient like it was before: */
|
||||
#if 0
|
||||
coll_node_ptr n;
|
||||
|
||||
n = coll_hash_node_for_key(retain_counts, anObject);
|
||||
if (!n) return wasZero;
|
||||
if (n->value.unsigned_int_u) wasZero = NO;
|
||||
if (!--n->value.unsigned_int_u)
|
||||
coll_hash_remove(retain_counts, anObject);
|
||||
return wasZero;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@implementation NSObject
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (self == [NSObject class])
|
||||
{
|
||||
retain_counts = NSCreateMapTable (NSNonOwnedPointerOrNullMapKeyCallBacks,
|
||||
NSIntMapValueCallBacks, 64);
|
||||
retain_counts = o_map_with_callbacks (o_callbacks_for_non_owned_void_p,
|
||||
o_callbacks_for_int);
|
||||
retain_counts_gate = objc_mutex_allocate ();
|
||||
autorelease_class = [NSAutoreleasePool class];
|
||||
}
|
||||
return;
|
||||
|
@ -433,7 +436,12 @@ BOOL NSDecrementExtraRefCountWasZero (id anObject)
|
|||
|
||||
- (unsigned) retainCount
|
||||
{
|
||||
return (unsigned) NSMapGet (retain_counts, self);
|
||||
unsigned ret;
|
||||
|
||||
objc_mutex_lock (retain_counts_gate);
|
||||
ret = (unsigned) o_map_value_at_key (retain_counts, self);
|
||||
objc_mutex_unlock (retain_counts_gate);
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ (unsigned) retainCount
|
||||
|
@ -451,12 +459,10 @@ BOOL NSDecrementExtraRefCountWasZero (id anObject)
|
|||
return NSZoneFromPtr(self);
|
||||
}
|
||||
|
||||
#if 1 /* waiting until I resolve type conflict with GNU Coding method */
|
||||
- (void) encodeWithCoder: (NSCoder*)aCoder
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
- initWithCoder: (NSCoder*)aDecoder
|
||||
{
|
||||
|
@ -465,6 +471,7 @@ BOOL NSDecrementExtraRefCountWasZero (id anObject)
|
|||
|
||||
@end
|
||||
|
||||
|
||||
@implementation NSObject (NEXTSTEP)
|
||||
|
||||
/* NEXTSTEP Object class compatibility */
|
||||
|
@ -581,6 +588,7 @@ BOOL NSDecrementExtraRefCountWasZero (id anObject)
|
|||
|
||||
@end
|
||||
|
||||
|
||||
@implementation NSObject (GNU)
|
||||
|
||||
/* GNU Object class compatibility */
|
||||
|
|
|
@ -22,12 +22,18 @@
|
|||
*/
|
||||
|
||||
#include <gnustep/base/preface.h>
|
||||
#ifndef __WIN32__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#if __mach__
|
||||
#include <mach.h>
|
||||
#endif
|
||||
|
||||
#ifdef __WIN32__
|
||||
#define getpagesize() vm_page_size
|
||||
#endif
|
||||
|
||||
/* Cache the size of a memory page here, so we don't have to make the
|
||||
getpagesize() system call repeatedly. */
|
||||
static unsigned ns_page_size = 0;
|
||||
|
|
|
@ -53,10 +53,10 @@
|
|||
*************************************************************************/
|
||||
|
||||
/* One of these two should have MAXHOSTNAMELEN */
|
||||
#ifndef WIN32
|
||||
#ifndef __WIN32__
|
||||
#include <sys/param.h>
|
||||
#include <netdb.h>
|
||||
#endif /* WIN32 */
|
||||
#endif /* !__WIN32__ */
|
||||
|
||||
#include <string.h>
|
||||
#include <Foundation/NSString.h>
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include <gnustep/base/String.h>
|
||||
#include <gnustep/base/behavior.h>
|
||||
#include <limits.h>
|
||||
#include <string.h> // for strstr()
|
||||
|
||||
@implementation NSString
|
||||
|
||||
|
@ -100,9 +101,13 @@ static Class NSMutableString_c_concrete_class;
|
|||
#include <printf.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/* <sattler@volker.cs.Uni-Magdeburg.DE>, with libc-5.3.9 thinks this
|
||||
should be 0, but for me, with libc-5.0.9, it crashes. -mccallum */
|
||||
#define PRINTF_ATSIGN_VA_LIST 1
|
||||
/* <sattler@volker.cs.Uni-Magdeburg.DE>, with libc-5.3.9 thinks this
|
||||
flag PRINTF_ATSIGN_VA_LIST should be 0, but for me, with libc-5.0.9,
|
||||
it crashes. -mccallum */
|
||||
#define PRINTF_ATSIGN_VA_LIST \
|
||||
(defined(_LINUX_C_LIB_VERSION_MINOR) \
|
||||
&& _LINUX_C_LIB_VERSION_MAJOR <= 5 \
|
||||
&& _LINUX_C_LIB_VERSION_MINOR < 2)
|
||||
|
||||
#if ! PRINTF_ATSIGN_VA_LIST
|
||||
static int
|
||||
|
@ -112,7 +117,7 @@ arginfo_func (const struct printf_info *info,
|
|||
*argtypes = PA_POINTER;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
#endif /* !PRINTF_ATSIGN_VA_LIST */
|
||||
|
||||
static int
|
||||
handle_printf_atsign (FILE *stream,
|
||||
|
@ -135,7 +140,7 @@ handle_printf_atsign (FILE *stream,
|
|||
#if PRINTF_ATSIGN_VA_LIST
|
||||
string_object = va_arg (*ap_pointer, id);
|
||||
#else
|
||||
string_object = *((id *) ptr);
|
||||
string_object = *((id*) ptr);
|
||||
#endif
|
||||
len = fprintf(stream, "%*s",
|
||||
(info->left ? - info->width : info->width),
|
||||
|
@ -297,21 +302,64 @@ handle_printf_atsign (FILE *stream,
|
|||
|
||||
/* xxx Change this when we have non-CString classes */
|
||||
- (id) initWithFormat: (NSString*)format
|
||||
arguments: (va_list)argList
|
||||
arguments: (va_list)arg_list
|
||||
{
|
||||
#if HAVE_VSPRINTF
|
||||
#define BUFFER_EXTRA 1024
|
||||
const char *format_cp = [format cStringNoCopy];
|
||||
int format_len = strlen (format_cp);
|
||||
char buf[format_len + BUFFER_EXTRA]; /* xxx horrible disgusting, fix this! */
|
||||
int printed_len;
|
||||
/* xxx horrible disgusting BUFFER_EXTRA arbitrary limit; fix this! */
|
||||
#define BUFFER_EXTRA 1024
|
||||
char buf[format_len + BUFFER_EXTRA];
|
||||
int printed_len = 0;
|
||||
|
||||
printed_len = vsprintf (buf, format_cp, argList);
|
||||
/* Signal error if we overran our buffer. */
|
||||
#if ! HAVE_REGISTER_PRINTF_FUNCTION
|
||||
/* If the available libc doesn't have `register_printf_function()', then
|
||||
the `%@' printf directive isn't available with printf() and friends.
|
||||
Here we make a feable attempt to handle it. */
|
||||
{
|
||||
/* We need a local copy since we change it. (Changing and undoing
|
||||
the change doesn't work because some format strings are constant
|
||||
strings, placed in a non-writable section of the executable, and
|
||||
can't be written to.) */
|
||||
char format_cp_copy[format_len+1];
|
||||
char *atsign_pos;
|
||||
char *format_to_go = format_cp_copy;
|
||||
strcpy (format_cp_copy, format_cp);
|
||||
/* Loop once for each `%@' in the format string. */
|
||||
while ((atsign_pos = strstr (format_to_go, "%@")))
|
||||
{
|
||||
const char *cstring;
|
||||
/* If there is a "%%@", then do the right thing: print it literally. */
|
||||
if ((*(atsign_pos-1) == '%')
|
||||
&& atsign_pos != format_cp_copy)
|
||||
continue;
|
||||
/* Temporarily terminate the string before the `%@'. */
|
||||
*atsign_pos = '\0';
|
||||
/* Print the part before the '%@' */
|
||||
printed_len = vsprintf (buf, format_cp_copy, arg_list);
|
||||
/* Get a C-string (char*) from the String object, and print it. */
|
||||
cstring = [(id) va_arg (arg_list, id) cStringNoCopy];
|
||||
strcat (buf+printed_len, cstring);
|
||||
printed_len += strlen (cstring);
|
||||
/* Put back the `%' we removed when we terminated mid-string. */
|
||||
*atsign_pos = '%';
|
||||
/* Skip over this `%@', and look for another one. */
|
||||
format_to_go = atsign_pos + 2;
|
||||
}
|
||||
/* Print the rest of the string after the last `%@'. */
|
||||
printed_len += vsprintf (buf+printed_len, format_to_go, arg_list);
|
||||
}
|
||||
#else
|
||||
/* The available libc has `register_printf_function()', so the `%@'
|
||||
printf directive is handled by printf and friends. */
|
||||
printed_len = vsprintf (buf, format_cp, arg_list);
|
||||
#endif /* !HAVE_REGISTER_PRINTF_FUNCTION */
|
||||
|
||||
/* Raise an exception if we overran our buffer. */
|
||||
NSParameterAssert (printed_len < format_len + BUFFER_EXTRA - 1);
|
||||
return [self initWithCString:buf];
|
||||
#else
|
||||
[self notImplemented:_cmd];
|
||||
#else /* HAVE_VSPRINTF */
|
||||
[self notImplemented: _cmd];
|
||||
return self;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ static o_map_t thread_id_2_nsthread;
|
|||
/* Flag indicating whether the objc runtime ever went multi-threaded. */
|
||||
static BOOL entered_multi_threaded_state;
|
||||
|
||||
|
||||
@implementation NSThread
|
||||
|
||||
// Class initialization
|
||||
|
@ -72,8 +73,8 @@ static BOOL entered_multi_threaded_state;
|
|||
[super init];
|
||||
|
||||
/* initialize our ivars. */
|
||||
_thread_dictionary = [NSMutableDictionary dictionary];
|
||||
_thread_autorelease_pool = nil;
|
||||
_thread_dictionary = nil; // Initialize this later only when needed
|
||||
init_autorelease_thread_vars (&_autorelease_vars);
|
||||
|
||||
/* Make it easy and fast to get this NSThread object from the thread. */
|
||||
objc_thread_set_data (self);
|
||||
|
@ -137,6 +138,8 @@ static BOOL entered_multi_threaded_state;
|
|||
|
||||
- (NSMutableDictionary*) threadDictionary
|
||||
{
|
||||
if (!_thread_dictionary)
|
||||
_thread_dictionary = [NSMutableDictionary dictionary];
|
||||
return _thread_dictionary;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,19 +24,26 @@
|
|||
#include <gnustep/base/preface.h>
|
||||
#include <Foundation/NSString.h>
|
||||
#include <stdlib.h> // for getenv()
|
||||
#ifndef __WIN32__
|
||||
#include <unistd.h> // for getlogin()
|
||||
#include <pwd.h> // for getpwnam()
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
|
||||
/* Return the caller's login name as an NSString object. */
|
||||
NSString *
|
||||
NSUserName ()
|
||||
{
|
||||
#ifndef __WIN32__
|
||||
const char *login_name = getlogin ();
|
||||
|
||||
if (login_name)
|
||||
return [NSString stringWithCString: login_name];
|
||||
else
|
||||
return nil;
|
||||
#else
|
||||
return nil;
|
||||
#endif /* __WIN32__ */
|
||||
}
|
||||
|
||||
/* Return the caller's home directory as an NSString object. */
|
||||
|
@ -50,7 +57,11 @@ NSHomeDirectory ()
|
|||
NSString *
|
||||
NSHomeDirectoryForUser (NSString *login_name)
|
||||
{
|
||||
#ifndef __WIN32__
|
||||
struct passwd *pw;
|
||||
pw = getpwnam ([login_name cStringNoCopy]);
|
||||
return [NSString stringWithCString: pw->pw_dir];
|
||||
#else
|
||||
return nil;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -182,7 +182,8 @@
|
|||
@implementation NotificationDispatcher
|
||||
|
||||
/* The default instance, most often the only one created.
|
||||
It is accessed by the class methods at the end of this file. */
|
||||
It is accessed by the class methods at the end of this file.
|
||||
There is no need to mutex locking of this variable. */
|
||||
static NotificationDispatcher *default_notification_dispatcher = nil;
|
||||
|
||||
+ (void) initialize
|
||||
|
@ -219,9 +220,21 @@ static NotificationDispatcher *default_notification_dispatcher = nil;
|
|||
NSCreateMapTable (NSNonOwnedPointerOrNullMapKeyCallBacks,
|
||||
NSObjectMapValueCallBacks, 0);
|
||||
|
||||
_lock = [NSRecursiveLock new];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[_anonymous_nr_list release];
|
||||
NSFreeMapTable( _object_2_nr_list);
|
||||
NSFreeMapTable (_name_2_nr_list);
|
||||
NSFreeMapTable (_observer_2_nr_array);
|
||||
[_lock release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
/* Adding new observers. */
|
||||
|
||||
|
@ -237,6 +250,8 @@ static NotificationDispatcher *default_notification_dispatcher = nil;
|
|||
if (!observer)
|
||||
return;
|
||||
|
||||
[_lock lock];
|
||||
|
||||
/* Record the notification request in an array keyed by OBSERVER. */
|
||||
{
|
||||
/* Find the array of all the requests by OBSERVER. */
|
||||
|
@ -298,6 +313,8 @@ static NotificationDispatcher *default_notification_dispatcher = nil;
|
|||
}
|
||||
[nr_list appendObject: nr];
|
||||
}
|
||||
|
||||
[_lock unlock];
|
||||
}
|
||||
|
||||
- (void) addInvocation: (id <Invoking>)invocation
|
||||
|
@ -435,6 +452,8 @@ static NotificationDispatcher *default_notification_dispatcher = nil;
|
|||
if (!observer)
|
||||
return;
|
||||
|
||||
[_lock lock];
|
||||
|
||||
/* Get the array of NotificationRequest's associated with OBSERVER. */
|
||||
observer_nr_array = NSMapGet (_observer_2_nr_array, observer);
|
||||
|
||||
|
@ -454,6 +473,8 @@ static NotificationDispatcher *default_notification_dispatcher = nil;
|
|||
associated with OBSERVER. This also releases the observer_nr_array,
|
||||
and its contents. */
|
||||
NSMapRemove (_observer_2_nr_array, observer);
|
||||
|
||||
[_lock unlock];
|
||||
}
|
||||
|
||||
|
||||
|
@ -473,6 +494,8 @@ static NotificationDispatcher *default_notification_dispatcher = nil;
|
|||
|
||||
/* We are now guaranteed that at least one of NAME and OBJECT is non-nil. */
|
||||
|
||||
[_lock lock];
|
||||
|
||||
/* Get the list of NotificationRequest's associated with OBSERVER. */
|
||||
observer_nr_array = NSMapGet (_observer_2_nr_array, observer);
|
||||
|
||||
|
@ -508,6 +531,8 @@ static NotificationDispatcher *default_notification_dispatcher = nil;
|
|||
/* xxx If there are some LinkedList's that are empty, I should
|
||||
remove them from the map table's. */
|
||||
}
|
||||
|
||||
[_lock unlock];
|
||||
}
|
||||
|
||||
|
||||
|
@ -526,6 +551,8 @@ static NotificationDispatcher *default_notification_dispatcher = nil;
|
|||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"Tried to post a notification with no name."];
|
||||
|
||||
[_lock lock];
|
||||
|
||||
/* Post the notification to all the observers that specified neither
|
||||
NAME or OBJECT. */
|
||||
if ([_anonymous_nr_list count])
|
||||
|
@ -566,6 +593,8 @@ static NotificationDispatcher *default_notification_dispatcher = nil;
|
|||
}
|
||||
END_FOR_COLLECTION (nr_list);
|
||||
}
|
||||
|
||||
[_lock unlock];
|
||||
}
|
||||
|
||||
- (void) postNotificationName: (id <String>)name
|
||||
|
|
|
@ -59,9 +59,9 @@
|
|||
#include <Foundation/NSValue.h>
|
||||
#include <Foundation/NSAutoreleasePool.h>
|
||||
#include <Foundation/NSTimer.h>
|
||||
#ifndef WIN32
|
||||
#ifndef __WIN32__
|
||||
#include <sys/time.h>
|
||||
#endif /* !WIN32 */
|
||||
#endif /* !__WIN32__ */
|
||||
#include <limits.h>
|
||||
#include <string.h> /* for memset() */
|
||||
|
||||
|
@ -341,7 +341,7 @@ static RunLoop *current_run_loop;
|
|||
want us to listen to; add these to FD_LISTEN_SET. */
|
||||
for (i = [ports count]-1; i >= 0; i--)
|
||||
{
|
||||
int port_fd_count = 128;
|
||||
int port_fd_count = 128; // xxx #define this constant
|
||||
int port_fd_array[port_fd_count];
|
||||
port = [ports objectAtIndex: i];
|
||||
if ([port respondsTo: @selector(getFds:count:)])
|
||||
|
@ -376,7 +376,10 @@ static RunLoop *current_run_loop;
|
|||
abort ();
|
||||
}
|
||||
else if (select_return == 0)
|
||||
return;
|
||||
{
|
||||
NSFreeMapTable (fd_2_object);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Look at all the file descriptors select() says are ready for reading;
|
||||
notify the corresponding object for each of the ready fd's. */
|
||||
|
|
|
@ -40,16 +40,16 @@
|
|||
#include <Foundation/NSDate.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef WIN32
|
||||
#ifndef __WIN32__
|
||||
#include <unistd.h> /* for gethostname() */
|
||||
#include <sys/param.h> /* for MAXHOSTNAMELEN */
|
||||
#include <arpa/inet.h> /* for inet_ntoa() */
|
||||
#endif /* !WIN32 */
|
||||
#include <string.h> /* for memset() */
|
||||
#ifndef WIN32
|
||||
#endif /* !__WIN32__ */
|
||||
#include <string.h> /* for memset() and strchr() */
|
||||
#ifndef __WIN32__
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
#endif /* !__WIN32__ */
|
||||
|
||||
/* On some systems FD_ZERO is a macro that uses bzero().
|
||||
Just define it to use GCC's builtin memset(). */
|
||||
|
@ -224,7 +224,7 @@ static NSMapTable* port_number_2_port;
|
|||
abort ();
|
||||
}
|
||||
|
||||
/* Now change INADDR_ANY to the specific network address of this
|
||||
/* Now change _LISTENING_ADDRESS to the specific network address of this
|
||||
machine so that, when we encoded our _LISTENING_ADDRESS for a
|
||||
Distributed Objects connection to another machine, they get our
|
||||
unique host address that can identify us across the network. */
|
||||
|
@ -233,12 +233,15 @@ static NSMapTable* port_number_2_port;
|
|||
perror ("[TcpInPort +newForReceivingFromPortNumber:] gethostname()");
|
||||
abort ();
|
||||
}
|
||||
/* Terminate the name at the first dot. */
|
||||
{
|
||||
char *first_dot = strchr (hostname, '.');
|
||||
if (first_dot)
|
||||
*first_dot = '\0';
|
||||
}
|
||||
hp = gethostbyname (hostname);
|
||||
if (!hp)
|
||||
/* xxx This won't work with port connections on a network, though.
|
||||
Fix this. Perhaps there is a better way of getting the address
|
||||
of the local host. */
|
||||
hp = gethostbyname ("localhost");
|
||||
[self error: "Could not get address of local host \"%s\"", hostname];
|
||||
assert (hp);
|
||||
memcpy (&(p->_listening_address.sin_addr), hp->h_addr, hp->h_length);
|
||||
}
|
||||
|
@ -851,10 +854,25 @@ static NSMapTable *out_port_bag = NULL;
|
|||
struct hostent *hp;
|
||||
const char *host_cstring;
|
||||
struct sockaddr_in addr;
|
||||
/* Only used if no hostname is passed in. */
|
||||
char local_hostname[MAXHOSTNAMELEN];
|
||||
|
||||
/* Look up the hostname. */
|
||||
if (!hostname || ![hostname length])
|
||||
host_cstring = "localhost";
|
||||
{
|
||||
int len = sizeof (local_hostname);
|
||||
char *first_dot;
|
||||
if (gethostname (local_hostname, len) < 0)
|
||||
{
|
||||
perror ("[TcpOutPort +newForSendingToPortNumber:onHost:] "
|
||||
"gethostname()");
|
||||
abort ();
|
||||
}
|
||||
host_cstring = local_hostname;
|
||||
first_dot = strchr (host_cstring, '.');
|
||||
if (first_dot)
|
||||
*first_dot = '\0';
|
||||
}
|
||||
else
|
||||
host_cstring = [hostname cStringNoCopy];
|
||||
hp = gethostbyname ((char*)host_cstring);
|
||||
|
@ -1093,7 +1111,6 @@ static NSMapTable *out_port_bag = NULL;
|
|||
{
|
||||
char prefix_buffer[PREFIX_SIZE];
|
||||
int c;
|
||||
struct sockaddr_in *addr;
|
||||
|
||||
c = read (s, prefix_buffer, PREFIX_SIZE);
|
||||
if (c == 0)
|
||||
|
@ -1120,10 +1137,13 @@ static NSMapTable *out_port_bag = NULL;
|
|||
/* If the reply address is non-zero, and the TcpOutPort for this socket
|
||||
doesn't already have its _address ivar set, then set it now. */
|
||||
{
|
||||
addr = (struct sockaddr_in*) (prefix_buffer + PREFIX_LENGTH_SIZE);
|
||||
if (addr->sin_family)
|
||||
struct sockaddr_in addr;
|
||||
/* Do this memcpy instead of simply casting the pointer because
|
||||
some systems fail to do the cast correctly (due to alignment issues?) */
|
||||
memcpy (&addr, prefix_buffer + PREFIX_LENGTH_SIZE, sizeof (typeof (addr)));
|
||||
if (addr.sin_family)
|
||||
{
|
||||
*rp = [TcpOutPort newForSendingToSockaddr: addr
|
||||
*rp = [TcpOutPort newForSendingToSockaddr: &addr
|
||||
withAcceptedSocket: s
|
||||
pollingInPort: ip];
|
||||
}
|
||||
|
@ -1167,7 +1187,9 @@ static NSMapTable *out_port_bag = NULL;
|
|||
/* Put the sockaddr_in for replies in the next bytes of the prefix
|
||||
region. If there is no reply address specified, fill it with zeros. */
|
||||
if (addr)
|
||||
*(PREFIX_ADDRESS_TYPE*)(buffer + PREFIX_LENGTH_SIZE) = *addr;
|
||||
/* Do this memcpy instead of simply casting the pointer because
|
||||
some systems fail to do the cast correctly (due to alignment issues?) */
|
||||
memcpy (buffer + PREFIX_LENGTH_SIZE, addr, PREFIX_ADDRESS_SIZE);
|
||||
else
|
||||
memset (buffer + PREFIX_LENGTH_SIZE, 0, PREFIX_ADDRESS_SIZE);
|
||||
|
||||
|
|
|
@ -31,8 +31,10 @@
|
|||
#endif
|
||||
|
||||
#if HAVE_TIMES
|
||||
#ifndef __WIN32__
|
||||
#include <sys/times.h>
|
||||
#endif
|
||||
#endif /* !__WIN32__ */
|
||||
#endif /* HAVE_TIMES */
|
||||
|
||||
/* There are several places where I need to deal with tz more intelligently */
|
||||
/* I should allow customization of a strftime() format string for printing. */
|
||||
|
@ -64,6 +66,37 @@ int gettimeofday(tvp, tzp)
|
|||
}
|
||||
#endif /* _SEQUENT_ */
|
||||
|
||||
#ifdef __WIN32__
|
||||
/* Win32 does not provide gettimeofday() */
|
||||
int gettimeofday(tvp, tzp)
|
||||
struct timeval *tvp;
|
||||
struct timezone *tzp;
|
||||
{
|
||||
TIME_ZONE_INFORMATION sys_time_zone;
|
||||
SYSTEMTIME sys_time;
|
||||
|
||||
// Get the time zone information
|
||||
GetTimeZoneInformation(&sys_time_zone);
|
||||
|
||||
// Get the local time
|
||||
GetLocalTime(&sys_time);
|
||||
|
||||
tvp->tv_usec = sys_time.wMilliseconds;
|
||||
tvp->tv_sec = sys_time.wSecond;
|
||||
tvp->tv_sec = tvp->tv_sec + (sys_time.wMinute * 60);
|
||||
tvp->tv_sec = tvp->tv_sec + (sys_time.wHour * 60 * 60);
|
||||
tvp->tv_sec = tvp->tv_sec + (sys_time.wDay * 60 * 60 * 24);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Win32 does not provide times() */
|
||||
int times(struct tms *atms)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* __WIN32__ */
|
||||
|
||||
/* tmp for passing to gettimeofday() */
|
||||
static struct timeval _Time_tv;
|
||||
static struct timezone _Time_tz;
|
||||
|
|
|
@ -31,16 +31,16 @@
|
|||
#include <gnustep/base/ConnectedCoder.h>
|
||||
#include <gnustep/base/String.h>
|
||||
#include <assert.h>
|
||||
#ifndef WIN32
|
||||
#ifndef __WIN32__
|
||||
#include <sys/param.h> /* for MAXHOSTNAMELEN */
|
||||
#endif /* !WIN32 */
|
||||
#endif /* !__WIN32__ */
|
||||
#if _AIX
|
||||
#include <sys/select.h>
|
||||
#endif /* _AIX */
|
||||
#ifndef WIN32
|
||||
#ifndef __WIN32__
|
||||
#include <netdb.h>
|
||||
#include <sys/time.h>
|
||||
#endif /* !WIN32 */
|
||||
#endif /* !__WIN32__ */
|
||||
|
||||
@interface UdpInPort (Private)
|
||||
@end
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef __WIN32__
|
||||
#include <limits.h>
|
||||
#define S_IFLNK 0120000
|
||||
int readlink(char *path, char *buf, int bufsiz) { return (-1); }
|
||||
|
@ -42,7 +42,7 @@ int lstat(char *path, struct stat *buf) { return (-1); }
|
|||
#include <sys/file.h>
|
||||
#include <sys/param.h>
|
||||
#include <unistd.h>
|
||||
#endif /* WIN32 */
|
||||
#endif /* __WIN32__ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -322,6 +322,23 @@ _o_map_node_for_key(o_map_t *map, const void *key)
|
|||
return node;
|
||||
}
|
||||
|
||||
/* A non--static-inline version for use in NSObject.
|
||||
xxx Figure out if this change should be generalized. */
|
||||
o_map_node_t *
|
||||
o_map_node_for_key (o_map_t *map, const void *key)
|
||||
{
|
||||
return _o_map_node_for_key (map, key);
|
||||
}
|
||||
|
||||
/* A non--static-inline version for use in NSObject.
|
||||
xxx Figure out if this change should be generalized. */
|
||||
void
|
||||
o_map_remove_node (o_map_node_t *node)
|
||||
{
|
||||
_o_map_remove_node_from_its_map (node);
|
||||
_o_map_free_node(node);
|
||||
}
|
||||
|
||||
/** Callbacks... **/
|
||||
|
||||
/* Return a hash index for MAP. Needed for the callbacks below. */
|
||||
|
|
|
@ -59,7 +59,7 @@ WINBOOL WINAPI DLLMain(HANDLE hInst, ULONG ul_reason_for_call,
|
|||
#endif /* __MS_WIN32__ */
|
||||
|
||||
/* Initialize the GNUstep Base Library runtime structures */
|
||||
init_gnustep_base_runtime();
|
||||
gnustep_base_init_runtime();
|
||||
|
||||
printf("GNUstep Base Library: process attach\n");
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ WINBOOL WINAPI DLLMain(HANDLE hInst, ULONG ul_reason_for_call,
|
|||
#endif /* __MS_WIN32__ */
|
||||
|
||||
/* Initialize the Library? -not for threads? */
|
||||
init_gnustep_base_runtime();
|
||||
gnustep_base_init_runtime();
|
||||
|
||||
printf("GNUstep Base Library: thread attach\n");
|
||||
}
|
||||
|
@ -89,3 +89,6 @@ WINBOOL WINAPI DLLMain(HANDLE hInst, ULONG ul_reason_for_call,
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue