diff --git a/ChangeLog b/ChangeLog index 1ed653368..bab1aaa93 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,30 @@ +2002-08-20 Richard Frith-Macdonald + + * Source/GSCountedSet.m: + * Source/NSAutoreleasePool.m: + * Source/NSCharacterSet.m: + * Source/NSCountedSet.m: + * Source/NSData.m: + * Source/NSDebug.m: + * Source/NSDictionary.m: + * Source/NSFileHandle.m: + * Source/NSLock.m: + * Source/NSNull.m: + * Source/NSNumber.m: + * Source/NSObject.m: + * Source/NSPipe.m: + * Source/NSScanner.m: + * Source/NSSerializer.m: + * Source/NSSet.m: + * Source/NSString.m: + * Source/NSThread.m: + * Source/NSTimeZone.m: + * Source/Additions/GSMime.m: + * Headers/gnustep/base/NSBundle.h: + * Headers/gnustep/base/NSRange.h: + * Headers/gnustep/base/NSSet.h: + Modify comments to include gsdoc documentation for autogsdoc. + 2002-08-19 Richard Frith-Macdonald * Source/NSProxy.m: Documented all methods and corrected implementation diff --git a/Headers/gnustep/base/NSBundle.h b/Headers/gnustep/base/NSBundle.h index 2cceb86a5..fcae95ec1 100644 --- a/Headers/gnustep/base/NSBundle.h +++ b/Headers/gnustep/base/NSBundle.h @@ -3,23 +3,23 @@ Written by: Adam Fedor Date: 1995 - + This file is part of the GNUstep Base Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. - + You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. - */ + */ #ifndef __NSBundle_h_GNUSTEP_BASE_INCLUDE #define __NSBundle_h_GNUSTEP_BASE_INCLUDE @@ -64,10 +64,10 @@ GS_EXPORT NSString* NSLoadedClasses; + (NSBundle*) bundleWithPath: (NSString*)path; + (NSString*) pathForResource: (NSString*)name - ofType: (NSString*)ext + ofType: (NSString*)ext inDirectory: (NSString*)bundlePath; + (NSString*) pathForResource: (NSString*)name - ofType: (NSString*)ext + ofType: (NSString*)ext inDirectory: (NSString*)bundlePath withVersion: (int)version; @@ -86,11 +86,11 @@ GS_EXPORT NSString* NSLoadedClasses; - (NSArray*) pathsForResourcesOfType: (NSString*)extension inDirectory: (NSString*)bundlePath; - (NSString*) pathForResource: (NSString*)name - ofType: (NSString*)ext + ofType: (NSString*)ext inDirectory: (NSString*)bundlePath; - (NSString*) pathForResource: (NSString*)name ofType: (NSString*)ext; -- (NSString*) localizedStringForKey: (NSString*)key +- (NSString*) localizedStringForKey: (NSString*)key value: (NSString*)value table: (NSString*)tableName; - (NSString*) resourcePath; @@ -117,7 +117,7 @@ GS_EXPORT NSString* NSLoadedClasses; + (NSString*) _library_combo; + (NSBundle*) gnustepBundle; + (NSString*) pathForGNUstepResource: (NSString*)name - ofType: (NSString*)ext + ofType: (NSString*)ext inDirectory: (NSString*)bundlePath; @end @@ -130,10 +130,98 @@ GS_EXPORT NSString* NSLoadedClasses; #endif /* GNUSTEP */ +/* + *

+ * This function (macro) is used to get the localized + * translation of the string key. + * key is looked up in the + * Localizable.strings file for the current + * language. The current language is determined by the + * available languages in which the application is + * translated, and by using the NSLanguages user + * defaults (which should contain an array of the languages + * preferred by the user, in order of preference). + *

+ *

+ * Technically, the function works by calling + * localizedStringForKey:value:table: on the + * main bundle, using @"" as value, and + * nil as the table. The comment + * is ignored when the macro is expanded; but when we have + * tools which can generate the + * Localizable.strings files automatically from + * source code, the comment will be used by the + * tools and added as a comment before the string to + * translate. Upon finding something like + *

+ *

+ * + * NSLocalizedString (@"My useful string", + * @"My useful comment about the string"); + * + *

+ *

+ * in the source code, the tools will generate a comment and the line + *

+ *

+ * + * " My useful string" = "My useful string"; + * + *

+ *

+ * in the Localizable.strings file (the + * translator then can use this as a skeleton for the + * Localizable.strings for his/her own language, + * where she/he can replace the right hand side with the + * translation in her/his own language). The comment can + * help the translator to decide how to translate when it is + * not clear how to translate (because the original string is + * now out of context, and out of context might not be so + * clear what the string means). The comment is totally + * ignored by the library code. + *

+ *

+ * If you don't have a comment (because the string is so + * self-explanatory that it doesn't need it), you can leave + * it blank, by using @"" as a comment. If the + * string might be unclear out of context, it is recommended + * that you add a comment (even if it is unused for now). + *

+ */ #define NSLocalizedString(key, comment) \ [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil] + +/* + * This function (macro) does the same as + * NSLocalizedString, but uses the table + * table rather than the default table. This + * means that the string to translate will be looked up in a + * different file than Localizable.strings. For + * example, if you pass DatabaseErrors as the + * table, the string will be looked up for + * translation in the file + * DatabaseErrors.strings. This allows you to + * have the same string translated in different ways, by + * having a different translation in different tables, and + * choosing between the different translation by choosing a + * different table. + */ #define NSLocalizedStringFromTable(key, tbl, comment) \ [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:(tbl)] + +/* + * This function is the full-blown localization function (it + * is actually a macro). It looks up the string + * key for translation in the table + * table of the bundle bundle + * (please refer to the NSBundle documentation for more + * information on how this lookup is done). + * comment is a comment, which is ignored by the + * library (it is discarded when the macro is expanded) but which + * can be used by tools which parse the source code and generate + * strings table to provide a comment which the translator can + * use when translating the string. + */ #define NSLocalizedStringFromTableInBundle(key, tbl, bundle, comment) \ [bundle localizedStringForKey:(key) value:@"" table:(tbl)] @@ -146,33 +234,145 @@ GS_EXPORT NSString* NSLoadedClasses; /* Now Support for Quick Localization */ #ifndef NO_GNUSTEP - /* The quickest possible way to localize a string: - + /* The quickest possible way to localize a string: + NSLog (_(@"New Game")); - - Please make use of the longer functions taking a comment when you + + Please make use of the longer functions taking a comment when you get the time to localize seriously your code. */ + +/* + *

+ * This function (macro) is a GNUstep extension. + *

+ *

+ * _(@"My string to translate") + *

+ *

+ * is exactly the same as + *

+ *

+ * NSLocalizedString (@"My string to translate", @"") + *

+ *

+ * It is useful when you need to translate an application + * very quickly, as you just need to enclose all strings + * inside _(). But please note that when you + * use this macro, you are not taking advantage of comments + * for the translator, so consider using + * NSLocalizedString instead when you need a + * comment. + *

+ */ #define _(X) NSLocalizedString (X, @"") - + /* The quickest possible way to localize a static string: - + static NSString *string = __(@"New Game"); - + NSLog (_(string)); */ - + +/* + *

+ * This function (macro) is a GNUstep extension. + *

+ *

+ * __(@"My string to translate") + *

+ *

+ * is exactly the same as + *

+ *

+ * NSLocalizedStaticString (@"My string to translate", @"") + *

+ *

+ * It is useful when you need to translate an application very + * quickly. You would use it as follows for static strings: + *

+ *

+ * + * NSString *message = __(@"Hello there"); + + * ... more code ... + + * NSLog (_(messages)); + * + *

+ *

+ * But please note that when you use this macro, you are not + * taking advantage of comments for the translator, so + * consider using NSLocalizedStaticString + * instead when you need a comment. + *

+ */ #define __(X) X - /* The better way for a static string, with a comment - use as follows - + /* The better way for a static string, with a comment - use as follows - - static NSString *string = NSLocalizedStaticString (@"New Game", + static NSString *string = NSLocalizedStaticString (@"New Game", @"Menu Option"); NSLog (_(string)); - If you need anything more complicated than this, please initialize + If you need anything more complicated than this, please initialize the static strings manually. */ + +/* + *

+ * This function (macro) is a GNUstep extensions, and it is used + * to localize static strings. Here is an example of a static + * string: + *

+ *

+ * + * NSString *message = @"Hi there"; + + * ... some code ... + + * NSLog (message); + * + *

+ *

+ * This string can not be localized using the standard + * openstep functions/macros. By using this gnustep extension, + * you can localize it as follows: + *

+ *

+ * + * NSString *message = NSLocalizedStaticString (@"Hi there", + * @"Greeting"); + + * ... some code ... + + * NSLog (NSLocalizedString (message, @"")); + * + *

+ *

+ * When the tools generate the + * Localizable.strings file from the source + * code, they will ignore the NSLocalizedString + * call while they will extract the string (and the comment) + * to localize from the NSLocalizedStaticString + * call. + *

+ *

+ * When the code is compiled, instead, the + * NSLocalizedStaticString call is ignored (discarded, + * it is a macro which simply expands to key), while + * the NSLocalizedString will actually look up the + * string for translation in the Localizable.strings + * file. + *

+ *

+ * Please note that there is currently no macro/function to + * localize static strings using different tables. If you + * need that functionality, you have either to prepare the + * localization tables by hand, or to rewrite your code in + * such a way as not to use static strings. + *

+ */ #define NSLocalizedStaticString(key, comment) key #endif /* NO_GNUSTEP */ diff --git a/Headers/gnustep/base/NSRange.h b/Headers/gnustep/base/NSRange.h index 8c5ecf678..2ca6ce7d7 100644 --- a/Headers/gnustep/base/NSRange.h +++ b/Headers/gnustep/base/NSRange.h @@ -46,6 +46,28 @@ #define GS_DEFINED_MIN #endif +/** + *

