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:
Andrew McCallum 1996-07-15 18:41:44 +00:00
parent a88ace74a6
commit 52441fecef
55 changed files with 935 additions and 342 deletions

View file

@ -53,6 +53,7 @@ mostlyclean:
rm -f *~ rm -f *~
clean: mostlyclean clean: mostlyclean
distclean: clean distclean: clean
rm -f Makefile
maintainer-clean: distclean maintainer-clean: distclean
copy-dist: $(DIST_FILES) copy-dist: $(DIST_FILES)

299
ChangeLog
View file

@ -1,7 +1,300 @@
Wed Jun 26 20:45:26 1996 Andrew McCallum <mccallum@cs.cmu.edu> Thu Jul 11 21:12:41 1996 Andrew McCallum <mccallum@cs.rochester.edu>
* src/Makefile.in (install): Create a soft link for `objc' in * Version (SUBMINOR_VERSION): Version 0.2.6.
addition to `Foundation'.
Tue Jun 25 12:56:01 1996 Scott Christley <scottc@ocbi.com>
* NSCharacterSets/Makefile.in: Remove Makefile when distclean.
* admin/Makefile.in: Likewise.
* checks/Makefile.in: Change realclean target to maintainer-clean.
* doc/Makefile.in: Likewise.
* examples/Makefile.in: Likewise.
* Makefile.in: Clean the subdirectories first before the top
level directory to avoid configuration loop.
* checks/Makefile.sed.nt: Change name of runtime initialization
routine to use standard "_init_runtime" suffix.
* checks/nsarchiver.m: Likewise.
* checks/nsarray.m: Likewise.
* src/win32-entry.c: Likewise.
* src/Makefile.in: Likewise. Clean additional files.
* src/NSDate.m: Use __WIN32__ macro instead of WIN32.
* src/NSTime.m: Implement Win32 specific time routines.
* src/include/config-win32.h: Likewise.
Fri Jun 21 16:45:31 1996 Scott Christley <scottc@ocbi.com>
* configure.bat: New filenames for Win32 configuration.
* src/Makefile.in: (DIST_FILES): Add Win32 configuration files:
src/include/config-win32.sed, src/include/config-win32.h.
* src/BinaryCStream.m: Rename WIN32 to __WIN32__ to conform
to ANSI specifications. Perform any WIN32 customization.
* src/NSBundle.m: Likewise.
* src/NSPage.m: Likewise.
* src/NSProcessInfo.m: Likewise.
* src/NSUser.m: Likewise.
* src/NSRunLoop.m: Likewise.
* src/TcpPort.m: Likewise.
* src/UdpPort.m: Likewise.
* src/find_exec.c: Likewise.
* src/include/TcpPort.h: Likewise.
* src/include/Time.h: Likewise.
* src/include/config-nt.sed: Renamed to config-win32.sed.
* src/include/config-nt.h: Renamed to config-win32.h
Thu Jul 11 08:20:34 1996 Andrew McCallum <mccallum@cs.rochester.edu>
* src/NSAutoreleasePool.m ([NSAutoreleasePool -dealloc]): Remove
untrue assertion that SELF be this thread's current pool.
(Reported by Adam Fedor.)
* checks/Makefile.in (LIBS): Remove -lmcheck.
* Version (SUBMINOR_VERSION): Version 0.2.5.
* doc/news.texi: Fix typo, replace @ with @@ in email address.
* Version (SUBMINOR_VERSION): Version 0.2.4.
* src/NSString.m (PRINTF_ATSIGN_VA_LIST): Reverse sense of test.
This macro should be defined if libc version is *less than* 5.2.
* examples/dictionary.m: Long-overdue update for new collection
heirarchy.
* examples/textcoding.m (main): Fix typo in comment.
* examples/second-server.m: Add comments.
* examples/second-client.m (main): To avoid warnings: make SERVER
static; get rid of unused variable.
* examples/Makefile.in (CFLAGS): Added -Wno-format so we don't get
complains about the %@ printf directive.
* doc/news.texi: Add news about NSUserDefaults, thread-safety, @%,
and NSPage.
* doc/readme.texi: Update description of classes, although the
list is still incomplete.
Wed Jul 10 16:28:14 1996 Andrew McCallum <mccallum@cs.rochester.edu>
* doc/gnustep-faq.texi: New Q/A about mixing Objective C and C++.
Include base-desc.texi for description of Base Library. Update
"state of development for Base Library. Correct description of
NeXT's archiving. Add ocbi.com ftp site.
* doc/base-desc.texi: Improve list of example classes.
* doc/announce.texi: Fix comments about NeXT's cc.
* doc/machines.texi: Label as out-of-date.
* doc/advertisement.texi: Comment out inclusion of machines.texi.
* src/NSUserDefaults.m: Fix source to avoid warnings.
* src/NSUserDefaults.m: New file from Georg Tuparev.
* src/include/NSUserDefaults.h: Likewise.
* src/NSUserDefaults.m, src/include/NSUserDefaults.h: Fix
formatting to conform to GNU standards.
* src/Makefile.in (GNUSTEP_MFILES): Added NSUserDefaults.m.
(GNUSTEP_HEADERS): Added include/NSUserDefaults.h.
Tue Jul 9 20:05:16 1996 Andrew McCallum <mccallum@cs.rochester.edu>
* doc/install.texi: Enumerate the steps, and various other
corrections.
* src/RunLoop.m ([RunLoop -acceptInputForMode:beforeDate:]): Free
fd_2_object before returning in case where select() returned 0.
(Reported by Marc Decugis <mds@sepgifbr.sep.de.edf.fr>.)
Mon Jul 8 21:55:11 1996 Andrew McCallum <mccallum@cs.rochester.edu>
* Version (SUBMINOR_VERSION): Version 0.2.3.
* src/Invocation.m ([ArgframeInvocation -dealloc]): Release
arguments depending on ARGS_RETAINED, not RETURN_RETAINED.
* checks/release.m: New file.
* checks/Makefile.in (SRCS): Added release.m.
* src/o_map.m (o_map_remove_node): Function renamed from
o_map_remove_node_from_its_map(). Free the node after removing
it! Otherwise, memory leaks and leaks!
* src/NSObject.m (NSDecrementExtraRefCountWasZero): Call renamed
function for removing node.
* src/NSAutoreleasePool.m (push_pool_to_cache): Avoid unnecessary
test.
(pop_pool_from_cache): Don't bother conditionally initializing the
cache; it will always be initialized when we are here.
([NSAutoreleasePool -dealloc]): Add assertion.
([NSAutoreleasePool -reallyDealloc]): New method.
Tue May 28 15:39:36 1996 Adam Fedor <fedor@wave.Colorado.edu>
* checks/nsmaptable.m: Check for nil map element.
* src/Invocation [Invocation -dealloc]: Release return_value
only if return_retained.
[ArgframeInvocation -dealloc]: Likewise.
Sat Jul 6 09:03:25 1996 Andrew McCallum <mccallum@cs.rochester.edu>
* Version (SUBMINOR_VERSION): gnustep-base version 0.2.2.
* doc/install.texi: Describe installation of pthreads.
* src/NSObject.m ([NSObject +initialize]): Use
o_map_with_callbacks(), instead of the short-cut function
o_map_of_non_owned_void_p_to_int().
* src/RunLoop.m ([RunLoop -acceptInputForMode:beforeDate:]): Add
comment about arbitrary fd port limit. Fix this eventually.
* checks/tcpport-client.m (main): When argc == 1, pass nil for
hostname instead of @"localhost".
* checks/string.m (main): Add test of copyWithZone.
* src/TcpPort.m ([TcpOutPacket
-_writeToSocket:withReplySockaddr:]): Use memcpy() instead of
cast; some systems have trouble with the cast due to alignment
issues. (Reported by Marc Decugis <mds@sepgifbr.sep.de.edf.fr>.)
([TcpInPacket +_getPacketSize:andReplyPort:fromSocket:inPort:]):
Likewise.
* configure.in: Clean up echo'ed message for shared library flags.
* gcc-objc.patch: New objc runtime patch from Scott Christley.
* Makefile.in (DIST_FILES): Include gcc-objc.patch instead of
objc.patch.
* doc/install.texi: Update instructions for new objc runtime
patch.
* src/Foundation/NSAutoreleasePool.h: Include <string.h> for
memset().
A first attempt at making NotificationDispatcher thread-safe.
* src/NotificationDispatcher.m ([NotificationDispatcher -init]):
Create _LOCK.
([NotificationDispatcher -dealloc]): New method.
([NotificationDispatcher
-_addObserver:notificationRequest:name:object:]): Use _LOCK to
provide thread-safety. Lock around all access to ivars.
([NotificationDispatcher -removeObserver:]): Likewise.
([NotificationDispatcher -removeObserver:name:object:]): Likewise.
([NotificationDispatcher -postNotification:]): Likewise. All
Notification postings are serialized. If this weren't true, the
user would have to worry about all kinds of thread-safety issues
in unpredictable ways, because there is no way to tell what other
objects have asked for notification postings.
* src/include/NotificationDispatcher.h (NotificationDispatcher
_lock): New ivar.
Fix error that occurs when using a TcpOutPort that was created
with a default hostname.
* src/TcpPort.m ([TcpInPort +newForReceivingFromPortNumber:]):
Terminate the hostname at the first dot before looking up with
gethostbyname(). If gethostbyname() fails, don't try again with
"localhost"; signal an error instead.
([TcpOutPort +newForSendingToPortNumber:onHost:]): When HOSTNAME is
empty or nil, don't use "localhost", look up the name of the local
machine, and use that. Before this change we could easily get
"Can't change reply port of an out port once set" errors.
Fri Jul 5 08:59:26 1996 Andrew McCallum <mccallum@cs.rochester.edu>
Use more-efficient o_map instead NSMapTable for retain counts.
* src/NSObject.m (retain_counts): Make it an o_map instead of
NSMapTable; (o_map is more efficient).
(NSIncrementExtraRefCount): Use o_map interface.
(NSDecrementExtraRefCountWasZero): Likewise.
([NSObject +initialize]): Likewise.
([NSObject -retainCount]): Likewise.
* src/o_map.m (o_map_node_for_key): New function, non-static, for
efficient implementation of NSObject retain count management.
(o_map_remove_node_from_its_map): Likewise.
Thu Jul 4 21:00:42 1996 Andrew McCallum <mccallum@cs.rochester.edu>
Make -retain/-release counts thread-safe.
* src/NSObject.m (retain_counts_gate): New static variable, mutex
for protecting RETAIN_COUNTS.
(NSIncrementExtraRefCount): Use it.
(NSDecrementExtraRefCountWasZero): Likewise.
([NSObject -retainCount]): Likewise.
([NSObject +initialize]): Allocate RETAIN_COUNTS_GATE.
Tue Jun 11 14:50:20 1996 Andrew McCallum <mccallum@pad>
Make NSAutoreleasePool thread-safe.
* src/include/NSAutoreleasePool.h (struct
autorelease_thread_vars): New structure declared.
(struct autorelease_cache): Structure declaration removed.
(init_autorelease_thread_vars): New static inline function.
* src/NSAutoreleasePool.m (ARP_THREAD_VARS): New macro for
accessing NSAutoreleasePool's per-thread variables.
(current_pool): Static variable removed.
(total_autoreleased_objects_count): Likewise.
(autorelease_pool_cache): Likewise.
(autorelease_pool_size): Likewise.
(autorelease_pool_count): Likewise.
(push_pool_to_cache): Add (struct autorelease_thread_vars*) argument.
All callers changed.
(pop_pool_from_cache): Likewise.
(push_pool_to_cache): Likewise.
(init_pool_cache): New function.
([NSAutoreleasePool +initialize]): Don't initialize the
autorelease_pool_cache here.
([NSAutoreleasePool +init]): Use per-thread variables.
([NSAutoreleasePool -autoreleaseCountForObject:]): Likewise.
([NSAutoreleasePool -currentPool:]): Likewise.
([NSAutoreleasePool +currentPool:]): Likewise.
([NSAutoreleasePool -addObject:]): Likewise.
([NSAutoreleasePool +addObject:]): Likewise.
([NSAutoreleasePool -dealloc:]): Likewise.
([NSAutoreleasePool +totalAutoreleasedObjects:]): Likewise. This
return value is now only a per-thread count.
([NSAutoreleasePool +resetTotalAutoreleasedObjects:]): Likewise.
* src/include/NSThread.h: Make the ivars @public, not @private, so
NSAutoreleasePool can efficiently access the _autorelease_vars
ivar.
(_autorelease_vars): New ivar.
* src/NSThread.m ([NSThread -init]): Instead of creating an
NSMutableDictionary here, just set the ivar `_thread_dictionary' to
nil, and create it later, only on demand. Use
`init_autorelease_thread_vars()' to initialize `_autorelease_vars'.
([NSThread -threadDictionary]): If `_thread_dictionary' is nil,
create it.
* checks/string.m (print_string): Use -cStringNoCopy instead of
-cString.
(main): Test the use of the `%@' printf format directive.
Implement handling of `%@' for non-GNU libc systems.
* src/NSString.m: Include <string.h>.
(PRINTF_ATSIGN_VA_LIST): Make it an expression that depends on the
libc version, not a boolean constant.
([NSString -initWithFormat:arguments:]): Implement the `%@' printf
directive in the case where the available libc doesn't have
`register_printf_function()'. It does not currently handle format
width specifiers, etc.
Mon Jun 10 23:22:58 1996 Andrew McCallum <mccallum@pad>
* src/gnustep/base/preface.h.in: Fix comment.
Mon Jun 3 12:07:16 1996 Andrew McCallum <mccallum@pad>
* src/Makefile.in (gnustep/base): Remove `gnustep' and `base'
before trying to recreate them.
Fri May 31 10:06:05 1996 Andrew McCallum <mccallum@cs.rochester.edu> Fri May 31 10:06:05 1996 Andrew McCallum <mccallum@cs.rochester.edu>

View file

@ -159,7 +159,7 @@ clean: mostlyclean
distclean: clean distclean: clean
rm -f Makefile rm -f Makefile
realclean: distclean maintainer-clean: distclean
rm -f gnustep-base.info version.texi \ rm -f gnustep-base.info version.texi \
README TODO INSTALL NEWS ANNOUNCE README TODO INSTALL NEWS ANNOUNCE

View file

@ -43,12 +43,10 @@ More information about the library, including a list of machines on
which it has been successfully compiled and used, can be found at which it has been successfully compiled and used, can be found at
@samp{http://www.cs.rochester.edu/u/mccallum/libgnustep-base}. @samp{http://www.cs.rochester.edu/u/mccallum/libgnustep-base}.
The library requires gcc @value{GNUSTEP_BASE_GCC_VERSION} or higher. The The library requires gcc @value{GNUSTEP_BASE_GCC_VERSION} or higher.
library does not work with the NEXTSTEP 3.2 compiler because that Significant sections of the library do not work with the NeXT runtime,
version of NeXT's cc cannot handle nested functions. Until a later so we recommend using gcc instead of NeXT's cc. See the @samp{INSTALL}
release from NeXT, NEXTSTEP users will have to install gcc. See the file for more instructions about compiling and installing the library.
@samp{INSTALL} file for more instructions about compiling and installing
the library.
The @samp{.tar} file is compressed with GNU gzip. Gzip can be obtained by The @samp{.tar} file is compressed with GNU gzip. Gzip can be obtained by
anonymous ftp at any of the GNU archive sites. anonymous ftp at any of the GNU archive sites.

View file

@ -1,8 +1,9 @@
The GNUstep Base Library is a library of general-purpose, non-graphical The GNUstep Base Library is a library of general-purpose, non-graphical
Objective C objects. For example, it includes classes for strings, Objective C objects. For example, it includes classes for strings,
collections, byte streams, typed coders, invocations, notifications, object collections, byte streams, typed coders, invocations,
notification dispatchers, times, network ports, remote object messaging notifications, notification dispatchers, moments in time, network ports,
support (distributed objects), event loops, and random number generators. remote object messaging support (distributed objects), event loops, and
random number generators.
It provides functionality that aims to implement the non-graphical It provides functionality that aims to implement the non-graphical
portion of the OpenStep standard. In many cases, the @samp{NS*} classes portion of the OpenStep standard. In many cases, the @samp{NS*} classes

View file

@ -25,7 +25,7 @@ contributions by Pascal Forget @email{pascal@@wsc.com}, Scott Christley
@email{scottc@@net-community.com}, and Randy Chapman @email{scottc@@net-community.com}, and Randy Chapman
@email{chapman@@u.washington.edu}. @email{chapman@@u.washington.edu}.
Last updated 26 March 1996. Last updated 10 July 1996.
The most up-to-date version of this FAQ is The most up-to-date version of this FAQ is
available at @url{ftp://ftp.cs.rochester.edu/pub/u/mccallum/gnustep-base}. available at @url{ftp://ftp.cs.rochester.edu/pub/u/mccallum/gnustep-base}.
Please send corrections to @email{mccallum@@gnu.ai.mit.edu}. Please send corrections to @email{mccallum@@gnu.ai.mit.edu}.
@ -54,7 +54,7 @@ The GNUstep project consists of the following sub-projects:
@itemize @bullet @itemize @bullet
@item GNU Objective C Compiler and Objective C Runtime Library - @item GNU Objective C Compiler and Objective C Runtime Library -
Although not actually a sub-project the GNUstep, GCC and the GNU Although not actually a component of GNUstep, GCC and the GNU
Objective C Runtime Library are integral to GNUstep, since they are used Objective C Runtime Library are integral to GNUstep, since they are used
to make every GNU Objective C program. to make every GNU Objective C program.
@ -171,8 +171,8 @@ Please send corrections to the FAQ maintainer.
@item @b{Is there a WWW site for GNUstep? Are there mailing lists for GNUstep?} @item @b{Is there a WWW site for GNUstep? Are there mailing lists for GNUstep?}
There is a WWW site at @url{http://www.GNUstep.org}, (and its mirror There is a WWW site at @url{http://www.gnustep.org}, (and its mirror
@url{http://www.NMR.EMBL-Heidelberg.DE/GNUstep}, that contains many @url{http://www.NMR.EMBL-Heidelberg.DE/gnustep}, that contains many
useful pointers. The technical information in this FAQ may be more up useful pointers. The technical information in this FAQ may be more up
to date than the WWW pages since this FAQ is maintained directly by the to date than the WWW pages since this FAQ is maintained directly by the
people who are developing GNUstep code. people who are developing GNUstep code.
@ -337,6 +337,25 @@ are currently thread-safe backends for DEC OSF/1, Solaris, IRIX, and
WindowsNT. Volunteers are solicited for writing additional back-ends, WindowsNT. Volunteers are solicited for writing additional back-ends,
especially one for Linux. especially one for Linux.
@item @b{Does it allow a mixture of Objective C and C++}
No. Unlike NeXT's @samp{cc}, GNU GCC does not support source files
containing both Objective C and C++. People at Cygnus have mentioned
that they would be willing to do the work---if they were paid for it, of
course. Several people are interested in seeing this happen. Send
email to @samp{discussion@gnustep.org} and
@samp{gnu-objc@prep.ai.mit.edu} if you are interesting in pushing this
issue, so that the efforts of all those people interested can be
coordinated.
Also, unlike NeXT's @samp{cc}, GNU GCC does not support the @samp{extern
"Objective-C"} construct.
@item @b{Where can I find more information?}
The FAQ associated with the newsgroup @samp{comp.lang.objective-c}
contains more information about GNU Objective C.
@end enumerate @end enumerate
@c GNU Compiler and Objective C Runtime Library @c GNU Compiler and Objective C Runtime Library
@ -347,16 +366,7 @@ especially one for Linux.
@item @b{What is the GNUstep Base Library?} @item @b{What is the GNUstep Base Library?}
The GNUstep Base Library is a library of general-purpose, non-graphical @include base-desc.texi
Objective C objects. For example, it includes classes for strings,
collections, byte streams, typed coders, invocations, notifications,
notification dispatchers, times, network ports, remote object messaging
support, event loops and random number generators.
It provides functionality that aims to implement the
@samp{FoundationKit} portion of the OpenStep standard. In many cases,
the @samp{NS*} classes are implemented as wrappers around more
featureful GNU classes.
There is more (although perhaps out-of-date) information available at There is more (although perhaps out-of-date) information available at
the GNUstep Base Library homepage at the GNUstep Base Library homepage at
@ -376,7 +386,7 @@ NSBitmapCharSet, NSBundle, NSCharacterSet, NSCoder, NSCountedSet,
NSData, NSDate, NSDictionary, NSEnumerator, NSException, NSInvocation, NSData, NSDate, NSDictionary, NSEnumerator, NSException, NSInvocation,
NSLock, NSMethodSignature, NSNotification, NSNotificationCenter, NSLock, NSMethodSignature, NSNotification, NSNotificationCenter,
NSNumber, NSObject, NSProcessInfo, NSRunLoop, NSSet, NSString, NSThread, NSNumber, NSObject, NSProcessInfo, NSRunLoop, NSSet, NSString, NSThread,
NSTimeZone, NSTimer, NSValue. NSTimeZone, NSTimer, NSUserDefaults, NSValue.
Most of the C functions are also implemented, including NSHashTable and Most of the C functions are also implemented, including NSHashTable and
NSMaptable. NSMaptable.
@ -387,7 +397,7 @@ not yet been made.
The following classes are unstarted or unusable: NSBTreeBlock, The following classes are unstarted or unusable: NSBTreeBlock,
NSBTreeCursor, NSByteStore, NSByteStoreFile, NSCalendarDate, NSBTreeCursor, NSByteStore, NSByteStoreFile, NSCalendarDate,
NSDeserializer, NSScanner, NSSerializer, NSUserDefaults. NSDeserializer, NSScanner, NSSerializer.
@item @b{In what ways is the Base Library different from OpenStep's FoundationKit?} @item @b{In what ways is the Base Library different from OpenStep's FoundationKit?}
@ -441,16 +451,13 @@ A third writes in an even more compact stream of machine-dependent bits;
this is useful for distributed objects connections on machines of the this is useful for distributed objects connections on machines of the
same architecture. same architecture.
I'm not sure how OpenStep's archiving system implements forward OpenStep's archiving system implements forward references, (that is,
references, (that is, calls to @samp{encodeConditionalObject:} for which calls to @samp{encodeConditionalObject:} for which the object argument
the object argument has not yet been encoded, but will be encoded has not yet been encoded, but will be encoded later.) by making two
later.) According to its restricted interface, NeXT's implementation passes through all the -encodeWithCoder: methods of the objects to be
must either (1) make two passes through all the -encodeWithCoder: encoded GNU's archiving system, on the other hand, implements forward
methods of the objects to be encoded, or (2) not handle forward references efficiently, without making two passes. It does this by
references with @samp{-encodeConditionalObject:}, only backward using an object decoding method (@samp{-decodeObjectAt:..}) that
references. GNU's archiving system, on the other hand, implements
forward references efficiently, without making two passes. It does this
by using an object decoding method (@samp{-decodeObjectAt:..}) that
back-patches @code{id}-pointers when the conditionally encoded objects back-patches @code{id}-pointers when the conditionally encoded objects
are found in the coded stream. are found in the coded stream.
@ -755,7 +762,8 @@ All remaining classes have stub implementations.
@item @b{Where can I get a copy?} @item @b{Where can I get a copy?}
It is not yet publically available. When it is available you will be It is not yet publically available. When it is available you will be
able to find it in @url{ftp://alpha.gnu.ai.mit.edu/gnu}. able to find it in @url{ftp://alpha.gnu.ai.mit.edu/gnu}. Pre-release
snapshots are available at @url{ftp://ocbi.com}.
@end enumerate @end enumerate
@c GNUstep GUI Library @c GNUstep GUI Library

View file

@ -15,25 +15,46 @@ as you preserve this copyright notice and permission notice.
To compile and install @samp{libgnustep-base}: To compile and install @samp{libgnustep-base}:
Here is a quick-and-dirty example of installation commands: @enumerate
First install the GNU Objective C runtime patch (objc.patch), possibly @item
like this: If you are running Linux, first install pthreads. gnustep-base has been
tested with pthreads-0.9.2. You can just copying the libaries from the
@file{lib} directory of the distribution to /usr/local/lib, and the
@file{pthreads} directory from the @file{include} directory of the
distribution to /usr/local/include. For example:
@example
cd pthreads-0.9.2/lib
tar -cf - * | (cd /usr/local/lib ; tar -xvf -)
cd ../include
tar -cf - pthreads | (cd /usr/local/include ; tar -xvf -)
cd /usr/local/include; ln -s pthreads/pthread.h .
mkdirs /usr/local/src/linux_threads/kits/pthreads-0.9.2/lib/pthreads
cd !$
ln /usr/local/lib/libpthreads.so.1 .
@end example
@item
Then install the GNU Objective C runtime patch (gcc-objc.patch),
possibly like this:
@example @example
cd gcc-2.7.2 cd gcc-2.7.2
patch -p0 <../gnustep-base/objc.patch rm -f objc/list.h
patch -p1 < ../gstep-base*/gcc-objc.patch
@end example @end example
and make and install gcc. Because the objc.patch is not quite @item
up-to-date, you will also have to make a link from @file{thread.h} to Make and install gcc, possibly like this:
@file{thr.h} in the objc include directory. For example:
@example @example
cd /usr/local/lib/gcc-lib/i586-unknown-linux/2.7.2/include/objc/ ./configure --prefix=/usr/local
ln -s thread.h thr.h make OBJC_THREAD_FILE=thr-pthreads
make install
@end example @end example
@item
Then configure and make libgnustep-base: Then configure and make libgnustep-base:
@example @example
@ -44,30 +65,26 @@ make install
If you are running GNU/Linux and have an older version of libc, then the If you are running GNU/Linux and have an older version of libc, then the
Objective C runtime will not work unless you pass @samp{-lieee} to the Objective C runtime will not work unless you pass @samp{-lieee} to the
linker. You can do that like this: linker. If you use the pthreads library that will also have to be
linked in. You can do that like this:
@example @example
LIBS=-lieee ./configure --prefix=/usr/local LIBS="-lieee -lpthreads" ./configure --prefix=/usr/local
make make
make install make install
@end example @end example
@item
If you have trouble with the Makefile, it may be that our makefiles use If you have trouble with the Makefile, it may be that our makefiles use
features that your @code{make} does not support; use GNU make. features that your @code{make} does not support; use GNU make.
Here are instructions that describe more options. @end enumerate
Here are general instructions for @file{configure}, that explain
@file{configure}'s options.
@enumerate @enumerate
@item
Patch the @samp{gcc} Objective C runtime with objc.patch. These changes
will be part of @samp{gcc} version 2.8.0, but 2.8.0 hasn't been released
yet.
@item
Install @samp{gcc}. The library requires gcc version
@value{GNUSTEP_BASE_GCC_VERSION} or later.
@item @item
Configure the package for your system. In the directory that this file Configure the package for your system. In the directory that this file
is in, type @samp{./configure}. If you're using @samp{csh} on an old is in, type @samp{./configure}. If you're using @samp{csh} on an old

View file

@ -1,6 +1,8 @@
@c set the vars GNUSTEP_BASE_VERSION and GNUSTEP_BASE_GCC_VERSION @c set the vars GNUSTEP_BASE_VERSION and GNUSTEP_BASE_GCC_VERSION
@include version.texi @include version.texi
THIS INFORMATION IS OUT-OF-DATE.
The library requires gcc @value{GNUSTEP_BASE_GCC_VERSION} or higher. The The library requires gcc @value{GNUSTEP_BASE_GCC_VERSION} or higher. The
library does not work with the NEXTSTEP 3.2 compiler because that library does not work with the NEXTSTEP 3.2 compiler because that
version of NeXT's cc cannot handle nested functions. Until a later version of NeXT's cc cannot handle nested functions. Until a later

View file

@ -21,6 +21,16 @@ thread-safe features to the GNU Objective C runtime.
are sent back to the client. Ungracefully closed connections are are sent back to the client. Ungracefully closed connections are
gracefully handled. gracefully handled.
@item NSUserDefaults has been implemented, thanks to Georg Tuparev
<tuparev@@NMR.EMBL-Heidelberg.DE>.
@item Preliminary thread-safety work has been done. NSObject and
NSAutoreleasePool should be thread-safe.
@item The "%@@" printf directive now works on systems without GNU libc.
@item The NS*Page* functions have been implemented.
@item The mframe and behavior functions have been overhauled and @item The mframe and behavior functions have been overhauled and
better commented. better commented.

View file

@ -9,8 +9,8 @@ Here is some introductory info to get you started:
@section Initial reading @section Initial reading
The file @samp{ANNOUNCE} contains a very brief overview of the library. The file @file{doc/GNUstep-FAQ} contains a brief overview of the
It also tells you where to get the most recent version. library. It also tells you where to get the most recent version.
The file @samp{NEWS} has the library's feature history. The file @samp{NEWS} has the library's feature history.
@ -21,42 +21,42 @@ The file @samp{INSTALL} gives instructions for installing the library.
The documentation isn't much to speak of so far. Better documentation The documentation isn't much to speak of so far. Better documentation
will be forthcoming, but the library needs to settle first. For now I will be forthcoming, but the library needs to settle first. For now I
recommend skipping @file{gnustep-base.info} and reading the header files recommend skipping @file{gnustep-base.info} and reading the header files
instead. The headers for the classes are in @file{./src/include} and instead. The headers for the classes are in @file{./src/include}.
@file{./src/objc}.
The GNUstep FAQ also contains much useful information, including an The GNUstep FAQ contains an outline of the class heirarchy, as well as a
outline of the class heirarchy. The FAQ can be found in list of the differences between GNUstep and NeXT's implementation of
@file{./doc/GNUstep-FAQ}. OpenStep, and GNUstep's improvements over NeXT's implementation. The
FAQ can be found in @file{doc/GNUstep-FAQ}.
Preliminary documentation is available via @samp{texinfo} in the files Outdated, preliminary documentation is available via @samp{texinfo} in
@samp{gnustep-base.info} and @samp{gnustep-base.texi}. Because texinfo the files @samp{gnustep-base.info} and @samp{gnustep-base.texi}.
doesn't yet handle @code{@@deftypemethod}, this documentation cannot yet Because texinfo doesn't yet handle @code{@@deftypemethod}, this
be compiled into more readable forms. documentation cannot yet be compiled into more readable forms.
@section Overview of the classes @section Overview of the classes
[This section badly needs updating -mccallum Apr 17 1996.] Here is partial list of non-OpenStep classes, grouped by functionality.
The GNU classes included in this version of the library fall into six There are several GNU-specific protocols also. You can recognize the
categories: collections, strings, magnitudes, streams, coders and protocols by their name: they all end with ``ing''.
distributed object support.
@c There are several GNU protocols also. You can recognize the protocols
@c by their name: they all end with ``ing''.
@itemize @bullet @itemize @bullet
@item The collection objects all conform to the @samp{Collecting} @item The collection objects all conform to the @samp{Collecting}
protocol. Reading @samp{./objects/Collecting.h} is a good place to protocol. Reading @samp{src/include/Collecting.h} is a good place to
start. Protocols for collections that store their contents with keys start. Protocols for collections that store their contents with keys
and with indices can be found in @samp{./objects/KeyedCollecting.h} and and with indices can be found in @samp{src/incliude/KeyedCollecting.h} and
@samp{./objects/IndexedCollecting.h} respectively. Examples of generic @samp{src/include/IndexedCollecting.h} respectively. Examples of generic
collections are @samp{Set} and @samp{Bag}. The keyed collections are collections are @samp{Set} and @samp{Bag}. The keyed collections are
@samp{Dictionary} and @samp{MappedCollector}. The classes @samp{Array}, @samp{Dictionary} and @samp{MappedCollector}. The classes @samp{Array},
@samp{Queue}, @samp{GapArray}, @samp{LinkedList}, @samp{BinaryTree}, @samp{Queue}, @samp{GapArray}, @samp{LinkedList}, @samp{BinaryTree},
@samp{RBTree} and @samp{SplayTree} are all indexed collections. @samp{RBTree} and @samp{SplayTree} are all indexed collections.
@item The string objects... [unfinished]. @item The string objects conform to the @samp{String} protocol.
@samp{CString} provides an interface to strings based on ASCII bytes,
and is currently the only concrete subclass of String. The interface
between GNU @samp{String} and OpenStep's @samp{NSString} needs cleaning
up and will change. For now, I recommend using @samp{NSString}.
@item The public magnitude classes are @samp{Time} and @samp{Random}. @item The public magnitude classes are @samp{Time} and @samp{Random}.
The @samp{Random} class works in conjunction with pseudo-random number The @samp{Random} class works in conjunction with pseudo-random number
@ -66,57 +66,56 @@ BSD random() function. The class @samp{RNGAdditiveCongruential} is an
implementation of the additive congruential method. implementation of the additive congruential method.
@item Stream objects provide a consistent interface for reading and @item Stream objects provide a consistent interface for reading and
writing bytes. Read @samp{./objects/Stream.h} to get the general idea. writing bytes. Read @samp{src/include/Stream.h} to get the general
@samp{StdioStream} objects work with files, file descriptors, FILE idea. @samp{StdioStream} objects work with files, file descriptors,
pointers and pipes to/from executables. @samp{MemoryStream} objects FILE pointers and pipes to/from executables. @samp{MemoryStream}
work with memory buffers. objects work with memory buffers.
@item Coders provide a formatted way of writing to Streams. After a @item CStream objects provide a way to write C variables to Stream
coder is initialized with a stream, the coder can encode/decode objects. Read @file{src/include/CStream.h} to understand the interface
Objective C objects and C types in an architecture-independent way. See of the abstract superclass. @samp{TextCStream} writes C variables in a
@samp{./objects/Coder.h} for the abstract superclass interface; see human-readable ASCII format that can be manipulated with a text editor
@samp{./objects/Coding.h} for the protocol adopted by objects that read or with your choice of text-processing programs, like @samp{awk} or
and write themselves using coders. The currently available concrete @samp{perl}. @samp{BinaryCStream} writes C variables in a compact,
coder classes are @samp{BinaryCoder}, for reading and writing a compact illegible stream of bytes. @samp{TextCStream} and @samp{BinaryCStream}
stream of illegible bytes, and @samp{TextCoder}, for reading and writing each write in machine-independant formats---so you can write on one
human-readable text (which you can also process with @samp{perl}, machine architecture, and successfully read on another.
@samp{awk}, or whatever scripting language you like). @samp{RawCStream} is like @samp{BinaryCStream} accept it is
machine-dependant; it useful for efficient Distributed Objects
connections on the same machine.
Coders and streams can be mixed and matched so that programmers can @item Coders provide a formatted way of writing Objective C objects to
choose the destination and the format separately. CStream objects. After a coder is initialized with a stream, the coder
can encode/decode interconnected webs of Objective C objects and C types
and successfully keep track of complex interconnections between objects.
See @samp{src/include/Coder.h} for the abstract superclass interface;
see @samp{src/include/Coding.h} for the protocol adopted by objects that
read and write themselves using coders. @samp{Archiver} and
@samp{Unarchiver} are concrete subclasses that are used for
writing/reading with files.
Neither the stream or coder class heirarchies are very mature yet. I @samp{Coder}s and @samp{CStream}s and @samp{Stream}s can be mixed and
threw them together because I needed them for distributed objects. matched so that programmers can choose the destination and the format
separately.
@ignore
@item @samp{Notification}
@samp{NotificationDispatcher}
@end ignore
@item The distributed object support classes are @samp{Connection}, @item The distributed object support classes are @samp{Connection},
@samp{Proxy}, @samp{ConnectedCoder}, @samp{Port} and @samp{SocketPort}. @samp{Proxy}, @samp{ConnectedCoder}, @samp{Port} and @samp{TcpPort}.
This version of the distributed objects only works with sockets. A Mach This version of the distributed objects only works with sockets. A Mach
port back-end should be on the way. port back-end should be on the way.
[NOTE: The GNU distributed object facilities have the same ease-of-use See @file{doc/GNUstep-FAQ} for a detailed description of the cabilities
as NeXT's; be warned, however, that they are not compatible with each and non-capabilities of GNU Distributed Objects.
other. They have different class heirarchies, different instance
variables, different method names, different implementation strategies
and different network message formats. You cannot communicate with a
NeXT NXConnection using a GNU Connection. The GNU distributed object
code does not work with the NeXT Objective C runtime. NXConnection
creates NXProxy objects for local objects as well as remote objects; GNU
Connection doesn't need and doesn't create proxies for local objects.
NXProxy asks it's remote target for the method encoding types and caches
the results; GNU Proxy gets the types directly from the local GNU "typed
selector" mechanism and has no need for querying the remote target or
caching encoding types. The NXProxy for the remote root object always
has name 0 and, once set, you cannot change the root object of a
NXConnection; the GNU Proxy for the remote root object has a target
address value just like all other Proxy's, and you can change the root
object as many times as you like. See the "lacking-capabilities" list
below for a partial list of things that NXConnection can do that GNU
Connection cannot.]
To begin using distributed objects, you only need to know about To begin using distributed objects, you only need to know about
@samp{Connection} class. You can see the full interface in @samp{Connection} class. You can see the full (documented!) interface
@samp{./objects/Connection.h}. The long list of methods may be a little in @samp{src/include/Connection.h}. The long list of methods may be a
daunting, but actually, a lot can be done with just a few key methods: little daunting, but actually, a lot can be done with just a few key
methods:
@smallexample @smallexample
- (Connection*) newRegisteringAtName: name - (Connection*) newRegisteringAtName: name
@ -139,7 +138,7 @@ daunting, but actually, a lot can be done with just a few key methods:
@subsection Examples @subsection Examples
A few simple example programs can be found in @samp{./examples}. A few simple example programs can be found in @samp{examples}.
Read and enjoy. To compile them (after having compiled the library), Read and enjoy. To compile them (after having compiled the library),
type @samp{make} in the @samp{examples} directory. type @samp{make} in the @samp{examples} directory.
@ -182,7 +181,7 @@ takers?
@itemize @bullet @itemize @bullet
@item Read the projects and questions in the @samp{TODO} file. If you @item Read the projects and questions in the @samp{TODO} file. If you
can volunteer for any of the projects, or if you have any useful can volunteer for any of the projects, or if you have any useful
comments send me email! <mccallum@@gnu.ai.mit.edu> comments send me email! <mccallum@@gnu.ai.mit.edu>

View file

@ -30,7 +30,7 @@ VPATH = @srcdir@
CC = @CC@ CC = @CC@
CFLAGS = -Wall -Wno-implicit -g -O CFLAGS = -Wall -Wno-implicit -Wno-format -g -O
CPPFLAGS = CPPFLAGS =
LDFLAGS = LDFLAGS =
@ -113,7 +113,7 @@ clean: mostlyclean
distclean: clean distclean: clean
rm -f Makefile config.status rm -f Makefile config.status
realclean: distclean maintainer-clean: distclean
rm -f TAGS rm -f TAGS
copy-dist: $(DIST_FILES) copy-dist: $(DIST_FILES)

View file

@ -1,49 +1,40 @@
/* A simple demonstration of the GNU Dictionary object. /* A simple demonstration of the GNU Dictionary object.
In this example the Dictionary holds int's which are keyed by strings. */ In this example the Dictionary holds int's which are keyed by strings. */
#include <gnustep/base/all.h>
#include <gnustep/base/Dictionary.h> #include <gnustep/base/Dictionary.h>
#include <Foundation/NSValue.h>
#include <Foundation/NSString.h>
#warning This file has not been updated for the new collection classes
#if 0
int main() int main()
{ {
id d; id d;
/* Create a Dictionary object that will store int's with string keys */ /* Create a Dictionary object. */
d = [[Dictionary alloc] d = [[Dictionary alloc] initWithCapacity: 32];
initWithType:@encode(int)
keyType:@encode(char*)];
/* Load the dictionary with some items */ /* Load the dictionary with some items */
[d putElement:1 atKey:"one"]; [d putObject: [NSNumber numberWithInt: 1] atKey: @"one"];
[d putElement:2 atKey:"two"]; [d putObject: [NSNumber numberWithInt: 2] atKey: @"two"];
[d putElement:3 atKey:"three"]; [d putObject: [NSNumber numberWithInt: 3] atKey: @"three"];
[d putElement:4 atKey:"four"]; [d putObject: [NSNumber numberWithInt: 4] atKey: @"four"];
[d putElement:5 atKey:"five"]; [d putObject: [NSNumber numberWithInt: 5] atKey: @"five"];
[d putElement:6 atKey:"six"]; [d putObject: [NSNumber numberWithInt: 6] atKey: @"six"];
printf("There are %u elements stored in the dictionary\n", printf("There are %u elements stored in the dictionary\n",
[d count]); [d count]);
printf("Element %d is stored at \"%s\"\n", printf("Element %d is stored at \"%s\"\n",
[d elementAtKey:"three"].int_u, "three"); [[d objectAtKey: @"three"] intValue],
"three");
printf("Removing element stored at \"three\"\n"); printf("Removing element stored at \"three\"\n");
[d removeElementAtKey:"three"]; [d removeObjectAtKey: @"three"];
printf("Removing element 2\n"); printf("Removing element 2\n");
[d removeElement:2]; [d removeObject: [NSNumber numberWithInt: 2]];
printf("Now there are %u elements stored in the dictionary\n", printf("Now there are %u elements stored in the dictionary\n",
[d count]); [d count]);
exit(0); exit(0);
} }
#else
int main()
{
exit (0);
}
#endif /* 0 */

View file

@ -18,7 +18,7 @@ id announce_new_connection (id notification)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
id server; static id server;
id a1; id a1;
id remote_array; id remote_array;
char namebuf[16]; char namebuf[16];
@ -69,7 +69,7 @@ int main(int argc, char *argv[])
/* Cause an exception, and watch it return to us. */ /* Cause an exception, and watch it return to us. */
NS_DURING NS_DURING
{ {
id o = [remote_array objectAtIndex: 99]; [remote_array objectAtIndex: 99];
} }
NS_HANDLER NS_HANDLER
{ {

View file

@ -6,6 +6,8 @@
#include <gnustep/base/Notification.h> #include <gnustep/base/Notification.h>
#include <gnustep/base/Invocation.h> #include <gnustep/base/Invocation.h>
/* This function will be called by an Invocation object that will be
registered to fire every time an InPort accepts a new client. */
id announce_new_port (id notification) id announce_new_port (id notification)
{ {
id in_port = [notification object]; id in_port = [notification object];
@ -17,6 +19,8 @@ id announce_new_port (id notification)
return nil; return nil;
} }
/* This function will be called by an Invocation object that will be
registered to fire every time an InPort client disconnects. */
id announce_broken_port (id notification) id announce_broken_port (id notification)
{ {
id in_port = [notification object]; id in_port = [notification object];
@ -28,6 +32,8 @@ id announce_broken_port (id notification)
return nil; return nil;
} }
/* The implementation of the object that will be registered with D.O.
as the server. */
@implementation SecondServer @implementation SecondServer
- init - init

View file

@ -77,7 +77,7 @@ int main()
[array printForDebugger]; [array printForDebugger];
[dictionary printForDebugger]; [dictionary printForDebugger];
/* Relase the objects we read */ /* Release the objects we read */
[array release]; [array release];
[dictionary release]; [dictionary release];

View file

@ -25,7 +25,41 @@
#define __NSAutoreleasePool_h_GNUSTEP_BASE_INCLUDE #define __NSAutoreleasePool_h_GNUSTEP_BASE_INCLUDE
#include <gnustep/base/preface.h> #include <gnustep/base/preface.h>
#include <string.h> /* for memset() */
@class NSAutoreleasePool;
/* Each thread has its own copy of these variables.
A pointer to this structure is an ivar of NSThread. */
struct autorelease_thread_vars
{
/* The current, default NSAutoreleasePool for the calling thread;
the one that will hold objects that are arguments to
[NSAutoreleasePool +addObject:]. */
NSAutoreleasePool *current_pool;
/* The total number of objects autoreleased since the thread was
started, or since -resetTotalAutoreleasedObjects was called
in this thread. */
unsigned total_objects_count;
/* A cache of NSAutoreleasePool's already alloc'ed. Caching old pools
instead of deallocating and re-allocating them will save time. */
id *pool_cache;
int pool_cache_size;
int pool_cache_count;
};
/* Initialize an autorelease_thread_vars structure for a new thread.
This function is called in NSThread each time an NSThread is created. */
static inline void
init_autorelease_thread_vars (struct autorelease_thread_vars *tv)
{
memset (tv, 0, sizeof (typeof (*tv)));
}
/* Each pool holds its objects-to-be-released in a linked-list of /* Each pool holds its objects-to-be-released in a linked-list of
these structures. */ these structures. */
struct autorelease_array_list struct autorelease_array_list
@ -36,22 +70,15 @@ struct autorelease_array_list
id objects[0]; id objects[0];
}; };
/* This structure holds a per-thread cache of NSAutoreleasePool objects,
so they don't have to be alloc/dealloc'ed each time. */
struct autorelease_cache
{
id *cache;
int cache_size;
int cache_count;
};
@interface NSAutoreleasePool : NSObject @interface NSAutoreleasePool : NSObject
{ {
/* For re-setting the current pool when we are dealloc'ed. */ /* For re-setting the current pool when we are dealloc'ed. */
NSAutoreleasePool *_parent; NSAutoreleasePool *_parent;
/* This necessary for co-existing with exceptions. */ /* This pointer to our child pool is necessary for co-existing
with exceptions. */
NSAutoreleasePool *_child; NSAutoreleasePool *_child;
/* An collection of the objects to be released. */ /* A collection of the objects to be released. */
struct autorelease_array_list *_released; struct autorelease_array_list *_released;
struct autorelease_array_list *_released_head; struct autorelease_array_list *_released_head;
/* The total number of objects autoreleased in this pool. */ /* The total number of objects autoreleased in this pool. */

View file

@ -29,6 +29,7 @@
#include <objc/thr.h> #include <objc/thr.h>
#include <Foundation/NSDictionary.h> #include <Foundation/NSDictionary.h>
#include <Foundation/NSDate.h> #include <Foundation/NSDate.h>
#include <Foundation/NSAutoreleasePool.h> // for struct autorelease_thread_vars
typedef enum typedef enum
{ {
@ -39,10 +40,10 @@ typedef enum
@interface NSThread : NSObject @interface NSThread : NSObject
{ {
@private @public
_objc_thread_t _thread_id; _objc_thread_t _thread_id;
NSMutableDictionary *_thread_dictionary; NSMutableDictionary *_thread_dictionary;
id _thread_autorelease_pool; struct autorelease_thread_vars _autorelease_vars;
} }
+ (NSThread*) currentThread; + (NSThread*) currentThread;

View file

@ -61,6 +61,7 @@
#include <gnustep/base/Array.h> #include <gnustep/base/Array.h>
#include <Foundation/NSMapTable.h> #include <Foundation/NSMapTable.h>
#include <gnustep/base/NSString.h> #include <gnustep/base/NSString.h>
#include <Foundation/NSLock.h>
@interface NotificationDispatcher : NSObject @interface NotificationDispatcher : NSObject
{ {
@ -78,6 +79,9 @@
/* The keys are observers; the values are Array's containing all /* The keys are observers; the values are Array's containing all
NotificationInvocation objects associated with the observer key. */ NotificationInvocation objects associated with the observer key. */
NSMapTable *_observer_2_nr_array; NSMapTable *_observer_2_nr_array;
/* A mutex lock for making the ivars thread-safe. */
NSRecursiveLock *_lock;
} }

View file

@ -27,11 +27,11 @@
#include <gnustep/base/preface.h> #include <gnustep/base/preface.h>
#include <gnustep/base/Port.h> #include <gnustep/base/Port.h>
#include <gnustep/base/RunLoop.h> #include <gnustep/base/RunLoop.h>
#ifndef WIN32 #ifndef __WIN32__
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netdb.h> #include <netdb.h>
#endif /* !WIN32 */ #endif /* !__WIN32__ */
#include <Foundation/NSMapTable.h> #include <Foundation/NSMapTable.h>
/* A concrete implementation of a Port object implemented on top of /* A concrete implementation of a Port object implemented on top of

View file

@ -29,10 +29,10 @@
#include <gnustep/base/preface.h> #include <gnustep/base/preface.h>
#include <gnustep/base/Magnitude.h> #include <gnustep/base/Magnitude.h>
#ifndef WIN32 #ifndef __WIN32__
#include <sys/time.h> #include <sys/time.h>
#include <sys/resource.h> #include <sys/resource.h>
#endif #endif /* !__WIN32__ */
#ifdef _SEQUENT_ #ifdef _SEQUENT_
/* Include needed for getclock() in our replacement for gettimeofday() */ /* Include needed for getclock() in our replacement for gettimeofday() */

View file

@ -54,14 +54,14 @@
#include <objc/objc-api.h> #include <objc/objc-api.h>
#include <objc/encoding.h> #include <objc/encoding.h>
#include <objc/sarray.h> #include <objc/sarray.h>
#include <objc/objc-list.h> /* #include <objc/objc-list.h> */
#endif #endif
#include <Foundation/NSObject.h> #include <Foundation/NSObject.h>
#include <gnustep/base/objc-malloc.h> #include <gnustep/base/objc-malloc.h>
@class String; @class String;
/* The following group of lines are maintained by the libobjects Makefile */ /* The following group of lines maintained by the gstep-base src/Makefile */
#define @VERSION@ #define @VERSION@
#define @MAJOR_VERSION@ #define @MAJOR_VERSION@
#define @MINOR_VERSION@ #define @MINOR_VERSION@

View file

@ -50,7 +50,7 @@ DIST_FILES = \
COPYING COPYING.LIB ChangeLog \ COPYING COPYING.LIB ChangeLog \
configure Version \ configure Version \
config.guess mkinstalldirs install-sh \ config.guess mkinstalldirs install-sh \
NSBundle.README objc.patch NSBundle.README gcc-objc.patch
all: src all: src
@ -90,7 +90,7 @@ maintainer-clean-top:
mostlyclean: mostlyclean-top mostlyclean-subdirs mostlyclean: mostlyclean-top mostlyclean-subdirs
clean: mostlyclean-top clean-subdirs clean: mostlyclean-top clean-subdirs
distclean: clean-top distclean-subdirs distclean: clean-top distclean-subdirs
maintainer-clean: distclean-top maintainer-clean-subdirs maintainer-clean: maintainer-clean-subdirs distclean-top
snap: $(DIST_FILES) snap: $(DIST_FILES)
rm -rf snap rm -rf snap

View file

@ -72,6 +72,7 @@ mostlyclean:
rm -f *~ rm -f *~
clean: mostlyclean clean: mostlyclean
distclean: clean distclean: clean
rm -f Makefile
maintainer-clean: distclean maintainer-clean: distclean
copy-dist: $(DIST_FILES) copy-dist: $(DIST_FILES)

View file

@ -21,7 +21,7 @@ with which I compiled the program:
gcc NSExceptionTest.m -L/usr/local/lib -lobjects -lobjc -L/usr/ucblib -lucb -lm gcc NSExceptionTest.m -L/usr/local/lib -lobjects -lobjc -L/usr/ucblib -lucb -lm
Apparently, there are some serious bugs in the ucblib files. I Apparently, there are some serious bugs in the ucblib files. I
changed the lin\ e to changed the line to
gcc NSExceptionTest.m -L/usr/local/lib -lobjects -lobjc -lm -lnsl gcc NSExceptionTest.m -L/usr/local/lib -lobjects -lobjc -lm -lnsl

View file

@ -3,5 +3,3 @@ list of what's changed, and the old and new names.
The `o-*' file names have been changed to `o_*' to better match their The `o-*' file names have been changed to `o_*' to better match their
function names and the GNU standards. function names and the GNU standards.
The %@ printf directive only works if you are using the GNU C library.

View file

@ -29,10 +29,10 @@
#include <gnustep/base/MallocAddress.h> #include <gnustep/base/MallocAddress.h>
#include <Foundation/NSException.h> #include <Foundation/NSException.h>
#include <math.h> #include <math.h>
#ifndef WIN32 #ifndef __WIN32__
#include <values.h> // This gets BITSPERBYTE on Solaris #include <values.h> // This gets BITSPERBYTE on Solaris
#include <netinet/in.h> // for byte-conversion #include <netinet/in.h> // for byte-conversion
#endif /* !WIN32 */ #endif /* !__WIN32__ */
#define DEFAULT_FORMAT_VERSION 0 #define DEFAULT_FORMAT_VERSION 0

View file

@ -244,7 +244,7 @@
- (void) dealloc - (void) dealloc
{ {
if (*return_type == _C_ID) if (return_retained && *return_type == _C_ID)
[*(id*)return_value release]; [*(id*)return_value release];
OBJC_FREE(return_type); OBJC_FREE(return_type);
[super dealloc]; [super dealloc];
@ -457,7 +457,7 @@ my_method_get_next_argument (arglist_t argframe,
while ((datum = my_method_get_next_argument(argframe, &tmptype))) while ((datum = my_method_get_next_argument(argframe, &tmptype)))
{ {
tmptype = objc_skip_type_qualifiers (tmptype); tmptype = objc_skip_type_qualifiers (tmptype);
if (*tmptype == _C_ID) if (args_retained && *tmptype == _C_ID)
[*(id*)datum release]; [*(id*)datum release];
} }
[self _deallocArgframe]; [self _deallocArgframe];

View file

@ -392,6 +392,7 @@ NSThread.m \
NSTimer.m \ NSTimer.m \
NSTimeZone.m \ NSTimeZone.m \
NSUser.m \ NSUser.m \
NSUserDefaults.m \
NSValue.m \ NSValue.m \
NSZone.m NSZone.m
@ -461,6 +462,7 @@ include/NSSet.h \
include/NSString.h \ include/NSString.h \
include/NSThread.h \ include/NSThread.h \
include/NSTimer.h \ include/NSTimer.h \
include/NSUserDefaults.h \
include/NSUtilities.h \ include/NSUtilities.h \
include/NSValue.h \ include/NSValue.h \
include/NSZone.h \ include/NSZone.h \
@ -472,8 +474,9 @@ OBJS_INSTALL = @OBJS_INSTALL@
OBJS_INSTALL_PIC = $(OBJS_INSTALL:${OEXT}=_pic${OEXT}) OBJS_INSTALL_PIC = $(OBJS_INSTALL:${OEXT}=_pic${OEXT})
DIST_FILES = \ DIST_FILES = \
Makefile.in AUTHORS \ Makefile.in AUTHORS Makefile.sed.nt\
include/config.h.in include/preface.h.in \ include/config.h.in include/preface.h.in \
include/config-win32.h include/config-win32.sed \
$(GNU_MFILES) \ $(GNU_MFILES) \
$(GNU_CFILES) \ $(GNU_CFILES) \
$(GNU_HEADERS) \ $(GNU_HEADERS) \
@ -509,6 +512,7 @@ lib$(LIBRARY_NAME)$(LIBEXT): $(HEADERS_INSTALL) $(OBJS_INSTALL)
# Local links to the include files # Local links to the include files
gnustep/base: gnustep/base:
rm -f gnustep base
ln -s . gnustep ln -s . gnustep
ln -s ./include base ln -s ./include base
# Make necessary links to source headers if compiling in seperate dir # Make necessary links to source headers if compiling in seperate dir
@ -546,7 +550,6 @@ install: installdirs all
done done
$(INSTALL_DATA) include/config.h $(includedir)/gnustep/base/config.h $(INSTALL_DATA) include/config.h $(includedir)/gnustep/base/config.h
cd $(includedir); rm -f Foundation; ln -s ./gnustep/base ./Foundation 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 . cd $(includedir)/objc; rm -f README; ln -s ../include/README .
installdirs: installdirs:

View file

@ -25,32 +25,28 @@
#include <Foundation/NSAutoreleasePool.h> #include <Foundation/NSAutoreleasePool.h>
#include <gnustep/base/objc-malloc.h> #include <gnustep/base/objc-malloc.h>
#include <Foundation/NSException.h> #include <Foundation/NSException.h>
#include <Foundation/NSThread.h>
#include <limits.h> #include <limits.h>
/* TODO: /* TODO:
Doesn't work multi-threaded. 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 /* When this is `NO', autoreleased objects are never actually recorded
in an NSAutoreleasePool, and are not sent a `release' message. in an NSAutoreleasePool, and are not sent a `release' message.
Thus memory for objects use grows, and grows, and... */ Thus memory for objects use grows, and grows, and... */
static BOOL autorelease_enabled = YES; static BOOL autorelease_enabled = YES;
/* When the _released_count of the current pool gets over this value, /* When the _released_count of a pool gets over this value, we raise
we raise an exception. This can be adjusted with -setPoolCountThreshhold */ an exception. This can be adjusted with -setPoolCountThreshhold */
static unsigned pool_count_warning_threshhold = UINT_MAX; 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. */ /* The size of the first _released array. */
#define BEGINNING_POOL_SIZE 32 #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) @interface NSAutoreleasePool (Private)
- _parentAutoreleasePool; - _parentAutoreleasePool;
@ -61,28 +57,37 @@ static unsigned total_autoreleased_objects_count = 0;
- (void) _setChildPool: pool; - (void) _setChildPool: pool;
@end @end
/* A cache of NSAutoreleasePool's already alloc'ed. Caching old pools
instead of deallocating and re-allocating them will save time. */ /* Functions for managing a per-thread cache of NSAutoreleasedPool's
static id *autorelease_pool_cache; already alloc'ed. The cache is kept in the autorelease_thread_var
static int autorelease_pool_cache_size = 32; structure, which is an ivar of NSThread. */
static int autorelease_pool_cache_count = 0;
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 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; tv->pool_cache_size *= 2;
OBJC_REALLOC (autorelease_pool_cache, id, autorelease_pool_cache_size); 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 static id
pop_pool_from_cache () pop_pool_from_cache (struct autorelease_thread_vars *tv)
{ {
assert (autorelease_pool_cache_count); assert (tv->pool_cache_count);
return autorelease_pool_cache[--autorelease_pool_cache_count]; return tv->pool_cache[--(tv->pool_cache_count)];
} }
@ -91,17 +96,18 @@ pop_pool_from_cache ()
+ (void) initialize + (void) initialize
{ {
if (self == [NSAutoreleasePool class]) 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, /* If there is an already-allocated NSAutoreleasePool available,
save time by just returning that, rather than allocating a new one. */ save time by just returning that, rather than allocating a new one. */
if (autorelease_pool_cache_count) struct autorelease_thread_vars *tv = ARP_THREAD_VARS;
return pop_pool_from_cache (); if (tv->pool_cache_count)
return pop_pool_from_cache (tv);
return NSAllocateObject (self, 0, z); return NSAllocateObject (self, 0, zone);
} }
- init - init
@ -130,10 +136,13 @@ pop_pool_from_cache ()
_released_count = 0; _released_count = 0;
/* Install ourselves as the current pool. */ /* Install ourselves as the current pool. */
_parent = current_pool; {
_child = nil; struct autorelease_thread_vars *tv = ARP_THREAD_VARS;
[current_pool _setChildPool: self]; _parent = tv->current_pool;
current_pool = self; _child = nil;
[tv->current_pool _setChildPool: self];
tv->current_pool = self;
}
return self; return self;
} }
@ -181,10 +190,12 @@ pop_pool_from_cache ()
} }
/* This method not in OpenStep */ /* 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) autoreleaseCountForObject: anObject
{ {
unsigned count = 0; unsigned count = 0;
id pool = current_pool; id pool = ARP_THREAD_VARS->current_pool;
while (pool) while (pool)
{ {
count += [pool autoreleaseCountForObject: anObject]; count += [pool autoreleaseCountForObject: anObject];
@ -195,12 +206,12 @@ pop_pool_from_cache ()
+ currentPool + currentPool
{ {
return current_pool; return ARP_THREAD_VARS->current_pool;
} }
+ (void) addObject: anObj + (void) addObject: anObj
{ {
[current_pool addObject: anObj]; [ARP_THREAD_VARS->current_pool addObject: anObj];
} }
- (void) addObject: anObj - (void) addObject: anObj
@ -246,7 +257,7 @@ pop_pool_from_cache ()
/* Keep track of the total number of objects autoreleased across all /* Keep track of the total number of objects autoreleased across all
pools. */ pools. */
total_autoreleased_objects_count++; ARP_THREAD_VARS->total_objects_count++;
/* Keep track of the total number of objects autoreleased in this pool */ /* Keep track of the total number of objects autoreleased in this pool */
_released_count++; _released_count++;
@ -303,13 +314,32 @@ pop_pool_from_cache ()
} }
} }
/* Uninstall ourselves as the current pool; install our parent pool. */ {
current_pool = _parent; struct autorelease_thread_vars *tv;
if (current_pool) NSAutoreleasePool **cp;
current_pool->_child = nil;
/* Don't deallocate ourself, just save us for later use. */ /* Uninstall ourselves as the current pool; install our parent pool. */
push_pool_to_cache (self); 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 - autorelease
@ -321,12 +351,12 @@ pop_pool_from_cache ()
+ (void) resetTotalAutoreleasedObjects + (void) resetTotalAutoreleasedObjects
{ {
total_autoreleased_objects_count = 0; ARP_THREAD_VARS->total_objects_count = 0;
} }
+ (unsigned) totalAutoreleasedObjects + (unsigned) totalAutoreleasedObjects
{ {
return total_autoreleased_objects_count; return ARP_THREAD_VARS->total_objects_count;
} }
+ (void) enableRelease: (BOOL)enable + (void) enableRelease: (BOOL)enable

View file

@ -24,7 +24,7 @@
#include <assert.h> #include <assert.h>
#ifndef WIN32 #ifndef __WIN32__
#include <unistd.h> #include <unistd.h>
#include <sys/param.h> /* Needed by sys/stat */ #include <sys/param.h> /* Needed by sys/stat */
#endif #endif

View file

@ -29,12 +29,14 @@
#include <Foundation/NSDate.h> #include <Foundation/NSDate.h>
#include <Foundation/NSString.h> #include <Foundation/NSString.h>
#ifndef __WIN32__
#include <time.h> #include <time.h>
#endif /* !__WIN32__ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#ifndef WIN32 #ifndef __WIN32__
#include <sys/time.h> #include <sys/time.h>
#endif /* WIN32 */ #endif /* !__WIN32__ */
/* The number of seconds between 1/1/2001 and 1/1/1970 = -978307200. */ /* The number of seconds between 1/1/2001 and 1/1/1970 = -978307200. */
/* This number comes from: /* This number comes from:

View file

@ -30,7 +30,7 @@
#include <Foundation/NSInvocation.h> #include <Foundation/NSInvocation.h>
#include <Foundation/NSAutoreleasePool.h> #include <Foundation/NSAutoreleasePool.h>
#include <Foundation/NSString.h> #include <Foundation/NSString.h>
#include <Foundation/NSMapTable.h> #include <gnustep/base/o_map.h>
#include <Foundation/NSException.h> #include <Foundation/NSException.h>
#include <limits.h> #include <limits.h>
@ -39,20 +39,29 @@ extern void (*_objc_error)(id object, const char *format, va_list);
/* Reference count management */ /* Reference count management */
/* Doesn't handle multi-threaded stuff. /* Handles multi-threaded access.
Doesn't handle exceptions. */ ?? Doesn't handle exceptions. */
/* The hashtable of retain counts on objects */ /* The maptable of retain counts on objects */
static NSMapTable *retain_counts = NULL; 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; static id autorelease_class = nil;
/* When this is `YES', every call to release/autorelease, checks to make sure /* When this is `YES', every call to release/autorelease, checks to
isn't being set up to release itself too many times. */ 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; static BOOL double_release_check_enabled = NO;
BOOL NSShouldRetainWithZone(NSObject *anObject, NSZone *requestedZone) BOOL
NSShouldRetainWithZone (NSObject *anObject, NSZone *requestedZone)
{ {
if (!requestedZone || [anObject zone] == requestedZone) if (!requestedZone || [anObject zone] == requestedZone)
return YES; return YES;
@ -60,58 +69,52 @@ BOOL NSShouldRetainWithZone(NSObject *anObject, NSZone *requestedZone)
return NO; return NO;
} }
void NSIncrementExtraRefCount (id anObject) void
NSIncrementExtraRefCount (id anObject)
{ {
unsigned c = (unsigned) NSMapGet (retain_counts, anObject); o_map_node_t *node;
NSMapInsert (retain_counts, anObject, (void*)c+1); 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: */ objc_mutex_lock (retain_counts_gate);
#if 0 node = o_map_node_for_key (retain_counts, anObject);
coll_node_ptr n; if (node)
((int)(node->value))++;
n = coll_hash_node_for_key(retain_counts, anObject);
if (n)
(n->value.unsigned_int_u)++;
else else
coll_hash_add(&retain_counts, anObject, (unsigned)1); o_map_at_key_put_value_known_absent (retain_counts, anObject, (void*)1);
#endif 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) objc_mutex_lock (retain_counts_gate);
return YES; node = o_map_node_for_key (retain_counts, anObject);
if (!node)
c--; {
if (c) objc_mutex_unlock (retain_counts_gate);
NSMapInsert (retain_counts, anObject, (void*)c); return YES;
else }
NSMapRemove (retain_counts, anObject); assert ((int)(node->value) > 0);
if (!--((int)(node->value)))
o_map_remove_node (node);
objc_mutex_unlock (retain_counts_gate);
return NO; 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 @implementation NSObject
+ (void) initialize + (void) initialize
{ {
if (self == [NSObject class]) if (self == [NSObject class])
{ {
retain_counts = NSCreateMapTable (NSNonOwnedPointerOrNullMapKeyCallBacks, retain_counts = o_map_with_callbacks (o_callbacks_for_non_owned_void_p,
NSIntMapValueCallBacks, 64); o_callbacks_for_int);
retain_counts_gate = objc_mutex_allocate ();
autorelease_class = [NSAutoreleasePool class]; autorelease_class = [NSAutoreleasePool class];
} }
return; return;
@ -433,7 +436,12 @@ BOOL NSDecrementExtraRefCountWasZero (id anObject)
- (unsigned) retainCount - (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 + (unsigned) retainCount
@ -451,12 +459,10 @@ BOOL NSDecrementExtraRefCountWasZero (id anObject)
return NSZoneFromPtr(self); return NSZoneFromPtr(self);
} }
#if 1 /* waiting until I resolve type conflict with GNU Coding method */
- (void) encodeWithCoder: (NSCoder*)aCoder - (void) encodeWithCoder: (NSCoder*)aCoder
{ {
return; return;
} }
#endif
- initWithCoder: (NSCoder*)aDecoder - initWithCoder: (NSCoder*)aDecoder
{ {
@ -465,6 +471,7 @@ BOOL NSDecrementExtraRefCountWasZero (id anObject)
@end @end
@implementation NSObject (NEXTSTEP) @implementation NSObject (NEXTSTEP)
/* NEXTSTEP Object class compatibility */ /* NEXTSTEP Object class compatibility */
@ -581,6 +588,7 @@ BOOL NSDecrementExtraRefCountWasZero (id anObject)
@end @end
@implementation NSObject (GNU) @implementation NSObject (GNU)
/* GNU Object class compatibility */ /* GNU Object class compatibility */

View file

@ -22,12 +22,18 @@
*/ */
#include <gnustep/base/preface.h> #include <gnustep/base/preface.h>
#ifndef __WIN32__
#include <unistd.h> #include <unistd.h>
#endif
#include <stdio.h> #include <stdio.h>
#if __mach__ #if __mach__
#include <mach.h> #include <mach.h>
#endif #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 /* Cache the size of a memory page here, so we don't have to make the
getpagesize() system call repeatedly. */ getpagesize() system call repeatedly. */
static unsigned ns_page_size = 0; static unsigned ns_page_size = 0;

View file

@ -53,10 +53,10 @@
*************************************************************************/ *************************************************************************/
/* One of these two should have MAXHOSTNAMELEN */ /* One of these two should have MAXHOSTNAMELEN */
#ifndef WIN32 #ifndef __WIN32__
#include <sys/param.h> #include <sys/param.h>
#include <netdb.h> #include <netdb.h>
#endif /* WIN32 */ #endif /* !__WIN32__ */
#include <string.h> #include <string.h>
#include <Foundation/NSString.h> #include <Foundation/NSString.h>

View file

@ -44,6 +44,7 @@
#include <gnustep/base/String.h> #include <gnustep/base/String.h>
#include <gnustep/base/behavior.h> #include <gnustep/base/behavior.h>
#include <limits.h> #include <limits.h>
#include <string.h> // for strstr()
@implementation NSString @implementation NSString
@ -100,9 +101,13 @@ static Class NSMutableString_c_concrete_class;
#include <printf.h> #include <printf.h>
#include <stdarg.h> #include <stdarg.h>
/* <sattler@volker.cs.Uni-Magdeburg.DE>, with libc-5.3.9 thinks this /* <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 */ flag PRINTF_ATSIGN_VA_LIST should be 0, but for me, with libc-5.0.9,
#define PRINTF_ATSIGN_VA_LIST 1 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 #if ! PRINTF_ATSIGN_VA_LIST
static int static int
@ -112,7 +117,7 @@ arginfo_func (const struct printf_info *info,
*argtypes = PA_POINTER; *argtypes = PA_POINTER;
return 1; return 1;
} }
#endif #endif /* !PRINTF_ATSIGN_VA_LIST */
static int static int
handle_printf_atsign (FILE *stream, handle_printf_atsign (FILE *stream,
@ -135,7 +140,7 @@ handle_printf_atsign (FILE *stream,
#if PRINTF_ATSIGN_VA_LIST #if PRINTF_ATSIGN_VA_LIST
string_object = va_arg (*ap_pointer, id); string_object = va_arg (*ap_pointer, id);
#else #else
string_object = *((id *) ptr); string_object = *((id*) ptr);
#endif #endif
len = fprintf(stream, "%*s", len = fprintf(stream, "%*s",
(info->left ? - info->width : info->width), (info->left ? - info->width : info->width),
@ -297,21 +302,64 @@ handle_printf_atsign (FILE *stream,
/* xxx Change this when we have non-CString classes */ /* xxx Change this when we have non-CString classes */
- (id) initWithFormat: (NSString*)format - (id) initWithFormat: (NSString*)format
arguments: (va_list)argList arguments: (va_list)arg_list
{ {
#if HAVE_VSPRINTF #if HAVE_VSPRINTF
#define BUFFER_EXTRA 1024
const char *format_cp = [format cStringNoCopy]; const char *format_cp = [format cStringNoCopy];
int format_len = strlen (format_cp); int format_len = strlen (format_cp);
char buf[format_len + BUFFER_EXTRA]; /* xxx horrible disgusting, fix this! */ /* xxx horrible disgusting BUFFER_EXTRA arbitrary limit; fix this! */
int printed_len; #define BUFFER_EXTRA 1024
char buf[format_len + BUFFER_EXTRA];
int printed_len = 0;
printed_len = vsprintf (buf, format_cp, argList); #if ! HAVE_REGISTER_PRINTF_FUNCTION
/* Signal error if we overran our buffer. */ /* 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); NSParameterAssert (printed_len < format_len + BUFFER_EXTRA - 1);
return [self initWithCString:buf]; return [self initWithCString:buf];
#else #else /* HAVE_VSPRINTF */
[self notImplemented:_cmd]; [self notImplemented: _cmd];
return self; return self;
#endif #endif
} }

View file

@ -48,6 +48,7 @@ static o_map_t thread_id_2_nsthread;
/* Flag indicating whether the objc runtime ever went multi-threaded. */ /* Flag indicating whether the objc runtime ever went multi-threaded. */
static BOOL entered_multi_threaded_state; static BOOL entered_multi_threaded_state;
@implementation NSThread @implementation NSThread
// Class initialization // Class initialization
@ -72,8 +73,8 @@ static BOOL entered_multi_threaded_state;
[super init]; [super init];
/* initialize our ivars. */ /* initialize our ivars. */
_thread_dictionary = [NSMutableDictionary dictionary]; _thread_dictionary = nil; // Initialize this later only when needed
_thread_autorelease_pool = nil; init_autorelease_thread_vars (&_autorelease_vars);
/* Make it easy and fast to get this NSThread object from the thread. */ /* Make it easy and fast to get this NSThread object from the thread. */
objc_thread_set_data (self); objc_thread_set_data (self);
@ -137,6 +138,8 @@ static BOOL entered_multi_threaded_state;
- (NSMutableDictionary*) threadDictionary - (NSMutableDictionary*) threadDictionary
{ {
if (!_thread_dictionary)
_thread_dictionary = [NSMutableDictionary dictionary];
return _thread_dictionary; return _thread_dictionary;
} }

View file

@ -24,19 +24,26 @@
#include <gnustep/base/preface.h> #include <gnustep/base/preface.h>
#include <Foundation/NSString.h> #include <Foundation/NSString.h>
#include <stdlib.h> // for getenv() #include <stdlib.h> // for getenv()
#ifndef __WIN32__
#include <unistd.h> // for getlogin() #include <unistd.h> // for getlogin()
#include <pwd.h> // for getpwnam() #include <pwd.h> // for getpwnam()
#endif
#include <sys/types.h> #include <sys/types.h>
/* Return the caller's login name as an NSString object. */ /* Return the caller's login name as an NSString object. */
NSString * NSString *
NSUserName () NSUserName ()
{ {
#ifndef __WIN32__
const char *login_name = getlogin (); const char *login_name = getlogin ();
if (login_name) if (login_name)
return [NSString stringWithCString: login_name]; return [NSString stringWithCString: login_name];
else else
return nil; return nil;
#else
return nil;
#endif /* __WIN32__ */
} }
/* Return the caller's home directory as an NSString object. */ /* Return the caller's home directory as an NSString object. */
@ -50,7 +57,11 @@ NSHomeDirectory ()
NSString * NSString *
NSHomeDirectoryForUser (NSString *login_name) NSHomeDirectoryForUser (NSString *login_name)
{ {
#ifndef __WIN32__
struct passwd *pw; struct passwd *pw;
pw = getpwnam ([login_name cStringNoCopy]); pw = getpwnam ([login_name cStringNoCopy]);
return [NSString stringWithCString: pw->pw_dir]; return [NSString stringWithCString: pw->pw_dir];
#else
return nil;
#endif
} }

View file

@ -182,7 +182,8 @@
@implementation NotificationDispatcher @implementation NotificationDispatcher
/* The default instance, most often the only one created. /* 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; static NotificationDispatcher *default_notification_dispatcher = nil;
+ (void) initialize + (void) initialize
@ -219,9 +220,21 @@ static NotificationDispatcher *default_notification_dispatcher = nil;
NSCreateMapTable (NSNonOwnedPointerOrNullMapKeyCallBacks, NSCreateMapTable (NSNonOwnedPointerOrNullMapKeyCallBacks,
NSObjectMapValueCallBacks, 0); NSObjectMapValueCallBacks, 0);
_lock = [NSRecursiveLock new];
return self; 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. */ /* Adding new observers. */
@ -237,6 +250,8 @@ static NotificationDispatcher *default_notification_dispatcher = nil;
if (!observer) if (!observer)
return; return;
[_lock lock];
/* Record the notification request in an array keyed by OBSERVER. */ /* Record the notification request in an array keyed by OBSERVER. */
{ {
/* Find the array of all the requests 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]; [nr_list appendObject: nr];
} }
[_lock unlock];
} }
- (void) addInvocation: (id <Invoking>)invocation - (void) addInvocation: (id <Invoking>)invocation
@ -435,6 +452,8 @@ static NotificationDispatcher *default_notification_dispatcher = nil;
if (!observer) if (!observer)
return; return;
[_lock lock];
/* Get the array of NotificationRequest's associated with OBSERVER. */ /* Get the array of NotificationRequest's associated with OBSERVER. */
observer_nr_array = NSMapGet (_observer_2_nr_array, 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, associated with OBSERVER. This also releases the observer_nr_array,
and its contents. */ and its contents. */
NSMapRemove (_observer_2_nr_array, observer); 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. */ /* 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. */ /* Get the list of NotificationRequest's associated with OBSERVER. */
observer_nr_array = NSMapGet (_observer_2_nr_array, 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 /* xxx If there are some LinkedList's that are empty, I should
remove them from the map table's. */ remove them from the map table's. */
} }
[_lock unlock];
} }
@ -526,6 +551,8 @@ static NotificationDispatcher *default_notification_dispatcher = nil;
[NSException raise: NSInvalidArgumentException [NSException raise: NSInvalidArgumentException
format: @"Tried to post a notification with no name."]; format: @"Tried to post a notification with no name."];
[_lock lock];
/* Post the notification to all the observers that specified neither /* Post the notification to all the observers that specified neither
NAME or OBJECT. */ NAME or OBJECT. */
if ([_anonymous_nr_list count]) if ([_anonymous_nr_list count])
@ -566,6 +593,8 @@ static NotificationDispatcher *default_notification_dispatcher = nil;
} }
END_FOR_COLLECTION (nr_list); END_FOR_COLLECTION (nr_list);
} }
[_lock unlock];
} }
- (void) postNotificationName: (id <String>)name - (void) postNotificationName: (id <String>)name

View file

@ -59,9 +59,9 @@
#include <Foundation/NSValue.h> #include <Foundation/NSValue.h>
#include <Foundation/NSAutoreleasePool.h> #include <Foundation/NSAutoreleasePool.h>
#include <Foundation/NSTimer.h> #include <Foundation/NSTimer.h>
#ifndef WIN32 #ifndef __WIN32__
#include <sys/time.h> #include <sys/time.h>
#endif /* !WIN32 */ #endif /* !__WIN32__ */
#include <limits.h> #include <limits.h>
#include <string.h> /* for memset() */ #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. */ want us to listen to; add these to FD_LISTEN_SET. */
for (i = [ports count]-1; i >= 0; i--) 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]; int port_fd_array[port_fd_count];
port = [ports objectAtIndex: i]; port = [ports objectAtIndex: i];
if ([port respondsTo: @selector(getFds:count:)]) if ([port respondsTo: @selector(getFds:count:)])
@ -376,7 +376,10 @@ static RunLoop *current_run_loop;
abort (); abort ();
} }
else if (select_return == 0) else if (select_return == 0)
return; {
NSFreeMapTable (fd_2_object);
return;
}
/* Look at all the file descriptors select() says are ready for reading; /* Look at all the file descriptors select() says are ready for reading;
notify the corresponding object for each of the ready fd's. */ notify the corresponding object for each of the ready fd's. */

View file

@ -40,16 +40,16 @@
#include <Foundation/NSDate.h> #include <Foundation/NSDate.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#ifndef WIN32 #ifndef __WIN32__
#include <unistd.h> /* for gethostname() */ #include <unistd.h> /* for gethostname() */
#include <sys/param.h> /* for MAXHOSTNAMELEN */ #include <sys/param.h> /* for MAXHOSTNAMELEN */
#include <arpa/inet.h> /* for inet_ntoa() */ #include <arpa/inet.h> /* for inet_ntoa() */
#endif /* !WIN32 */ #endif /* !__WIN32__ */
#include <string.h> /* for memset() */ #include <string.h> /* for memset() and strchr() */
#ifndef WIN32 #ifndef __WIN32__
#include <sys/time.h> #include <sys/time.h>
#include <sys/resource.h> #include <sys/resource.h>
#endif #endif /* !__WIN32__ */
/* On some systems FD_ZERO is a macro that uses bzero(). /* On some systems FD_ZERO is a macro that uses bzero().
Just define it to use GCC's builtin memset(). */ Just define it to use GCC's builtin memset(). */
@ -224,7 +224,7 @@ static NSMapTable* port_number_2_port;
abort (); 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 machine so that, when we encoded our _LISTENING_ADDRESS for a
Distributed Objects connection to another machine, they get our Distributed Objects connection to another machine, they get our
unique host address that can identify us across the network. */ unique host address that can identify us across the network. */
@ -233,12 +233,15 @@ static NSMapTable* port_number_2_port;
perror ("[TcpInPort +newForReceivingFromPortNumber:] gethostname()"); perror ("[TcpInPort +newForReceivingFromPortNumber:] gethostname()");
abort (); abort ();
} }
/* Terminate the name at the first dot. */
{
char *first_dot = strchr (hostname, '.');
if (first_dot)
*first_dot = '\0';
}
hp = gethostbyname (hostname); hp = gethostbyname (hostname);
if (!hp) if (!hp)
/* xxx This won't work with port connections on a network, though. [self error: "Could not get address of local host \"%s\"", hostname];
Fix this. Perhaps there is a better way of getting the address
of the local host. */
hp = gethostbyname ("localhost");
assert (hp); assert (hp);
memcpy (&(p->_listening_address.sin_addr), hp->h_addr, hp->h_length); 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; struct hostent *hp;
const char *host_cstring; const char *host_cstring;
struct sockaddr_in addr; struct sockaddr_in addr;
/* Only used if no hostname is passed in. */
char local_hostname[MAXHOSTNAMELEN];
/* Look up the hostname. */ /* Look up the hostname. */
if (!hostname || ![hostname length]) 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 else
host_cstring = [hostname cStringNoCopy]; host_cstring = [hostname cStringNoCopy];
hp = gethostbyname ((char*)host_cstring); hp = gethostbyname ((char*)host_cstring);
@ -1093,7 +1111,6 @@ static NSMapTable *out_port_bag = NULL;
{ {
char prefix_buffer[PREFIX_SIZE]; char prefix_buffer[PREFIX_SIZE];
int c; int c;
struct sockaddr_in *addr;
c = read (s, prefix_buffer, PREFIX_SIZE); c = read (s, prefix_buffer, PREFIX_SIZE);
if (c == 0) 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 /* 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. */ doesn't already have its _address ivar set, then set it now. */
{ {
addr = (struct sockaddr_in*) (prefix_buffer + PREFIX_LENGTH_SIZE); struct sockaddr_in addr;
if (addr->sin_family) /* 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 withAcceptedSocket: s
pollingInPort: ip]; 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 /* 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. */ region. If there is no reply address specified, fill it with zeros. */
if (addr) 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 else
memset (buffer + PREFIX_LENGTH_SIZE, 0, PREFIX_ADDRESS_SIZE); memset (buffer + PREFIX_LENGTH_SIZE, 0, PREFIX_ADDRESS_SIZE);

View file

@ -31,8 +31,10 @@
#endif #endif
#if HAVE_TIMES #if HAVE_TIMES
#ifndef __WIN32__
#include <sys/times.h> #include <sys/times.h>
#endif #endif /* !__WIN32__ */
#endif /* HAVE_TIMES */
/* There are several places where I need to deal with tz more intelligently */ /* There are several places where I need to deal with tz more intelligently */
/* I should allow customization of a strftime() format string for printing. */ /* I should allow customization of a strftime() format string for printing. */
@ -64,6 +66,37 @@ int gettimeofday(tvp, tzp)
} }
#endif /* _SEQUENT_ */ #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() */ /* tmp for passing to gettimeofday() */
static struct timeval _Time_tv; static struct timeval _Time_tv;
static struct timezone _Time_tz; static struct timezone _Time_tz;

View file

@ -31,16 +31,16 @@
#include <gnustep/base/ConnectedCoder.h> #include <gnustep/base/ConnectedCoder.h>
#include <gnustep/base/String.h> #include <gnustep/base/String.h>
#include <assert.h> #include <assert.h>
#ifndef WIN32 #ifndef __WIN32__
#include <sys/param.h> /* for MAXHOSTNAMELEN */ #include <sys/param.h> /* for MAXHOSTNAMELEN */
#endif /* !WIN32 */ #endif /* !__WIN32__ */
#if _AIX #if _AIX
#include <sys/select.h> #include <sys/select.h>
#endif /* _AIX */ #endif /* _AIX */
#ifndef WIN32 #ifndef __WIN32__
#include <netdb.h> #include <netdb.h>
#include <sys/time.h> #include <sys/time.h>
#endif /* !WIN32 */ #endif /* !__WIN32__ */
@interface UdpInPort (Private) @interface UdpInPort (Private)
@end @end

View file

@ -32,7 +32,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#ifdef WIN32 #ifdef __WIN32__
#include <limits.h> #include <limits.h>
#define S_IFLNK 0120000 #define S_IFLNK 0120000
int readlink(char *path, char *buf, int bufsiz) { return (-1); } 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/file.h>
#include <sys/param.h> #include <sys/param.h>
#include <unistd.h> #include <unistd.h>
#endif /* WIN32 */ #endif /* __WIN32__ */
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>

View file

@ -322,6 +322,23 @@ _o_map_node_for_key(o_map_t *map, const void *key)
return node; 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... **/ /** Callbacks... **/
/* Return a hash index for MAP. Needed for the callbacks below. */ /* Return a hash index for MAP. Needed for the callbacks below. */

View file

@ -59,7 +59,7 @@ WINBOOL WINAPI DLLMain(HANDLE hInst, ULONG ul_reason_for_call,
#endif /* __MS_WIN32__ */ #endif /* __MS_WIN32__ */
/* Initialize the GNUstep Base Library runtime structures */ /* Initialize the GNUstep Base Library runtime structures */
init_gnustep_base_runtime(); gnustep_base_init_runtime();
printf("GNUstep Base Library: process attach\n"); printf("GNUstep Base Library: process attach\n");
} }
@ -77,7 +77,7 @@ WINBOOL WINAPI DLLMain(HANDLE hInst, ULONG ul_reason_for_call,
#endif /* __MS_WIN32__ */ #endif /* __MS_WIN32__ */
/* Initialize the Library? -not for threads? */ /* Initialize the Library? -not for threads? */
init_gnustep_base_runtime(); gnustep_base_init_runtime();
printf("GNUstep Base Library: thread attach\n"); printf("GNUstep Base Library: thread attach\n");
} }
@ -89,3 +89,6 @@ WINBOOL WINAPI DLLMain(HANDLE hInst, ULONG ul_reason_for_call,
return TRUE; return TRUE;
} }