+ * The NSRange type is used to specify ranges of locations, + * typically items in an array, characters in a string, and bytes + * in a data object. + *

+ *

+ * As 'boundary' or 'fencepost' errors are a particularly common + * problem in programming, it is important that you understand + * how an NSRange works. + *

+ *

+ * An NSRange consists of a location and a length. The points + * that are considered to lie in a range are the integers from + * the location to the location plus the length, so the number + * of points in a range is the length of the range plus one.
+ * However, if you consider these points like the marks on a + * ruler, you can only store information between + * points. So the number of items that can be stored in a range + * is the length of the range. + *

+ */ typedef struct _NSRange NSRange; struct _NSRange { diff --git a/Headers/gnustep/base/NSSet.h b/Headers/gnustep/base/NSSet.h index 5e57bbae2..69e96ba87 100644 --- a/Headers/gnustep/base/NSSet.h +++ b/Headers/gnustep/base/NSSet.h @@ -1,4 +1,4 @@ -/* Interface for NSSet, NSMutableSet, NSCountedSet for GNUStep +/** Interface for NSSet, NSMutableSet, NSCountedSet for GNUStep Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc. Written by: Andrew Kachites McCallum @@ -19,6 +19,10 @@ You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. + + AutogsdocSource: NSSet.m + AutogsdocSource: NSCountedSet.m + */ #ifndef _NSSet_h_GNUSTEP_BASE_INCLUDE diff --git a/Source/Additions/GSMime.m b/Source/Additions/GSMime.m index 5ebe9c7af..c0a0404e0 100644 --- a/Source/Additions/GSMime.m +++ b/Source/Additions/GSMime.m @@ -30,12 +30,14 @@ to and from convenient internal formats.

- Eventually the goal is to center round three classes - + The idea is to center round two classes -

document - A container for the actual data (and headers) of a mime/http document. + A container for the actual data (and headers) of a mime/http + document, this is also used to create raw MIME data for sending. + parser An object that can be fed data and will parse it into a document. diff --git a/Source/GSCountedSet.m b/Source/GSCountedSet.m index a1b6108fd..8c21562bc 100644 --- a/Source/GSCountedSet.m +++ b/Source/GSCountedSet.m @@ -96,6 +96,12 @@ } } +/** + * Adds an object to the set. If the set already contains an object + * equal to the specified object (as determined by the [-isEqual:] + * method) then the count for that object is incremented rather + * than the new object being added. + */ - (void) addObject: (NSObject*)anObject { GSIMapNode node; @@ -285,6 +291,12 @@ GSIMapCleanMap(&map); } +/** + * Decrements the count of the number of times that the specified + * object (or an object qequal to it as determined by the + * [-isEqual:] method) has been added to the set. If the count + * becomes zero, the object is removed from the set. + */ - (void) removeObject: (NSObject*)anObject { GSIMapBucket bucket; diff --git a/Source/NSAutoreleasePool.m b/Source/NSAutoreleasePool.m index bd0f1b857..876e63486 100644 --- a/Source/NSAutoreleasePool.m +++ b/Source/NSAutoreleasePool.m @@ -119,6 +119,20 @@ pop_pool_from_cache (struct autorelease_thread_vars *tv) } +/** + *

+ * This class maintains a stack of autorelease pools objects + * in each thread. + *

+ *

+ * When an autorelease pool is created, it is automatically + * added to the stack of pools in the thread. + *

+ *

+ * When a pool is destroyed, it (and any pool later in + * the stack) is removed from the stack. + *

+ */ @implementation NSAutoreleasePool static IMP allocImp; @@ -133,10 +147,13 @@ static IMP initImp; } } +/** + * Allocate and return an autorelease pool instance.
+ * If there is an already-allocated NSAutoreleasePool available, + * save time by just returning that, rather than allocating a new one. + */ + (id) allocWithZone: (NSZone*)zone { - /* If there is an already-allocated NSAutoreleasePool available, - save time by just returning that, rather than allocating a new one. */ struct autorelease_thread_vars *tv = ARP_THREAD_VARS; if (tv->pool_cache_count) return pop_pool_from_cache (tv); @@ -202,7 +219,9 @@ static IMP initImp; return _parent; } -/* This method not in OpenStep */ +/* + * Return the number of objects in this pool. + */ - (unsigned) autoreleaseCount { unsigned count = 0; @@ -215,7 +234,16 @@ static IMP initImp; return count; } -/* This method not in OpenStep */ +/** + *

+ * Counts the number of times that the specified object occurs + * in autorelease pools in the current thread. + *

+ *

+ * This method is slow and should probably only be + * used for debugging purposes. + *

+ */ - (unsigned) autoreleaseCountForObject: (id)anObject { unsigned count = 0; @@ -232,9 +260,16 @@ static IMP initImp; return count; } -/* This method not in OpenStep */ -/* xxx This count should be made for *all* threads, but currently is - only madefor the current thread! */ +/** + *

+ * Counts the number of times that the specified object occurs + * in autorelease pools in the current thread. + *

+ *

+ * This method is slow and should probably only be + * used for debugging purposes. + *

+ */ + (unsigned) autoreleaseCountForObject: (id)anObject { unsigned count = 0; @@ -247,11 +282,19 @@ static IMP initImp; return count; } +/** + * Return the currently active autorelease pool. + */ + (id) currentPool { return ARP_THREAD_VARS->current_pool; } +/** + * Adds the specified object to the current autorelease pool. + * If there is no autorelease pool in the thread, + * a warning is logged. + */ + (void) addObject: (id)anObj { NSAutoreleasePool *pool = ARP_THREAD_VARS->current_pool; @@ -278,6 +321,9 @@ static IMP initImp; } } +/** + * Adds the specified object to this autorelease pool. + */ - (void) addObject: (id)anObj { /* If the global, static variable AUTORELEASE_ENABLED is not set, @@ -329,6 +375,9 @@ static IMP initImp; _released_count++; } +/** + * Raises an exception ... pools should not be retained. + */ - (id) retain { [NSException raise: NSGenericException @@ -336,6 +385,9 @@ static IMP initImp; return self; } +/** + * Destroys the receiver (calls -dealloc). + */ - (oneway void) release { [self dealloc]; @@ -416,6 +468,9 @@ static IMP initImp; [super dealloc]; } +/** + * Raises an exception - pools should not be autoreleased. + */ - (id) autorelease { [NSException raise: NSGenericException @@ -449,16 +504,50 @@ static IMP initImp; return ARP_THREAD_VARS->total_objects_count; } +/** + *

+ * Specifies whether objects contained in autorelease pools are to + * be released when the pools are deallocated (by default YES). + *

+ *

+ * You can set this to NO for debugging purposes. + *

+ */ + (void) enableRelease: (BOOL)enable { autorelease_enabled = enable; } +/** + *

+ * When autorelease pools are deallocated, the memory they used + * is retained in a cache for re-use so that new polls can be + * created very quickly. + *

+ *

+ * This method may be used to empty that cache, ensuring that + * the minimum memory is used by the application. + *

+ */ + (void) freeCache { free_pool_cache(ARP_THREAD_VARS); } +/** + *

+ * Specifies a limit to the number of objects that may be added to + * an autorelease pool. When this limit is reached an exception is + * raised. + *

+ *

+ * You can set this to a smallish value to catch problems with code + * that autoreleases too many objects to operate efficiently. + *

+ *

+ * Default value is maxint. + *

+ */ + (void) setPoolCountThreshhold: (unsigned)c { pool_count_warning_threshhold = c; diff --git a/Source/NSCharacterSet.m b/Source/NSCharacterSet.m index 0656a790e..e01a69e66 100644 --- a/Source/NSCharacterSet.m +++ b/Source/NSCharacterSet.m @@ -144,16 +144,28 @@ static NSLock* cache_lock = nil; return [self _bitmapForSet: @"controlCharSet" number: 1]; } +/** + * Returns a character set containing characters that represent + * the decimal digits 0 through 9. + */ + (NSCharacterSet*) decimalDigitCharacterSet { return [self _bitmapForSet: @"decimalDigitCharSet" number: 2]; } +/** + * Returns a character set containing individual charactars that + * can be represented also by a composed character sequence. + */ + (NSCharacterSet*) decomposableCharacterSet { return [self _bitmapForSet: @"decomposableCharSet" number: 3]; } +/** + * Returns a character set containing unassigned (illegal) + * character values. + */ + (NSCharacterSet*) illegalCharacterSet { return [self _bitmapForSet: @"illegalCharSet" number: 4]; @@ -164,6 +176,11 @@ static NSLock* cache_lock = nil; return [self _bitmapForSet: @"letterCharSet" number: 5]; } +/** + * Returns a character set that contains the lowercase characters. + * This set does not include caseless characters, only those that + * have corresponding characters in uppercase and/or titlecase. + */ + (NSCharacterSet*) lowercaseLetterCharacterSet { return [self _bitmapForSet: @"lowercaseLetterCharSet" number: 6]; @@ -184,16 +201,28 @@ static NSLock* cache_lock = nil; return [self _bitmapForSet: @"symbolAndOperatorCharSet" number: 9]; } +/** + * Returns a character set that contains the uppercase characters. + * This set does not include caseless characters, only those that + * have corresponding characters in lowercase and/or titlecase. + */ + (NSCharacterSet*) uppercaseLetterCharacterSet { return [self _bitmapForSet: @"uppercaseLetterCharSet" number: 10]; } +/** + * Returns a character set that contains the whitespace characters, + * plus the newline characters, values 0x000A and 0x000D. + */ + (NSCharacterSet*) whitespaceAndNewlineCharacterSet { return [self _bitmapForSet: @"whitespaceAndNlCharSet" number: 11]; } +/** + * Returns a character set that contains the whitespace characters. + */ + (NSCharacterSet*) whitespaceCharacterSet { return [self _bitmapForSet: @"whitespaceCharSet" number: 12]; @@ -201,6 +230,10 @@ static NSLock* cache_lock = nil; // Creating custom character sets +/** + * Returns a character set containing characters as encoded in the + * data object. + */ + (NSCharacterSet*) characterSetWithBitmapRepresentation: (NSData*)data { return AUTORELEASE([[NSBitmapCharSet alloc] initWithBitmap: data]); @@ -264,12 +297,20 @@ static NSLock* cache_lock = nil; return nil; } +/** + * Returns a bitmap representation of the receiver's character set + * suitable for archiving or writing to a file, in an NSData object. + */ - (NSData*) bitmapRepresentation { [self subclassResponsibility: _cmd]; return 0; } +/** + * Returns YES if the receiver contains aCharacter, NO if + * it does not. + */ - (BOOL) characterIsMember: (unichar)aCharacter { [self subclassResponsibility: _cmd]; @@ -308,6 +349,10 @@ static NSLock* cache_lock = nil; return NO; } +/** + * Returns a character set containing only characters that the + * receiver does not contain. + */ - (NSCharacterSet*) invertedSet { unsigned i; diff --git a/Source/NSCountedSet.m b/Source/NSCountedSet.m index 8f12af6e7..c59cb1c37 100644 --- a/Source/NSCountedSet.m +++ b/Source/NSCountedSet.m @@ -52,6 +52,17 @@ static BOOL uniquing = NO; + (void) _becomeThreaded: (id)notification; @end +/** + *

+ * The NSCountedSet class is used to maintain a set of objects where + * the number of times each object has been added (wiithout a + * corresponding removal) is kept track of. + *

+ *

+ * In GNUstep, extra methods are provided to make use of a counted + * set for uniquing objects easier. + *

+ */ @implementation NSCountedSet static Class NSCountedSet_abstract_class; @@ -90,6 +101,11 @@ static Class NSCountedSet_concrete_class; } } +/** + * Returns the number of times that an object that is equal to the + * specified object (as determined byt the [-isEqual:] method) has + * been added to the set and not removed from it. + */ - (unsigned int) countForObject: (id)anObject { [self subclassResponsibility: _cmd]; @@ -201,6 +217,17 @@ static Class NSCountedSet_concrete_class; return self; } +/** + *

+ * This method removes from the set all objects whose count is + * less than or equal to the specified value. + *

+ *

+ * This is useful where a counted set is used for uniquing objects. + * The set can be periodically purged of objects that have only + * been added once - and are therefore simply wasting space. + *

+ */ - (void) purge: (int)level { if (level > 0) @@ -236,6 +263,22 @@ static Class NSCountedSet_concrete_class; } } +/** + *

+ * If the supplied object (or one equal to it as determined by + * the [-isEqual:] method) is already present in the set, the + * count for that object is incremented, the supplied object + * is released, and the object in the set is retained and returned. + * Otherwise, the supplied object is added to the set and returned. + *

+ *

+ * This method is useful for uniquing objects - the init method of + * a class need simply end with - + * + * return [myUniquingSet unique: self]; + * + *

+ */ - (id) unique: (id)anObject { id o = [self member: anObject]; @@ -268,7 +311,11 @@ static Class NSCountedSet_concrete_class; } @end - +/** + * This function purges the global NSCountedSet object used for + * uniquing. It handles locking as necessary. It can be used to + * purge the set even when uniquing is turned off. + */ void GSUPurge(unsigned level) { @@ -283,6 +330,14 @@ GSUPurge(unsigned level) } } +/** + * This function sets the count for the specified object. If the + * count for the object is set to zero then the object is removed + * from the global uniquing set. The object is added to the set + * if necessary. The object returned is the one stored in the set. + * The function handles locking as necessary. It can be used to + * alter the set even when uniquing is turned off. + */ id GSUSet(id obj, unsigned level) { @@ -329,6 +384,12 @@ GSUSet(id obj, unsigned level) return found; } +/** + * This function uniques the supplied argument, returning + * the result. It works by using the [-unique:] method of a global + * NSCountedSet object. It handles locking as necessary. + * If uniquing is turned off, it simply returns its argument. + */ id GSUnique(id obj) { @@ -347,6 +408,12 @@ GSUnique(id obj) return obj; } +/** + * This function sets the state of a flag that determines the + * behavior of the GSUnique() function. If the flag is on, + * uniquing is performed, if it is off the function has no effect. + * The default is for uniquing to be turned off. + */ void GSUniquing(BOOL flag) { diff --git a/Source/NSData.m b/Source/NSData.m index 7b8a4cd3b..290e069d4 100644 --- a/Source/NSData.m +++ b/Source/NSData.m @@ -1,5 +1,5 @@ -/** Stream of bytes class for serialization and persistance in GNUStep - Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc. +/** + Copyright (C) 1995, 1996, 1997, 2000, 2002 Free Software Foundation, Inc. Written by: Andrew Kachites McCallum Date: March 1995 @@ -1575,11 +1575,40 @@ failure: [self setLength: [self length]+extraLength]; } +/** + *

+ * Sets the length of the NSMutableData object. + * If the length is increased, the newly allocated data area + * is filled with zero bytes. + *

+ *

+ * This is a 'primitive' method ... you need to implement it + * if you write a subclass of NSMutableData. + *

+ */ - (void) setLength: (unsigned int)size { [self subclassResponsibility: _cmd]; } +/** + *

+ * Returns a pointer to the data storage of the receiver.
+ * Modifications to the memory pointed to by this pointer will + * change the contents of the object. It is important that + * your code should not try to modify the memory beyond the + * number of bytes given by the -length method. + *

+ *

+ * NB. if the object is released, or any method that changes its + * size or content is called, then the pointer previously returned + * by this method may cease to be valid. + *

+ *

+ * This is a 'primitive' method ... you need to implement it + * if you write a subclass of NSMutableData. + *

+ */ - (void*) mutableBytes { [self subclassResponsibility: _cmd]; @@ -1604,9 +1633,16 @@ failure: [self appendBytes: [other bytes] length: [other length]]; } - -// Modifying Data - +/** + * Replaces the bytes of data in the specified range with a + * copy of the new bytes supplied.
+ * If the location of the range specified lies beyond the end + * of the data ([self length] < range.location) + * then a range exception is raised.
+ * Otherwise, if the range specified extends beyond the end + * of the data, then the size of the data is increased to + * accomodate the new bytes.
+ */ - (void) replaceBytesInRange: (NSRange)aRange withBytes: (const void*)bytes { diff --git a/Source/NSDebug.m b/Source/NSDebug.m index 11fc67e00..74f1f9246 100644 --- a/Source/NSDebug.m +++ b/Source/NSDebug.m @@ -90,6 +90,17 @@ static const char* _GSDebugAllocationListAll(); @end +/** + * This function is a GNUstep extension. It activates or + * deactivates object allocation debugging. Returns the + * previous state. You should call this function to activate + * allocation debugging before using any of the functions + * described in this section. Object allocation debugging + * should not affect performance too much, and is very useful + * as it allows you to monitor how many objects of each class + * your application has allocated. See below for a detailed + * description of the info you can get, and why it is useful. + */ BOOL GSDebugAllocationActive(BOOL active) { @@ -100,6 +111,22 @@ GSDebugAllocationActive(BOOL active) return old; } +/** + * This function is a GNUstep extension. It activates + * tracking all allocated instances of the specified class + * (passed as argument). This tracking can slow your + * application down, so you should use it only when you are + * into serious debugging. Usually, you will monitor your + * application by using the functions GSDebugAllocationList + * and similia (see above), which do not slow things down + * much and return the number of allocated instances; when + * (if) by studying the reports generated by these functions + * you have found a leak of objects of a certain class, and + * if you can't figure out how to fix it by looking at the + * code, you can use this function to start tracking + * allocated instances of that class, and the following one + * can sometime allow you to list the leaked objects directly. + */ void GSDebugAllocationActiveRecordingObjects(Class c) { @@ -251,6 +278,29 @@ GSDebugAllocationAdd(Class c, id o) } } +/** + *

+ * This function is a GNUstep extension. Returns the number + * of instances of the specified class which are currently + * allocated. This number is very important to detect memory + * leaks. If you notice that this number is constantly + * increasing without apparent reason, it is very likely a + * memory leak - you need to check that you are correctly + * releasing objects of this class, otherwise when your + * application runs for a long time, it will eventually + * allocate so many objects as to eat up all your system's + * memory ... + *

+ *

+ * This function, like the ones below, returns the number of + * objects allocated/released from the time when + * GSDebugAllocationActive was first called. A negative + * number means that in total, there are less objects of this + * class allocated now than there were when you called + * GSDebugAllocationActive; a positive one means there are + * more. + *

+ */ int GSDebugAllocationCount(Class c) { @@ -266,6 +316,23 @@ GSDebugAllocationCount(Class c) return 0; } +/** + * This function is a GNUstep extension. Returns the total + * number of instances of the specified class which have been + * allocated - basically the number of times you have + * allocated an object of this class. If this number is very + * high, it means you are creating a lot of objects of this + * class; even if you are releasing them correctly, you must + * not forget that allocating and deallocating objects is + * usually one of the slowest things you can do, so you might + * want to consider whether you can reduce the number of + * allocations and deallocations that you are doing - for + * example, by recycling objects of this class, uniquing + * them, and/or using some sort of flyweight pattern. It + * might also be possible that you are unnecessarily creating + * too many objects of this class. Well - of course some times + * there is nothing you can do about it. + */ int GSDebugAllocationTotal(Class c) { @@ -281,6 +348,18 @@ GSDebugAllocationTotal(Class c) return 0; } +/** + * This function is a GNUstep extension. Returns the peak + * number of instances of the specified class which have been + * concurrently allocated. If this number is very high, it + * means at some point in time you had a situation with a + * huge number of objects of this class allocated - this is + * an indicator that probably at some point in time your + * application was using a lot of memory - so you might want + * to investigate whether you can prevent this problem by + * inserting autorelease pools in your application's + * processing loops. + */ int GSDebugAllocationPeak(Class c) { @@ -296,6 +375,15 @@ GSDebugAllocationPeak(Class c) return 0; } +/** + * This function is a GNUstep extension. Returns a NULL + * terminated array listing all the classes for which + * statistical information has been collected. Usually, you + * call this function, and then loop on all the classes returned, + * and for each one you get current, peak and total count by + * using GSDebugAllocationCount, GSDebugAllocationPeak and + * GSDebugAllocationTotal. + */ Class * GSDebugAllocationClassList() { @@ -321,11 +409,15 @@ GSDebugAllocationClassList() return ans; } -/* - * This function returns a string listing all those classes for which - * either objects are currently allocated (difference == 0), or there - * has been a change in the number of objects allocated since the last - * call (difference != 0). +/** + * This function is a GNUstep extension. Returns a newline + * separated list of the classes which have instances + * allocated, and the instance counts. If the 'changeFlag' + * argument is YES then the list gives the number of + * instances allocated/deallocated since the function was + * last called. This function only returns the current count + * of instances (not the peak or total count), but its output + * is ready to be displayed or logged. */ const char* GSDebugAllocationList(BOOL changeFlag) @@ -415,6 +507,15 @@ _GSDebugAllocationList(BOOL difference) return buf; } +/** + * This function is a GNUstep extension. Returns a newline + * separated list of the classes which have had instances + * allocated at any point, and the total count of the number + * of instances allocated for each class. The difference with + * GSDebugAllocationList is that this function returns also + * classes which have no objects allocated at the moment, but + * which had in the past. + */ const char* GSDebugAllocationListAll() { @@ -537,6 +638,16 @@ GSDebugAllocationRemove(Class c, id o) } } +/** + * This function is a GNUstep extension. Returns an array + * containing all the allocated objects of a certain class + * which have been recorded (to start the recording, you need + * to invoke GSDebugAllocationActiveRecordedObjects). + * Presumably, you will immediately call -description on them + * to find out the objects you are leaking. The objects are + * returned in an array, so until the array is autoreleased, + * the objects are not released. + */ NSArray * GSDebugAllocationListRecordedObjects(Class c) { diff --git a/Source/NSDictionary.m b/Source/NSDictionary.m index 8805ad593..ff465821b 100644 --- a/Source/NSDictionary.m +++ b/Source/NSDictionary.m @@ -90,7 +90,8 @@ static SEL appSel; } } -/* This is the designated initializer */ +/** + */ - (id) initWithObjects: (id*)objects forKeys: (id*)keys count: (unsigned)count @@ -99,24 +100,38 @@ static SEL appSel; return 0; } +/** + * Returns an unsigned integer which is the number of elements + * stored in the dictionary. + */ - (unsigned) count { [self subclassResponsibility: _cmd]; return 0; } +/** + * Returns the object in the dictionary corresponding to aKey, or nil if + * the key is not present. + */ - (id) objectForKey: (id)aKey { [self subclassResponsibility: _cmd]; return 0; } +/** + * Return an enumerator object containing all the keys of the dictionary. + */ - (NSEnumerator*) keyEnumerator { [self subclassResponsibility: _cmd]; return nil; } +/** + * Return an enumerator object containing all the objects of the dictionary. + */ - (NSEnumerator*) objectEnumerator { [self subclassResponsibility: _cmd]; @@ -197,12 +212,23 @@ static SEL appSel; return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()] init]); } +/** + * Returns a newly created dictionary with the keys and objects + * of otherDictionary. + * (The keys and objects are not copied.) + */ + (id) dictionaryWithDictionary: (NSDictionary*)otherDictionary { return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()] initWithDictionary: otherDictionary]); } +/** + * Returns a dictionary created using the given objects and keys. + * The two arrays must have the same size. + * The n th element of the objects array is associated with the n th + * element of the keys array. + */ + (id) dictionaryWithObjects: (id*)objects forKeys: (id*)keys count: (unsigned)count @@ -216,6 +242,12 @@ static SEL appSel; return [self count]; } +/** + * Initialises a dictionary created using the given objects and keys. + * The two arrays must have the same size. + * The n th element of the objects array is associated with the n th + * element of the keys array. + */ - (id) initWithObjects: (NSArray*)objects forKeys: (NSArray*)keys { unsigned objectCount = [objects count]; @@ -232,6 +264,11 @@ static SEL appSel; return [self initWithObjects: os forKeys: ks count: objectCount]; } +/** + * Initialises a dictionary created using the list given as argument. + * The list is alernately composed of objects and keys. + * Thus, the list's length must be pair. + */ - (id) initWithObjectsAndKeys: (id)firstObject, ... { va_list ap; @@ -287,6 +324,11 @@ static SEL appSel; return self; } +/** + * Returns a dictionary created using the list given as argument. + * The list is alernately composed of objects and keys. + * Thus, the list's length must be pair. + */ + (id) dictionaryWithObjectsAndKeys: (id)firstObject, ... { va_list ap; @@ -344,6 +386,10 @@ static SEL appSel; initWithObjects: objects forKeys: keys]); } +/** + * Returns a dictionary containing only one object which is associated + * with a key. + */ + (id) dictionaryWithObject: (id)object forKey: (id)key { return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()] @@ -460,7 +506,11 @@ static SEL appSel; return nil; } -+ (id) dictionaryWithContentsOfFile: (NSString *)path +/** + * Returns a dictionary using the file located at path. + * The file must be a property list containing a dictionary as its root object. + */ ++ (id) dictionaryWithContentsOfFile: (NSString*)path { return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()] initWithContentsOfFile: path]); @@ -512,6 +562,9 @@ static SEL appSel; return NO; } +/** + * Returns an array containing all the dictionary's keys. + */ - (NSArray*) allKeys { unsigned c = [self count]; @@ -537,6 +590,9 @@ static SEL appSel; } } +/** + * Returns an array containing all the dictionary's objects. + */ - (NSArray*) allValues { unsigned c = [self count]; @@ -561,6 +617,10 @@ static SEL appSel; } } +/** + * Returns an array containing all the dictionary's keys that are + * associated with anObject. + */ - (NSArray*) allKeysForObject: (id)anObject { unsigned c; diff --git a/Source/NSFileHandle.m b/Source/NSFileHandle.m index 4220df1ce..77ba6ae35 100644 --- a/Source/NSFileHandle.m +++ b/Source/NSFileHandle.m @@ -487,9 +487,24 @@ NSString * const NSFileHandleOperationException } /** - * Return a flag to indicate whether compression has been turned on for - * the file handle ... this is only available on systems where GNUstep - * was built with 'zlib' support for compressing/decompressing data. + *

+ * Return a flag to indicate whether compression has been turned on for + * the file handle ... this is only available on systems where GNUstep + * was built with 'zlib' support for compressing/decompressing data. + *

+ *

+ * On systems which support it, this method may be called after + * a file handle has been initialised to turn on compression or + * decompression of the data being written/read. + *

+ * Returns YES on success, NO on failure.
+ * Reasons for failure are -
+ * + * Not supported/built in to GNUstep + * File handle has been closed + * File handle is open for both read and write + * Failure in compression/decompression library + * */ - (BOOL) useCompression { diff --git a/Source/NSLock.m b/Source/NSLock.m index 5e2c47402..cb233cdac 100644 --- a/Source/NSLock.m +++ b/Source/NSLock.m @@ -67,6 +67,16 @@ NSString *NSRecursiveLockException = @"NSRecursiveLockException"; // NSLock class // Simplest lock for protecting critical sections of code +/** + * An NSLock is used in multi-threaded applications to protect critical + * pieces of code. While one thread holds a lock within a piece of code, + * another thread cannot execute that code until the first thread has + * given up it's hold on the lock. The limitation of NSLock is that + * you can only lock an + * NSLock once and it must be unlocked before it can be aquired again.
+ * Other lock classes, notably NSRecursiveLock, have + * different restrictions. + */ @implementation NSLock // Designated initializer @@ -106,8 +116,12 @@ NSString *NSRecursiveLockException = @"NSRecursiveLockException"; } } -// Try to acquire the lock -// Does not block +/** + * Attempts to aquire a lock, but returns immediately if the lock + * cannot be aquired. It returns YES if the lock is aquired. It returns + * NO if the lock cannot be aquired or if the current thread already has + * the lock. + */ - (BOOL) tryLock { /* Return NO if we're already locked */ @@ -124,6 +138,12 @@ NSString *NSRecursiveLockException = @"NSRecursiveLockException"; return YES; } +/** + * Attempts to aquire a lock before the date limit passes. It returns YES + * if it can. It returns NO if it cannot, or if the current thread already + * has the lock (but it waits until the time limit is up before returning + * NO). + */ - (BOOL) lockBeforeDate: (NSDate *)limit { int x; @@ -150,7 +170,9 @@ NSString *NSRecursiveLockException = @"NSRecursiveLockException"; return YES; } -// NSLocking protocol +/** + * Attempts to aquire a lock, and waits until it can do so. + */ - (void) lock { CHECK_RECURSIVE_LOCK(_mutex); @@ -457,16 +479,18 @@ NSString *NSRecursiveLockException = @"NSRecursiveLockException"; @end -// NSRecursiveLock -// Allows the lock to be recursively acquired by the same thread -// -// If the same thread locks the mutex (n) times then that same -// thread must also unlock it (n) times before another thread -// can acquire the lock. +/** + * See NSLock for more information about what a lock is. A recursive + * lock extends NSLock in that you can lock a recursive lock multiple + * times. Each lock must be balanced by a cooresponding unlock, and the + * lock is not released for another thread to aquire until the last + * unlock call is made (corresponding to the first lock message). + */ @implementation NSRecursiveLock -// Designated initializer +/** + */ - (id) init { self = [super init]; @@ -503,8 +527,11 @@ NSString *NSRecursiveLockException = @"NSRecursiveLockException"; } } -// Try to acquire the lock -// Does not block +/** + * Attempts to aquire a lock, but returns NO immediately if the lock + * cannot be aquired. It returns YES if the lock is aquired. Can be + * called multiple times to make nested locks. + */ - (BOOL) tryLock { // Ask the runtime to acquire a lock on the mutex @@ -514,6 +541,11 @@ NSString *NSRecursiveLockException = @"NSRecursiveLockException"; return YES; } +/** + * Attempts to aquire a lock before the date limit passes. It returns + * YES if it can. It returns NO if it cannot + * (but it waits until the time limit is up before returning NO). + */ - (BOOL) lockBeforeDate: (NSDate *)limit { while (objc_mutex_trylock(_mutex) == -1) diff --git a/Source/NSNull.m b/Source/NSNull.m index a2305f6b0..a295cdc4f 100644 --- a/Source/NSNull.m +++ b/Source/NSNull.m @@ -24,11 +24,11 @@ $Date$ $Revision$ */ -/* - * An object to use as a placeholder - in collections for instance. - */ #include +/** + * An object to use as a placeholder - in collections for instance. + */ @implementation NSNull static NSNull *null = 0; @@ -51,6 +51,10 @@ static NSNull *null = 0; } } +/** + * Return an object that can be used as a placeholder in a collection. + * This method always returns the same object. + */ + (NSNull*) null { return null; diff --git a/Source/NSNumber.m b/Source/NSNumber.m index a5d38635b..7757f3be0 100644 --- a/Source/NSNumber.m +++ b/Source/NSNumber.m @@ -667,6 +667,41 @@ static Class doubleNumberClass; return [self descriptionWithLocale: nil]; } +/** + *

+ * Produces a string representation of the number. For a boolean + * this will be either 'true' or 'false'. For other numbers the + * format is produced using the initWithFormat:locale:... method + * of NSString, and the format depends on the type of number as + * follows - + *

+ * + * char + * %i + * short + * %hi + * int + * %i + * long + * %li + * long long + * %li + * unsigned char + * %u + * unsigned short + * %hu + * unsigned int + * %u + * unsigned long + * %lu + * unsigned long long + * %lu + * float + * %0.7g + * double + * %0.16g + * + */ - (NSString*) descriptionWithLocale: (NSDictionary*)locale { NSString *result = nil; diff --git a/Source/NSObject.m b/Source/NSObject.m index bf55e5aae..0c948a99f 100644 --- a/Source/NSObject.m +++ b/Source/NSObject.m @@ -689,7 +689,65 @@ static BOOL double_release_check_enabled = NO; - +/** + *

+ * NSObject is the root class (a root class is + * a class with no superclass) of the gnustep base library + * class hierarchy, so all classes normally inherit from + * NSObject. There is an exception though: + * NSProxy (which is used for remote messaging) + * does not inherit from NSObject. + *

+ *

+ * Unless you are really sure of what you are doing, all + * your own classes should inherit (directly or indirectly) + * from NSObject (or in special cases from + * NSProxy). NSObject provides + * the basic common functionality shared by all gnustep + * classes and objects. + *

+ *

+ * The essential methods which must be implemented by all + * classes for their instances to be usable within gnustep + * are declared in a separate protocol, which is the + * NSObject protocol. Both + * NSObject and NSProxy conform to + * this protocol, which means all objects in a gnustep + * application will conform to this protocol (btw, if you + * don't find a method of NSObject you are + * looking for in this documentation, make sure you also + * look into the documentation for the NSObject + * protocol). + *

+ *

+ * Theoretically, in special cases you might need to + * implement a new root class. If you do, you need to make + * sure that your root class conforms (at least) to the + * NSObject protocol, otherwise it will not + * interact correctly with the gnustep framework. Said + * that, I must note that I have never seen a case in which + * a new root class is needed. + *

+ *

+ * NSObject is a root class, which implies that + * instance methods of NSObject are treated in + * a special way by the Objective-C runtime. This is an + * exception to the normal way messaging works with class + * and instance methods: if the Objective-C runtime can't + * find a class method for a class object, as a last resort + * it looks for an instance method of the root class with + * the same name, and executes it if it finds it. This + * means that instance methods of the root class (such as + * NSObject) can be performed by class objects + * which inherit from that root class ! This can only + * happen if the class doesn't have a class method with the + * same name, otherwise that method - of course - takes the + * precedence. Because of this exception, + * NSObject's instance methods are written in + * such a way that they work both on NSObject's + * instances and on class objects. + *

+ */ @implementation NSObject + (void) _becomeMultiThreaded: (NSNotification)aNotification @@ -768,8 +826,10 @@ static BOOL double_release_check_enabled = NO; } /** - * Simply calls the +allocWithZone: method passing it - * NSDefaultMallocZone() as an argument. + * Allocates a new instance of the receiver from the default + * zone, by invoking +allocWithZone: with + * NSDefaultMallocZone() as the zone argument.
+ * Returns the created instance. */ + (id) alloc { @@ -777,7 +837,39 @@ static BOOL double_release_check_enabled = NO; } /** - * Creates a new instance of a class by calling NSAllocateObject() + * This is the basic method to create a new instance. It + * allocates a new instance of the receiver from the specified + * memory zone. + *

+ * Memory for an instance of the receiver is allocated; a + * pointer to this newly created instance is returned. All + * instance variables are set to 0 except the + * isa pointer which is set to point to the + * object class. No initialization of the instance is + * performed: it is your responsibility to initialize the + * instance by calling an appropriate init + * method. If you are not using the garbage collector, it is + * also your responsibility to make sure the returned + * instance is destroyed when you finish using it, by calling + * the release method to destroy the instance + * directly, or by using autorelease and + * autorelease pools. + *

+ *

+ * You do not normally need to override this method in + * subclasses, unless you are implementing a class which for + * some reasons silently allocates instances of another class + * (this is typically needed to implement class clusters and + * similar design schemes). + *

+ *

+ * If you have turned on debugging of object allocation (by + * calling the GSDebugAllocationActive + * function), this method will also update the various + * debugging counts and monitors of allocated objects, which + * you can access using the GSDebugAllocation... + * functions. + *

*/ + (id) allocWithZone: (NSZone*)z { @@ -793,7 +885,67 @@ static BOOL double_release_check_enabled = NO; } /** - * Creates and returns a new instance by calling +alloc and -init + *

+ * This method is a short-hand for alloc followed by init, that is, + *

+ *

+ * NSObject *object = [NSObject new]; + *

+ * is exactly the same as + *

+ * NSObject *object = [[NSObject alloc] init]; + *

+ *

+ * This is a general convention: all new... + * methods are supposed to return a newly allocated and + * initialized instance, as would be generated by an + * alloc method followed by a corresponding + * init... method. Please note that if you are + * not using a garbage collector, this means that instances + * generated by the new... methods are not + * autoreleased, that is, you are responsible for releasing + * (autoreleasing) the instances yourself. So when you use + * new you typically do something like: + *

+ *

+ * + * NSMutableArray *array = AUTORELEASE ([NSMutableArray new]); + * + *

+ *

+ * You do no normally need to override new in + * subclasses, because if you override init (and + * optionally allocWithZone: if you really + * need), new will automatically use your + * subclass methods. + *

+ *

+ * You might need instead to define new new... + * methods specific to your subclass to match any + * init... specific to your subclass. For + * example, if your subclass defines an instance method + *

+ *

+ * initWithName: + *

+ *

+ * it might be handy for you to have a class method + *

+ *

+ * newWithName: + *

+ *

+ * which combines alloc and + * initWithName:. You would implement it as follows: + *

+ *

+ * + * + (id) newWithName: (NSString *)aName + * { + * return [[self alloc] initWithName: aName]; + * } + * + *

*/ + (id) new { @@ -836,15 +988,85 @@ static BOOL double_release_check_enabled = NO; /** * Deallocates the receiver by calling NSDeallocateObject() with self * as the argument.
- * You should normally call the superclass implementation of this method - * when you override it in a subclass, or the memory occupied by your - * object will not be released.
- * If you have allocated the memory using a non-standard mechanism, you - * will not call the superclass (NSObject) implementation of the method - * as you will need to handle the deallocation specially.
- * In some circumstances, an object may wish to prevent itsself from - * being deallocated, it can do this simply be refraining from calling - * the superclass implementation. + *

+ * You should normally call the superclass implementation of this method + * when you override it in a subclass, or the memory occupied by your + * object will not be released. + *

+ *

+ * NSObject's implementation of this method + * destroys the receiver, by returning the memory allocated + * to the receiver to the system. After this method has been + * called on an instance, you must not refer the instance in + * any way, because it does not exist any longer. If you do, + * it is a bug and your program might even crash with a + * segmentation fault. + *

+ *

+ * If you have turned on the debugging facilities for + * instance allocation, NSObject's + * implementation of this method will also update the various + * counts and monitors of allocated instances (see the + * GSDebugAllocation... functions for more + * info). + *

+ *

+ * Normally you are supposed to manage the memory taken by + * objects by using the high level interface provided by the + * retain, release and + * autorelease methods (or better by the + * corresponding macros RETAIN, + * RELEASE and AUTORELEASE), and by + * autorelease pools and such; whenever the + * release/autorelease mechanism determines that an object is + * no longer needed (which happens when its retain count + * reaches 0), it will call the dealloc method + * to actually deallocate the object. This means that normally, + * you should not need to call dealloc directly as + * the gnustep base library automatically calls it for you when + * the retain count of an object reaches 0. + *

+ *

+ * Because the dealloc method will be called + * when an instance is being destroyed, if instances of your + * subclass use objects or resources (as it happens for most + * useful classes), you must override dealloc in + * subclasses to release all objects and resources which are + * used by the instance, otherwise these objects and + * resources would be leaked. In the subclass + * implementation, you should first release all your subclass + * specific objects and resources, and then invoke super's + * implementation (which will do the same, and so on up in + * the class hierarchy to NSObject's + * implementation, which finally destroys the object). Here + * is an example of the implementation of + * dealloc for a subclass whose instances have a + * single instance variable name which needs to + * be released when an instance is deallocated: + *

+ *

+ * + * - (void) dealloc + * { + * RELEASE (name); + * [super dealloc]; + * } + * + *

+ *

+ * dealloc might contain code to release not + * only objects, but also other resources, such as open + * files, network connections, raw memory allocated in other + * ways, etc. + *

+ *

+ * If you have allocated the memory using a non-standard mechanism, you + * will not call the superclass (NSObject) implementation of the method + * as you will need to handle the deallocation specially.
+ * In some circumstances, an object may wish to prevent itsself from + * being deallocated, it can do this simply be refraining from calling + * the superclass implementation. + *

*/ - (void) dealloc { @@ -1020,7 +1242,7 @@ static BOOL double_release_check_enabled = NO; /** * Returns a string describing the receiver. The default implementation - * gives the class and memory location of the rceiver. + * gives the class and memory location of the receiver. */ - (NSString*) description { @@ -1719,6 +1941,11 @@ static BOOL double_release_check_enabled = NO; } } +/** + * The default (NSObject) implementation of this method simply calls + * the -description method and discards the locale + * information. + */ - (NSString*) descriptionWithLocale: (NSDictionary*)aLocale { return [self description]; @@ -1729,6 +1956,11 @@ static BOOL double_release_check_enabled = NO; return [self description]; } +/** + * The default (NSObject) implementation of this method simply calls + * the -descriptionWithLocale: method and discards the + * level information. + */ - (NSString*) descriptionWithLocale: (NSDictionary*)aLocale indent: (unsigned)level { @@ -1741,6 +1973,11 @@ static BOOL double_release_check_enabled = NO; return [self descriptionWithLocale: aLocale]; } +/** + * The default (NSObject) implementation of this method simply calls + * the -descriptionWithLocale:indent: method and appends + * the value returned by that method to the output object. + */ - (void) descriptionWithLocale: (NSDictionary*)aLocale indent: (unsigned)level to: (id)output diff --git a/Source/NSPipe.m b/Source/NSPipe.m index eb4f84ba6..b8eb39fd3 100644 --- a/Source/NSPipe.m +++ b/Source/NSPipe.m @@ -32,10 +32,17 @@ #include #endif +/** + * The NSPipe provides an encapsulation of the UNIX concept of pipe. + * With NSPipe, it is possible to redirect the standard input or + * standard output. + */ @implementation NSPipe -// Allocating and Initializing a FileHandle Object - +/** + * Returns a newly allocated and initialized NSPipe object that has been + * sent an autorelease message. + */ + (id) pipe { return AUTORELEASE([[self alloc] init]); diff --git a/Source/NSScanner.m b/Source/NSScanner.m index d125fc371..d5d9b8ec9 100644 --- a/Source/NSScanner.m +++ b/Source/NSScanner.m @@ -45,6 +45,20 @@ #define ULONG_LONG_MAX ULLONG_MAX #endif +/** + *

+ * The NSScanner class cluster (currently a single class in GNUstep) + * provides a mechanism to parse the contents of a string into number + * and string values by making a sequence of scan operations to + * step through the string retrieving successive items. + *

+ *

+ * You can tell the scanner whether its scanning is supposed to be + * case sensitive or not, and you can specify a set of characters + * to be skipped before each scanning operation (by default, + * whitespace and newlines). + *

+ */ @implementation NSScanner @class GSCString; @@ -104,7 +118,8 @@ typedef struct { } /* - * Create and return a scanner that scans aString. + * Create and return a scanner that scans aString.
+ * Uses -initWithString: and with no locale set. */ + (id) scannerWithString: (NSString *)aString { @@ -112,6 +127,11 @@ typedef struct { initWithString: aString]); } +/** + * Returns an NSScanner instance set up to scan aString + * (using -initWithString: and with a locale set the default locale + * (using -setLocale: + */ + (id) localizedScannerWithString: (NSString*)aString { NSScanner *scanner = [self scannerWithString: aString]; @@ -123,9 +143,14 @@ typedef struct { return scanner; } -/* - * Initialize a a newly-allocated scanner to scan aString. - * Returns self. +/** + * Initialises the scanner to scan aString. The GNUstep + * implementation may make an internal copy of the original + * string - so it is not safe to assume that if you modify a + * mutable string that you initialised a scanner with, the changes + * will be visible to the scanner. + *
+ * Returns the scanner object. */ - (id) initWithString: (NSString *)aString { @@ -200,9 +225,10 @@ typedef struct { [super dealloc]; } -/* - * Returns YES if no more characters remain to be scanned. - * Returns YES if all characters remaining to be scanned are to be skipped. +/** + * Returns YES if no more characters remain to be scanned.
+ * Returns YES if all characters remaining to be scanned + * are to be skipped.
* Returns NO if there are characters left to scan. */ - (BOOL) isAtEnd @@ -288,8 +314,15 @@ typedef struct { return YES; } -/* - * Scan an int into value. +/** + * After initial skipping (if any), this method scans a integer value, + * placing it in intValue if that is not null. + *
+ * Returns YES if anything is scanned, NO otherwise. + *
+ * On overflow, INT_MAX or INT_MIN is put into intValue + *
+ * Scans past any excess digits */ - (BOOL) scanInt: (int*)value { @@ -381,8 +414,18 @@ typedef struct { return YES; } -/* - * Scan an unsigned int of the given radix into value. +/** + * After initial skipping (if any), this method scans an unsigned + * integer value placing it in intValue if that is not null. + * If the number begins with "0x" or "0X" it is treated as hexadecimal, + * otherwise if the number begins with "0" it is treated as octal, + * otherwise the number is treated as decimal. + *
+ * Returns YES if anything is scanned, NO otherwise. + *
+ * On overflow, INT_MAX or INT_MIN is put into intValue + *
+ * Scans past any excess digits */ - (BOOL) scanRadixUnsignedInt: (unsigned int *)value { @@ -423,8 +466,16 @@ typedef struct { return NO; } -/* - * Scan a hexadecimal unsigned integer into value. +/** + * After initial skipping (if any), this method scans a hexadecimal + * integer value (optionally prefixed by "0x" or "0X"), + * placing it in intValue if that is not null. + *
+ * Returns YES if anything is scanned, NO otherwise. + *
+ * On overflow, INT_MAX or INT_MIN is put into intValue + *
+ * Scans past any excess digits */ - (BOOL) scanHexInt: (unsigned int *)value { @@ -464,9 +515,17 @@ typedef struct { return NO; } -/* - * Scan a long long int into value. - * Same as scanInt, except with different variable types and limits. +/** + * After initial skipping (if any), this method scans a long + * decimal integer value placing it in longLongValue if that + * is not null. + *
+ * Returns YES if anything is scanned, NO otherwise. + *
+ * On overflow, LONG_LONG_MAX or LONG_LONG_MIN is put into + * longLongValue + *
+ * Scans past any excess digits */ - (BOOL) scanLongLong: (long long *)value { @@ -552,19 +611,25 @@ typedef struct { #endif /* defined(LONG_LONG_MAX) */ } +/** + * Not implemented. + */ - (BOOL) scanDecimal: (NSDecimal*)value { [self notImplemented:_cmd]; /* FIXME */ return NO; } -/* - * Scan a double into value. - * Returns YES if a valid floating-point expression was scanned. - * Returns NO otherwise. - * On overflow, HUGE_VAL or -HUGE_VAL is put into value and YES is returned. - * On underflow, 0.0 is put into value and YES is returned. - * Based on the strtod code from the GNU C library. +/** + * After initial skipping (if any), this method scans a double value, + * placing it in doubleValue if that is not null. + * Returns YES if anything is scanned, NO otherwise. + *
+ * On overflow, HUGE_VAL or -HUGE_VAL is put into doubleValue + *
+ * On underflow, 0.0 is put into doubleValue + *
+ * Scans past any excess digits */ - (BOOL) scanDouble: (double *)value { @@ -680,12 +745,16 @@ typedef struct { return YES; } -/* - * Scan a float into value. - * Returns YES if a valid floating-point expression was scanned. - * Returns NO otherwise. - * On overflow, HUGE_VAL or -HUGE_VAL is put into value and YES is returned. - * On underflow, 0.0 is put into value and YES is returned. +/** + * After initial skipping (if any), this method scans a float value, + * placing it in floatValue if that is not null. + * Returns YES if anything is scanned, NO otherwise. + *
+ * On overflow, HUGE_VAL or -HUGE_VAL is put into floatValue + *
+ * On underflow, 0.0 is put into floatValue + *
+ * Scans past any excess digits */ - (BOOL) scanFloat: (float*)value { @@ -701,12 +770,13 @@ typedef struct { return NO; } -/* - * Scan as long as characters from aSet are encountered. - * Returns YES if any characters were scanned. - * Returns NO if no characters were scanned. - * If value is non-NULL, and any characters were scanned, a string - * containing the scanned characters is returned by reference in value. +/** + * After initial skipping (if any), this method scans any characters + * from aSet, terminating when a character not in the set + * is found.
+ * Returns YES if any character is scanned, NO otherwise.
+ * If value is not null, any character scanned are + * stored in a string returned in this location. */ - (BOOL) scanCharactersFromSet: (NSCharacterSet *)aSet intoString: (NSString **)value @@ -760,12 +830,12 @@ typedef struct { return NO; } -/* - * Scan until a character from aSet is encountered. - * Returns YES if any characters were scanned. - * Returns NO if no characters were scanned. - * If value is non-NULL, and any characters were scanned, a string - * containing the scanned characters is returned by reference in value. +/** + * After initial skipping (if any), this method scans characters until + * it finds one in set. The scanned characters are placed in + * stringValue if that is not null. + *
+ * Returns YES if anything is scanned, NO otherwise. */ - (BOOL) scanUpToCharactersFromSet: (NSCharacterSet *)aSet intoString: (NSString **)value @@ -819,13 +889,12 @@ typedef struct { return YES; } -/* - * Scans for aString. - * Returns YES if the characters at the scan location match aString. - * Returns NO if the characters at the scan location do not match aString. - * If the characters at the scan location match aString. - * If value is non-NULL, and the characters at the scan location match aString, - * a string containing the matching string is returned by reference in value. +/** + * After initial skipping (if any), this method scans for + * aString and places the string ound in stringValue + * if that is not null. + *
+ * Returns YES if anything is scanned, NO otherwise. */ - (BOOL) scanString: (NSString *)string intoString: (NSString **)value { @@ -851,12 +920,14 @@ typedef struct { return YES; } -/* - * Scans the string until aString is encountered.. - * Returns YES if any characters were scanned. - * Returns NO if no characters were scanned. - * If value is non-NULL, and any characters were scanned, a string - * containing the scanned characters is returned by reference in value. +/** + * After initial skipping (if any), this method scans characters until + * it finds aString. The scanned characters are placed in + * stringValue if that is not null. If aString is + * not found, all the characters up to the end of the scanned string + * will be returned. + *
+ * Returns YES if anything is scanned, NO otherwise. */ - (BOOL) scanUpToString: (NSString *)string intoString: (NSString **)value @@ -884,7 +955,7 @@ typedef struct { return YES; } -/* +/** * Returns the string being scanned. */ - (NSString *) string @@ -892,18 +963,21 @@ typedef struct { return _string; } -/* - * Returns the character index at which the scanner - * will begin the next scanning operation. +/** + * Returns the current position that the scanner has reached in + * scanning the string. This is the position at which the next scan + * operation will begin. */ - (unsigned) scanLocation { return _scanLocation; } -/* - * Set the character location at which the scanner - * will begin the next scanning operation to anIndex. +/** + * This method sets the location in the scanned string at which the + * next scan operation begins. + * Raises an NSRangeException if index is beyond the end of the + * scanned string. */ - (void) setScanLocation: (unsigned int)anIndex { @@ -914,37 +988,53 @@ typedef struct { format: @"Attempt to set scan location beyond end of string"]; } -/* - * Returns YES if the scanner makes a distinction - * between upper and lower case characters. +/** + * If the scanner is set to be case-sensitive in its scanning of + * the string (other than characters to be skipped), this method + * returns YES, otherwise it returns NO. + *
+ * The default is for a scanner to not be case sensitive. */ - (BOOL) caseSensitive { return _caseSensitive; } -/* - * If flag is YES the scanner will consider upper and lower case - * to be the same during scanning. If flag is NO the scanner will - * not make a distinction between upper and lower case characters. +/** + * Sets the case sensitivity of the scanner. + *
+ * Case sensitivity governs matrching of characters being scanned, + * but does not effect the characters in the set to be skipped. + *
+ * The default is for a scanner to not be case sensitive. */ - (void) setCaseSensitive: (BOOL)flag { _caseSensitive = flag; } -/* - * Return a character set object containing the characters the scanner - * will ignore when searching for the next element to be scanned. +/** + * Returns a set of characters containing those characters that the + * scanner ignores when starting any scan operation. Once a character + * not in this set has been encountered during an operation, skipping + * is finished, and any further characters from this set that are + * found are scanned normally. + *
+ * The default for this is the whitespaceAndNewlineCharacterSet. */ - (NSCharacterSet *) charactersToBeSkipped { return _charactersToBeSkipped; } -/* - * Set the characters to be ignored when the scanner - * searches for the next element to be scanned. +/** + * Sets the set of characters that the scanner will skip over at the + * start of each scanning operation to be skipSet. + * Skipping is performed by literal character matchins - the case + * sensitivity of the scanner does not effect it. + * If this is set to nil, no skipping is done. + *
+ * The default for this is the whitespaceAndNewlineCharacterSet. */ - (void) setCharactersToBeSkipped: (NSCharacterSet *)aSet { @@ -953,18 +1043,20 @@ typedef struct { [_charactersToBeSkipped methodForSelector: memSel]; } -/* - * Returns a dictionary object containing the locale - * information used by the scanner. +/** + * Returns the locale set for the scanner, or nil if no locale has + * been set. A scanner uses it's locale to alter the way it handles + * scanning - it uses the NSDecimalSeparator value for scanning + * numbers. */ - (NSDictionary *) locale { return _locale; } -/* - * Set the dictionary containing the locale - * information used by the scanner to localeDictionary. +/** + * This method sets the locale used by the scanner to aLocale. + * The locale may be set to nil. */ - (void) setLocale: (NSDictionary *)localeDictionary { diff --git a/Source/NSSerializer.m b/Source/NSSerializer.m index 8cef8da5c..e3f610417 100644 --- a/Source/NSSerializer.m +++ b/Source/NSSerializer.m @@ -816,6 +816,12 @@ deserializeFromInfo(_NSDeserializerInfo* info) @end @implementation NSDeserializer (GNUstep) +/** + * This method turns on/off uniquing of strings as they are + * deserialized from data objects. The uniquing mechanism + * employs the GNUstep-specific functions documented with + * the NSCountedSet class. + */ + (void) uniquing: (BOOL)flag { if (flag == YES) diff --git a/Source/NSSet.m b/Source/NSSet.m index 6f70dd880..9849b724a 100644 --- a/Source/NSSet.m +++ b/Source/NSSet.m @@ -119,6 +119,9 @@ static Class NSMutableSet_concrete_class; return RETAIN(self); } +/** + * Returns the number of objects stored in the set. + */ - (unsigned) count { [self subclassResponsibility: _cmd]; @@ -169,7 +172,8 @@ static Class NSMutableSet_concrete_class; } } -/* This is the designated initializer */ +/* + */ - (id) initWithObjects: (id*)objects count: (unsigned)count { @@ -257,6 +261,10 @@ static Class NSMutableSet_concrete_class; return [self initWithObjects: NULL count: 0]; } +/** + * Initialises a newly allocated set by adding all the objects + * in the supplied array to the set. + */ - (id) initWithArray: (NSArray*)other { unsigned count = [other count]; @@ -274,6 +282,10 @@ static Class NSMutableSet_concrete_class; } } +/** + * Initialises a newly allocated set by adding all the objects + * in the supplied set. + */ - (id) initWithSet: (NSSet*)other copyItems: (BOOL)flag { unsigned c = [other count]; @@ -487,17 +499,30 @@ static Class NSMutableSet_concrete_class; return [[NSSet_concrete_class allocWithZone: z] initWithSet: self]; } -/* This is the designated initializer */ +/** + * Initialises a newly allocated set to contain no objects but + * to have space available to hold the specified number of items.
+ * Additions of items to a set initialised + * with an appropriate capacity will be more efficient than addition + * of items otherwise. + */ - (id) initWithCapacity: (unsigned)numItems { return [self subclassResponsibility: _cmd]; } +/** + * Adds anObject to the set.
+ * The object is retained by the set. + */ - (void) addObject: (id)anObject { [self subclassResponsibility: _cmd]; } +/** + * Removes the anObject from the receiver. + */ - (void) removeObject: (id)anObject { [self subclassResponsibility: _cmd]; @@ -517,6 +542,9 @@ static Class NSMutableSet_concrete_class; return self; } +/** + * Adds all the objects in the array to the receiver. + */ - (void) addObjectsFromArray: (NSArray*)array { unsigned i, c = [array count]; @@ -527,6 +555,10 @@ static Class NSMutableSet_concrete_class; } } +/** + * Removes from the receiver all the objects it contains + * which are not also in other. + */ - (void) intersectSet: (NSSet*) other { if (other != self) @@ -544,6 +576,10 @@ static Class NSMutableSet_concrete_class; } } +/** + * Removes from the receiver all the objects that are in + * other. + */ - (void) minusSet: (NSSet*) other { if (other == self) @@ -562,11 +598,19 @@ static Class NSMutableSet_concrete_class; } } +/** + * Removes all objects from the receiver. + */ - (void) removeAllObjects { [self subclassResponsibility: _cmd]; } +/** + * Removes all objects from the receiver then adds the + * objects from other. If the receiver is + * other, the method has no effect. + */ - (void) setSet: (NSSet*)other { if (other == self) @@ -587,6 +631,9 @@ static Class NSMutableSet_concrete_class; } } +/** + * Adds all the objects from other to the receiver. + */ - (void) unionSet: (NSSet*) other { if (other != self) diff --git a/Source/NSString.m b/Source/NSString.m index 8cf1267a1..64dd83425 100644 --- a/Source/NSString.m +++ b/Source/NSString.m @@ -257,7 +257,30 @@ surrogatePairValue(unichar high, unichar low) } - +/** + *

+ * NSString objects represent an immutable string of characters. + * NSString itself is an abstract class which provides factory + * methods to generate objects of unspecified subclasses. + *

+ *

+ * A constant NSString can be created using the following syntax: + * @"...", where the contents of the quotes are the + * string, using only ASCII characters. + *

+ *

+ * To create a concrete subclass of NSString, you must have your + * class inherit from NSString and override at least the two + * primitive methods - length and characterAtIndex: + *

+ *

+ * In general the rule is that your subclass must override any + * initialiser that you want to use with it. The GNUstep + * implementation relaxes that to say that, you may override + * only the designated initialiser and the other + * initialisation methods should work. + *

+ */ @implementation NSString static NSStringEncoding _DefaultStringEncoding; @@ -541,7 +564,11 @@ handle_printf_atsign (FILE *stream, // Initializing Newly Allocated Strings -/* This is the designated initializer. */ +/** + * This is the most basic initialiser for unicode strings. + * In the GNUstep implementation, your subclasses may override + * this initialiser in order to have all others function. + */ - (id) initWithCharactersNoCopy: (unichar*)chars length: (unsigned int)length freeWhenDone: (BOOL)flag @@ -742,6 +769,9 @@ handle_printf_atsign (FILE *stream, return self; } +/** + * Invokes -initWithFormat:locale:arguments: with a nil locale. + */ - (id) initWithFormat: (NSString*)format,... { va_list ap; @@ -751,6 +781,9 @@ handle_printf_atsign (FILE *stream, return self; } +/** + * Invokes -initWithFormat:locale:arguments: + */ - (id) initWithFormat: (NSString*)format locale: (NSDictionary*)locale, ... { @@ -761,12 +794,19 @@ handle_printf_atsign (FILE *stream, return self; } +/** + * Invokes -initWithFormat:locale:arguments: with a nil locale. + */ - (id) initWithFormat: (NSString*)format arguments: (va_list)argList { return [self initWithFormat: format locale: nil arguments: argList]; } +/** + * Initialises the string using the specified format and locale + * to format the following arguments. + */ - (id) initWithFormat: (NSString*)format locale: (NSDictionary*)locale arguments: (va_list)argList @@ -1492,6 +1532,10 @@ handle_printf_atsign (FILE *stream, return range; } +/** + * Invokes -rangeOfString:options: with the options mask + * set to zero. + */ - (NSRange) rangeOfString: (NSString*)string { NSRange all = NSMakeRange(0, [self length]); @@ -1501,6 +1545,10 @@ handle_printf_atsign (FILE *stream, range: all]; } +/** + * Invokes -rangeOfString:options:range: with the range set + * set to the range of the whole of the reciever. + */ - (NSRange) rangeOfString: (NSString*)string options: (unsigned int)mask { @@ -1511,9 +1559,30 @@ handle_printf_atsign (FILE *stream, range: all]; } -- (NSRange) rangeOfString: (NSString *) aString - options: (unsigned int) mask - range: (NSRange) aRange +/** + * Returns the range giving the location and length of the first + * occurrence of aString within aRange. + *
+ * If aString does not exist in the receiver (an empty + * string is never considered to exist in the receiver), + * the length of the returned range is zero. + *
+ * If aString is nil, an exception is raised. + *
+ * If any part of aRange lies outside the range of the + * receiver, an exception is raised. + *
+ * The options mask may contain the following options - + * + * NSCaseInsensitiveSearch + * NSLiteralSearch + * NSBackwardsSearch + * NSAnchoredSearch + * + */ +- (NSRange) rangeOfString: (NSString *)aString + options: (unsigned int)mask + range: (NSRange)aRange { if (aString == nil) [NSException raise: NSInvalidArgumentException format: @"range of nil"]; @@ -2008,6 +2077,10 @@ handle_printf_atsign (FILE *stream, initWithCharactersNoCopy: s length: len freeWhenDone: YES]); } +/** + * Returns a copy of the receiver with all characters converted + * to lowercase. + */ - (NSString*) lowercaseString { unichar *s; @@ -2030,6 +2103,10 @@ handle_printf_atsign (FILE *stream, initWithCharactersNoCopy: s length: len freeWhenDone: YES]); } +/** + * Returns a copy of the receiver with all characters converted + * to uppercase. + */ - (NSString*) uppercaseString { unichar *s; @@ -2061,6 +2138,12 @@ handle_printf_atsign (FILE *stream, // Getting C Strings +/** + * Returns a pointer to a nul terminated string of 8-bit + * characters in the default encoding. The memory pointed + * to is not owned by the caller, so the caller must copy + * its contents to keep it. + */ - (const char*) cString { NSData *d; @@ -2217,16 +2300,40 @@ handle_printf_atsign (FILE *stream, // Working With Encodings +/** + *

+ * Returns the encoding used for any method accepting a C string. + * This value is determined automatically from the programs + * environment and cannot be changed programmatically. + *

+ *

+ * You should NOT override this method in an attempt to + * change the encoding being used... it won't work. + *

+ *

+ * In GNUstep, this encoding is determined by the initial value + * of the GNUSTEP_STRING_ENCODING environment + * variable. If this is not defined, + * NSISOLatin1StringEncoding is assumed. + *

+ */ + (NSStringEncoding) defaultCStringEncoding { return _DefaultStringEncoding; } +/** + * Returns an array of all available string encodings, + * terminated by a null value. + */ + (NSStringEncoding*) availableStringEncodings { return GetAvailableEncodings(); } +/** + * Returns the localized name of the encoding specified. + */ + (NSString*) localizedNameOfStringEncoding: (NSStringEncoding)encoding { id ourbundle; @@ -3973,6 +4080,13 @@ handle_printf_atsign (FILE *stream, return [self substringFromIndex: [_prefix length]]; } +/** + * Returns a string in which any (and all) occurrances of + * replace in the receiver have been replaced with by. + * Returns the receiver if replace + * does not occur within the receiver. NB. an empty string is + * not considered to exist within the receiver. + */ - (NSString*) stringByReplacingString: (NSString*)replace withString: (NSString*)by { @@ -4041,7 +4155,10 @@ handle_printf_atsign (FILE *stream, /** * Replaces all occurrances of the string replace with the string by - * in the receiver. + * in the receiver.
+ * Has no effect if replace does not occur within the + * receiver. NB. an empty string is not considered to exist within + * the receiver. */ - (void) replaceString: (NSString*)replace withString: (NSString*)by diff --git a/Source/NSThread.m b/Source/NSThread.m index d3eca01c6..a182daff8 100644 --- a/Source/NSThread.m +++ b/Source/NSThread.m @@ -85,7 +85,18 @@ static BOOL entered_multi_threaded_state = NO; static NSThread *defaultThread = nil; /** - * Fast access function to get current thread. + *

+ * This function is a GNUstep extension. It pretty much + * duplicates the functionality of [NSThread +currentThread] + * but is more efficient and is used internally throughout + * GNUstep. + *

+ *

+ * Returns the current thread. Could perhaps return nil + * if executing a thread that was started outside the GNUstep + * environment and not registered (this should not happen in a + * well-coded application). + *

*/ inline NSThread* GSCurrentThread() @@ -171,8 +182,16 @@ gnustep_base_thread_callback() @implementation NSThread -/* - * Return the current thread +/** + *

+ * Returns the NSThread object corresponding to the current thread. + *

+ *

+ * NB. In GNUstep the library internals use the GSCurrentThread() + * function as a more efficient mechanism for doing this job - so + * you cannot use a category to override this method and expect + * the library internals to use your implementation. + *

*/ + (NSThread*) currentThread { @@ -457,6 +476,22 @@ gnustep_base_thread_callback() typedef struct { @defs(NSThread) } NSThread_ivars; +/** + *

+ * This function is provided to let threads started by some other + * software library register themselves to be used with the + * GNUstep system. All such threads should call this function + * before attempting to use any GNUstep objects. + *

+ *

+ * Returns YES if the thread can be registered, + * NO if it is already registered. + *

+ *

+ * Sends out a NSWillBecomeMultiThreadedNotification + * if the process was not already multithreaded. + *

+ */ BOOL GSRegisterCurrentThread (void) { @@ -509,6 +544,19 @@ GSRegisterCurrentThread (void) return YES; } +/** + *

+ * This function is provided to let threads started by some other + * software library unregister themselves from the GNUstep threading + * system. + *

+ *

+ * Calling this function causes a + * NSThreadWillExitNotification + * to be sent out, and destroys the GNUstep NSThread object + * associated with the thread. + *

+ */ void GSUnregisterCurrentThread (void) { diff --git a/Source/NSTimeZone.m b/Source/NSTimeZone.m index ab3373db2..92688f4f6 100644 --- a/Source/NSTimeZone.m +++ b/Source/NSTimeZone.m @@ -851,7 +851,30 @@ static NSMapTable *absolutes = 0; @end - +/** + *

+ * If the GNUstep time zone datafiles become too out of date, one + * can download an updated database from ftp://elsie.nci.nih.gov/pub/ + * and compile it as specified in the README file in the + * NSTimeZones directory. + * + * Time zone names in NSDates should be GMT, MET etc. not + * Europe/Berlin, America/Washington etc. + * + * The problem with this is that various time zones may use the + * same abbreviation (e.g. Australia/Brisbane and + * America/New_York both use EST), and some time zones + * may have different rules for daylight saving time even if the + * abbreviation and offsets from UTC are the same. + * + * The problems with depending on the OS for providing time zone + * info are that some methods for the NSTimeZone classes might be + * difficult to implement, and also that time zone names may vary + * wildly between OSes (this could be a big problem when + * archiving is used between different systems). + *

+ */ @implementation NSTimeZone + (NSDictionary*) abbreviationDictionary