View file

@ -94,7 +94,8 @@ nstimer.m \
coder.m \ coder.m \
cstream.m \ cstream.m \
fref.m \ fref.m \
basic.m basic.m \
release.m
tcpport: FORCE tcpport: FORCE
(cd ../src; $(MAKE)) (cd ../src; $(MAKE))
@ -168,7 +169,7 @@ clean: mostlyclean
distclean: clean distclean: clean
rm -f Makefile config.status rm -f Makefile config.status
realclean: distclean maintainer-clean: distclean
rm -f TAGS rm -f TAGS
copy-dist: $(DIST_FILES) copy-dist: $(DIST_FILES)

View file

@ -11,6 +11,8 @@ s/OEXT = .o/OEXT = .obj/
s/LIBEXT = .a/LIBEXT = .lib/ s/LIBEXT = .a/LIBEXT = .lib/
s/@DEFS@/-DSTDC_HEADERS=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_TIMES=1 -DHAVE_VSPRINTF=1 -Dvm_page_size=4096/ s/@DEFS@/-DSTDC_HEADERS=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_TIMES=1 -DHAVE_VSPRINTF=1 -Dvm_page_size=4096/
/%: %$(OEXT)/,/$(CC) $(ALL_CFLAGS) $@$(OEXT)/c\ /%: %$(OEXT)/,/$(CC) $(ALL_CFLAGS) $@$(OEXT)/c\
LINK_CMD = nm $@$(OEXT) | grep " __GLOBAL_" > tmpinit.c \& collect tmpinit.c init_$@ \& $(CC) -c init_$@.c \& rm tmpinit.c \& ld $@$(OEXT) init_$@$(OEXT) -o $@$(EXEEXT) $(ALL_LDFLAGS)\ LINK_CMD = nm $@$(OEXT) | grep " __GLOBAL_" > tmpinit.c \& collect tmpinit.c $@_init_runtime \& $(CC) -c $@_init_runtime.c \& rm tmpinit.c \& ld $@$(OEXT) $@_init_runtime$(OEXT) -o $@$(EXEEXT) $(ALL_LDFLAGS)\
%: %$(OEXT) ../src/lib$(LIBRARY_NAME)$(LIBEXT)\ %: %$(OEXT) ../src/lib$(LIBRARY_NAME)$(LIBEXT)\
$(LINK_CMD) $(LINK_CMD)
s/clean: mostlyclean/clean: mostlyclean\
rm *_init_runtime.*/

View file

@ -69,11 +69,11 @@ int main(int argc, char *argv[])
/* Read in the Array */ /* Read in the Array */
[archiver decodeObjectAt: &array withName: &name]; [archiver decodeObjectAt: &array withName: &name];
printf("got object named %@\n", name); printf ("got object named %s\n", [name cStringNoCopy]);
/* Read in the Dictionary */ /* Read in the Dictionary */
[archiver decodeObjectAt: &dictionary withName: &name]; [archiver decodeObjectAt: &dictionary withName: &name];
printf("got object named %@\n", name); printf ("got object named %s\n", [name cStringNoCopy]);
/* Display what we read, to make sure it matches what we wrote */ /* Display what we read, to make sure it matches what we wrote */
[array printForDebugger]; [array printForDebugger];

View file

@ -24,7 +24,7 @@ int main()
{ {
id o, e = [set objectEnumerator]; id o, e = [set objectEnumerator];
while ((o = [e nextObject])) while ((o = [e nextObject]))
printf("%@\n", o); printf("%s\n", [o cStringNoCopy]);
} }
/* Write it to a file */ /* Write it to a file */
@ -50,7 +50,7 @@ int main()
{ {
id o, e = [set objectEnumerator]; id o, e = [set objectEnumerator];
while ((o = [e nextObject])) while ((o = [e nextObject]))
printf("%@\n", o); printf("%s\n", [o cStringNoCopy]);
} }
/* Do the autorelease. */ /* Do the autorelease. */

View file

@ -50,9 +50,13 @@ int main ()
[[o description] cString], [[o description] cString],
[[(id)NSMapGet (mt, o) description] cString]); [[(id)NSMapGet (mt, o) description] cString]);
NSMapRemove (mt, o); NSMapRemove (mt, o);
printf ("after removing: value for key %s is %s\n", if (NSMapGet (mt, o))
[[o description] cString], printf ("after removing: value for key %s is %s\n",
[[(id)NSMapGet (mt, o) description] cString]); [[o description] cString],
[[(id)NSMapGet (mt, o) description] cString]);
else
printf ("after removing: no value for key %s\n",
[[o description] cString]);
me = NSEnumerateMapTable (mt); me = NSEnumerateMapTable (mt);
while (NSNextMapEnumeratorPair (&me, &k, &v)) while (NSNextMapEnumeratorPair (&me, &k, &v))

View file

@ -6,9 +6,12 @@
void void
print_string(NSString* s) print_string(NSString* s)
{ {
printf("The string [%s], length %d\n", [s cString], [s length]); printf("The string [%s], length %d\n", [s cStringNoCopy], [s length]);
} }
#include <Foundation/NSString.h>
int main() int main()
{ {
id s = @"This is a test string"; id s = @"This is a test string";
@ -16,6 +19,9 @@ int main()
print_string(s); print_string(s);
s2 = [s copyWithZone: NS_NOZONE];
print_string(s2);
s2 = [s stringByAppendingString:@" with something added"]; s2 = [s stringByAppendingString:@" with something added"];
print_string(s2); print_string(s2);
@ -24,6 +30,11 @@ int main()
withString:@"changed"]; withString:@"changed"];
print_string(s2); print_string(s2);
/* Test the use of the `%@' format directive. */
s2 = [NSString stringWithFormat: @"foo %@ bar",
@"test"];
print_string(s2);
#if 0 #if 0
/* An example of treating a string like a Collection: /* An example of treating a string like a Collection:
Increment each char. */ Increment each char. */

View file

@ -27,7 +27,7 @@ int main (int argc, char *argv[])
onHost: @"localhost"]; onHost: @"localhost"];
else else
out_port = [TcpOutPort newForSendingToRegisteredName: @"tcpport-test" out_port = [TcpOutPort newForSendingToRegisteredName: @"tcpport-test"
onHost: @"localhost"]; onHost: nil];
in_port = [TcpInPort newForReceiving]; in_port = [TcpInPort newForReceiving];

View file

@ -6,7 +6,7 @@ GCC_VERSION = 2.7.2
# The version number of this release. # The version number of this release.
MAJOR_VERSION = 0 MAJOR_VERSION = 0
MINOR_VERSION = 2 MINOR_VERSION = 2
SUBMINOR_VERSION = 1 SUBMINOR_VERSION = 6
VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION)
#FTP_MACHINE = prep.ai.mit.edu #FTP_MACHINE = prep.ai.mit.edu

View file

@ -53,8 +53,8 @@ touch 12
echo "include subdirectory" echo "include subdirectory"
cd include cd include
rm -f config.h rm -f config.h
sed -f config-nt.sed config.h.in >>config.h sed -f config-win32.sed config.h.in >>config.h
cat config-nt.h >>config.h cat config-win32.h >>config.h
cd .. cd ..
cd .. cd ..

View file

@ -252,7 +252,7 @@ AC_SUBST(SHARED_LIBRARY)
# What flags to pass for making a shared library? # What flags to pass for making a shared library?
# xxx This should be smarter and more general # xxx This should be smarter and more general
#-------------------------------------------------------------------- #--------------------------------------------------------------------
echo Checking what flags to use for making a shared lib... echo Checking for flags to use when making a shared lib...
if ($srcdir/config.guess | grep solaris); then if ($srcdir/config.guess | grep solaris); then
CFLAGS_SHAREDLIB='$(CFLAGS_SHAREDLIB_SOLARIS)' CFLAGS_SHAREDLIB='$(CFLAGS_SHAREDLIB_SOLARIS)'
else else