Initial revision

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@161 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Andrew McCallum 1995-03-18 17:15:15 +00:00
parent b9c479fbdc
commit 4e1e3b6d7d
8 changed files with 1052 additions and 0 deletions

View file

@ -0,0 +1,59 @@
/* Interface for NSArray for GNUStep
Copyright (C) 1994 NeXT Computer, Inc.
Typed by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
Date: August 1994
This file is part of the GNU Objective C Class 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __NSArray_h_OBJECTS_INCLUDE
#define __NSArray_h_OBJECTS_INCLUDE
#include <objects/stdobjects.h>
#include <objects/Array.h>
@interface NSArray : Array <NSCopying, NSMutableCopying>
+ (id) array;
+ (id) arrayWithObject: anObject;
+ (id) arrayWithObject: firstObject, ...;
- (id) initWithArray: (NSArray*)array;
- (id) initWithObjects: (id)firstObject, ...;
- (id) initWithObjects: (id*)objects count: (unsigned int)count;
- (BOOL) containsObject: (id)candidate;
- (unsigned) count; /* inherited */
- (unsigned) indexOfObject: (id)anObject; /* inherited */
- (unsigned) indexOfObjectIdenticalTo: (id)anObject;
- (id) lastObject; /* inherited */
- (id) objectAtIndex: (unsigned)index; /* inherited */
- (NSEnumerator*) objectEnumerator;
- (NSEnumerator*) reverseObjectEnumerator;
- (void) makeObjectsPerform: (SEL)aSelector; /* inherited */
- (void) makeObjectsPerform: (SEL)aSelector withObject: (id)anObject; /* inh */
- (id) firstObjectCommonWithArray: (NSArray*)otherArray;
- (BOOL) isEqualToArray: (NSArray*)otherArray;
- (NSArray*) sortedArrayUsingFunction: (int(*)(id,id,void*))comparator
context: (void*)context;
- (NSArray*) sortedArrayUsingSelector: (SEL)comparator;
- (NSArray*) subarrayWithRange: (NSRange)range;
- (NSString*) componentsJoinedByString: (NSString*)separator;
- (NSString*) description;
@end
#endif /* __NSArray_h_OBJECTS_INCLUDE */

View file

@ -0,0 +1,58 @@
/* Interface for NSBundle class
*
* Copyright (C) 1993 The Board of Trustees of
* The Leland Stanford Junior University. All Rights Reserved.
*
* Authors: Adam Fedor, Scott Francis and Paul Kunz
*
* This file is part of an Objective-C class library for X/Motif
*
* NSBundle.h,v 1.9 1993/10/20 00:44:51 pfkeb Exp
*/
#ifndef _NS_Bundle_h_
#define _NS_Bundle_h_
#include <foundation/NSObject.h>
@class NSString;
@class NSArray;
@interface NSBundle : NSObject
{
NSString *_path;
Class _principalClass;
BOOL _codeLoaded;
int _bundleVersion;
}
+ (NSBundle *)mainBundle;
+ (NSBundle *)bundleForClass:aClass;
+ (NSBundle *)bundleWithPath:(NSString *)path;
- initWithPath:(NSString *)path;
- (NSString *)bundlePath;
- classNamed:(NSString *)className;
- principalClass;
+ (NSString *)pathForResource:(NSString *)name
ofType:(NSString *)ext
inDirectory:(NSString *)bundlePath
withVersion:(int)version;
- (NSString *)pathForResource:(NSString *)name
ofType:(NSString *)ext;
+ (void)stripAfterLoading:(BOOL)flag;
- (NSString *)localizedStringForKey:(NSString *)key
value:(NSString *)value
table:(NSString *)tableName;
- (unsigned)bundleVersion;
- (void)setBundleVersion:(unsigned)version;
+ (void)setSystemLanguages:(NSArray *)languages;
@end
#endif /* _NS_Bundle_h_ */

View file

@ -0,0 +1,109 @@
/*
NSException - exception handler
Copyright (C) 1995, Adam Fedor
$Id$
*/
#ifndef _NSException_include_
#define _NSException_include_
#include <foundation/NSObject.h>
#include <setjmp.h>
//#include <stdarg.h>
@class NSString;
@class NSDictionary;
@interface NSException : NSObject <NSCoding, NSCopying>
{
NSString *e_name;
NSString *e_reason;
NSDictionary *e_info;
}
+ (NSException *)exceptionWithName:(NSString *)name
reason:(NSString *)reason
userInfo:(NSDictionary *)userInfo;
+ (volatile void)raise:(NSString *)name
format:(NSString *)format,...;
+ (volatile void)raise:(NSString *)name
format:(NSString *)format
arguments:(va_list)argList;
- (id)initWithName:(NSString *)name
reason:(NSString *)reason
userInfo:(NSDictionary *)userInfo;
- (volatile void)raise;
// Querying Exceptions
- (NSString *)name;
- (NSString *)reason;
- (NSDictionary *)userInfo;
@end
/* Common exceptions */
extern NSString *NSInconsistentArchiveException;
extern NSString *NSGenericException;
extern NSString *NSInternalInconsistencyException;
extern NSString *NSInvalidArgumentException;
extern NSString *NSMallocException;
extern NSString *NSRangeException;
/* Exception handler definitions */
typedef struct _NSHandler
{
jmp_buf jumpState; /* place to longjmp to */
struct _NSHandler *next; /* ptr to next handler */
NSException *exception;
} NSHandler;
typedef volatile void NSUncaughtExceptionHandler(NSException *exception);
extern NSUncaughtExceptionHandler *_NSUncaughtExceptionHandler;
#define NSGetUncaughtExceptionHandler() _NSUncaughtExceptionHandler
#define NSSetUncaughtExceptionHandler(proc) \
(_NSUncaughtExceptionHandler = (proc))
/* NS_DURING, NS_HANDLER and NS_ENDHANDLER are always used like:
NS_DURING
some code which might raise an error
NS_HANDLER
code that will be jumped to if an error occurs
NS_ENDHANDLER
If any error is raised within the first block of code, the second block
of code will be jumped to. Typically, this code will clean up any
resources allocated in the routine, possibly case on the error code
and perform special processing, and default to RERAISE the error to
the next handler. Within the scope of the handler, a local variable
called exception holds information about the exception raised.
It is illegal to exit the first block of code by any other means than
NS_VALRETURN, NS_VOIDRETURN, or just falling out the bottom.
*/
/* private support routines. Do not call directly. */
extern void _NSAddHandler( NSHandler *handler );
extern void _NSRemoveHandler( NSHandler *handler );
#define NS_DURING { NSHandler NSLocalHandler; \
_NSAddHandler(&NSLocalHandler); \
if( !setjmp(NSLocalHandler.jumpState) ) {
#define NS_HANDLER _NSRemoveHandler(&NSLocalHandler); } else { \
NSException *exception = NSLocalHandler.exception;
#define NS_ENDHANDLER }}
#define NS_VALRETURN(val) do { typeof(val) temp = (val); \
_NSRemoveHandler(&NSLocalHandler); \
return(temp); } while (0)
#define NS_VOIDRETURN do { _NSRemoveHandler(&NSLocalHandler); \
return; } while (0)
#endif /* _NSException_include_ */

View file

@ -0,0 +1,74 @@
/* From
* (Preliminary Documentation) Copyright (c) 1994 by NeXT Computer, Inc.
* All Rights Reserved.
*
* NSGeometry.h
*/
#ifndef __NSGeometry_INCLUDE__
#define __NSGeometry_INCLUDE__
#include <objc/objc.h>
/* Geometry */
typedef struct _NSPoint { /* Point definition. */
float x;
float y;
} NSPoint;
typedef struct _NSSize { /* Rectangle sizes. */
float width;
float height;
} NSSize;
typedef struct _NSRect { /* Rectangle. */
NSPoint origin;
NSSize size;
} NSRect;
typedef enum {
NSMinXEdge,
NSMinYEdge,
NSMaxXEdge,
NSMaxYEdge
} NSRectEdge;
/* Create Basic Structures */
extern NSPoint NSMakePoint(float x, float y);
extern NSSize NSMakeSize(float w, float h);
extern NSRect NSMakeRect(float x, float y, float w, float h);
/* Get ractangel coordinates */
extern float NSMaxX(NSRect aRect);
extern float NSMaxY(NSRect aRect);
extern float NSMidX(NSRect aRect);
extern float NSMidY(NSRect aRect);
extern float NSMinX(NSRect aRect);
extern float NSMinY(NSRect aRect);
extern float NSWidth(NSRect aRect);
extern float NSHeight(NSRect aRect);
/* Modify a copy of a rectangle */
extern NSRect NSOffsetRect(NSRect aRect, float dx, float dy);
extern NSRect NSInsetRect(NSRect aRect, float dX, float dY);
extern NSRect NSIntegralRect(NSRect aRect);
extern void NSDivideRect(NSRect aRect, NSRect *slice, NSRect *remainder,
float amount, NSRectEdge edge);
/* Compute a third rectangle from two rectangles */
extern NSRect NSUnionRect(NSRect aRect, NSRect bRect);
extern NSRect NSIntersectionRect (NSRect aRect, NSRect bRect);
/* Test geometrical relationships */
extern BOOL NSEqualRects(NSRect aRect, NSRect bRect);
extern BOOL NSEqualSizes(NSSize aSize, NSSize bSize);
extern BOOL NSEqualPoints(NSPoint aPoint, NSPoint bPoint);
extern BOOL NSIsEmptyRect(NSRect aRect);
extern BOOL NSMouseInRect(NSPoint aPoint, NSRect aRect, BOOL flipped);
extern BOOL NSPointInRect(NSPoint aPoint, NSRect aRect);
extern BOOL NSContainsRect(NSRect aRect, NSRect bRect);
extern BOOL NSIntersectsRect (NSRect aRect, NSRect bRect);
#endif /* _NSGeometry_include_ */

View file

@ -0,0 +1,32 @@
/* Interface for NSObject for GNUStep
Copyright (C) 1994 NeXT Computer, Inc.
Typed by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
Date: August 1994
This file is part of the GNU Objective C Class 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __NSString_h_OBJECTS_INCLUDE
#define __NSString_h_OBJECTS_INCLUDE
#include <objects/String.h>
@interface NSString : String
@end
#endif /* __NSString_h_OBJECTS_INCLUDE */

View file

@ -0,0 +1,88 @@
/*
NSValue.h - Object encapsulation for C types.
Copyright 1994 NeXT, Inc. All rights reserved.
*/
#ifndef __NSValue_INCLUDE_GNU_
#define __NSValue_INCLUDE_GNU_
#include <foundation/NSObject.h>
#include <foundation/NSGeometry.h>
@class NSString;
@interface NSValue : NSObject <NSCopying, NSCoding>
{
void *_dataptr;
NSString *objctype;
}
// Allocating and Initializing
+ (NSValue *)value:(const void *)value
withObjCType:(const char *)type;
+ (NSValue *)valueWithNonretainedObject: (id)anObject;
+ (NSValue *)valueWithPoint:(NSPoint)point;
+ (NSValue *)valueWithPointer:(const void *)pointer;
+ (NSValue *)valueWithRect:(NSRect)rect;
+ (NSValue *)valueWithSize:(NSSize)size;
/* Note: not in OpenStep specification */
- initValue:(const void *)value
withObjCType:(const char *)type;
// Accessing Data
- (void)getValue:(void *)value;
- (const char *)objCType;
- (id)nonretainedObjectValue;
- (void *)pointerValue;
- (NSRect)rectValue;
- (NSSize)sizeValue;
- (NSPoint)pointValue;
@end
@interface NSNumber : NSValue
{
}
// Allocating and Initializing
+ (NSNumber *)numberWithBool:(BOOL)value;
+ (NSNumber *)numberWithChar:(char)value;
+ (NSNumber *)numberWithDouble:(double)value;
+ (NSNumber *)numberWithFloat:(float)value;
+ (NSNumber *)numberWithInt:(int)value;
+ (NSNumber *)numberWithLong:(long)value;
+ (NSNumber *)numberWithLongLong:(long long)value;
+ (NSNumber *)numberWithShort:(short)value;
+ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
+ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
+ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
+ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
+ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
// Accessing Data
- (BOOL)boolValue;
- (char)charValue;
- (double)doubleValue;
- (float)floatValue;
- (int)intValue;
- (long long)longLongValue;
- (long)longValue;
- (short)shortValue;
- (NSString *)stringValue;
- (unsigned char)unsignedCharValue;
- (unsigned int)unsignedIntValue;
- (unsigned long long)unsignedLongLongValue;
- (unsigned long)unsignedLongValue;
- (unsigned short)unsignedShortValue;
- (NSComparisonResult)compare:(NSNumber *)otherNumber;
@end
#endif

427
Source/NSBundle.m Normal file
View file

@ -0,0 +1,427 @@
/* Implementation of NSBundle class
*
* Copyright (C) 1993 The Board of Trustees of
* The Leland Stanford Junior University. All Rights Reserved.
*
* Authors: Adam Fedor, Scott Francis, Fred Harris, Paul Kunz, Tom Pavel,
* Imran Qureshi, and Libing Wang
*
* This file is part of an Objective-C class library
*
* NSBundle.m,v 1.8 1993/10/20 00:44:53 pfkeb Exp
*/
#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <objc/objc-api.h>
#include <objects/objc-load.h>
#include <foundation/NSBundle.h>
#include "NSObjectPrivate.h"
#include <foundation/NSException.h>
#include <foundation/NSString.h>
#include <foundation/NSArray.h>
#ifndef index
#define index strchr
#define rindex strrchr
#endif
#ifndef FREE_OBJECT
#define FFREE_OBJECT(id) ([id release],id=nil)
#define FREE_OBJECT(id) (id?FFREE_OBJECT(id):nil)
#endif
/* This is the extension that NSBundle expect on all bundle names */
#define BUNDLE_EXT "bundle"
/* By default, we transmorgrify extensions of type "nib" to type "xmib"
which is the common extension for IB files for the GnuStep project
*/
#define IB_EXT "xmib"
/* Class variables - We keep track of all the bundles and all the classes
that are in each bundle
*/
static NSBundle *_mainBundle = nil;
static NSMutableArray *_bundles = nil;
static NSMutableArray *_bundleClasses = nil;
/* List of language preferences */
static NSArray *_languages = nil;
/* When we are linking in an object file, objc_load_modules calls our
callBack routine for every Class and Category loaded. The following
variable stores the bundle that is currently doing the loading so we know
where to store the class names. This is way non-thread-safe, but
apparently this is how NeXT does it (maybe?).
*/
static int _loadingBundlePos = -1;
static BOOL _stripAfterLoading;
/* Get the object file that should be located in the bundle of the same name */
static NSString *
object_name(NSString *path)
{
NSString *name;
name = [[path lastPathComponent] stringByDeletingPathExtension];
name = [path stringByAppendingPathComponent:name];
return name;
}
/* Construct a path from the directory, language, name and extension. Used by
pathForResource:...
*/
static NSString *nib;
static NSString *xmib;
static NSString *
construct_path(NSString *path, NSString *lang,
NSString *name, NSString *ext )
{
NSString *fullpath;
name = [name stringByDeletingPathExtension];
if ([ext compare:nib] == NSOrderedSame)
ext = xmib;
// FIXME: change when NSString can support %@ parameters
if (lang) {
fullpath = [NSString stringWithFormat:
TEMP_STRING("%s/%s.lproj/%s.%s"), [path cString],
[lang cString], [name cString], [ext cString]];
} else {
fullpath = [NSString stringWithFormat:
TEMP_STRING("%s/%s.%s"), [path cString],
[name cString], [ext cString]];
}
/*
if (lang) {
fullpath = [NSString stringWithFormat:
TEMP_STRING("%@/%@.lproj/%@.%@"), path, lang, name, ext];
} else {
fullpath = [NSString stringWithFormat:
TEMP_STRING("%@/%@.%@"), path, name, ext];
}
*/
#ifdef DEBUG
fprintf(stderr, "Debug (NSBundle): path is %s\n", [fullpath cString]);
#endif
return fullpath;
}
void
_bundle_load_callback(Class *theClass, Category *theCategory)
{
/* Don't store categories */
assert(_loadingBundlePos >= 0);
if (!theCategory)
[[_bundleClasses objectAtIndex:_loadingBundlePos]
addObject:(id)theClass];
}
@implementation NSBundle
+ (void)initialize
{
nib = STATIC_STRING("nib");
xmib = STATIC_STRING("xmib");
}
+ (NSBundle *)mainBundle
{
if ( !_mainBundle ) {
NSString *path;
path = [NSString stringWithCString:objc_executable_location()];
/* Strip off the name of the program */
path = [path stringByDeletingLastPathComponent];
if (!path || [path length] == 0) {
fprintf(stderr, "Error (NSBundle): Cannot find main bundle.\n");
return nil;
}
#ifdef DEBUG
fprintf(stderr, "Debug (NSBundle): Found main in %s\n",
[path cString]);
#endif
/* We do alloc and init separately so initWithPath: does not
add us to the _bundles list
*/
_mainBundle = [NSBundle alloc];
_mainBundle = [_mainBundle initWithPath:path];
}
return _mainBundle;
}
/* Due to lazy evaluation, we will not find a class if a either classNamed: or
principalClass has not been called on the particular bundle that contains
the class. (FIXME)
*/
+ (NSBundle *)bundleForClass:aClass
{
int i, count;
NSBundle *bundle = nil;
if (!aClass)
return nil;
count = [_bundleClasses count];
for (i=0; i < count; i++) {
int j, class_count;
NSArray *classList = [_bundleClasses objectAtIndex:i];
class_count = [classList count];
for (j = 0; j < class_count; j++)
if ([aClass isEqual:[classList objectAtIndex:j]]) {
bundle = [_bundles objectAtIndex:i];
break;
}
if (bundle)
break;
}
if (!bundle) {
/* Is it in the main bundle? */
if (class_is_class(aClass))
bundle = [NSBundle mainBundle];
}
return bundle;
}
+ (NSBundle *)bundleWithPath:(NSString *)path
{
return [[[NSBundle alloc] initWithPath:path] autorelease];
}
- initWithPath:(NSString *)path;
{
struct stat statbuf;
[super init];
if (!_languages)
[[self class] setSystemLanguages:NULL];
if (!path || [path length] == 0) {
[NSException raise:NSInvalidArgumentException
format:TEMP_STRING("No path specified for bundle")];
/* NOT REACHED */
}
if (stat([path cString], &statbuf) != 0) {
[NSException raise:NSGenericException
format:TEMP_STRING("Path does not exist")];
/* NOT REACHED */
}
_path = [path retain];
if (self == _mainBundle)
return self;
if (!_bundles) {
_bundles = [[NSMutableArray arrayWithCapacity:2] retain];
_bundleClasses = [[NSMutableArray arrayWithCapacity:2] retain];
}
[_bundles addObject:self];
[_bundleClasses addObject:[[NSMutableArray arrayWithCapacity:0] retain]];
return self;
}
/* We can't really unload the module, since objc_unload_module has
no idea where we were loaded from, so we just dealloc everything and
don't worry about it.
*/
- (void)dealloc
{
int pos = [_bundles indexOfObject:self];
if (pos >= 0) {
[_bundleClasses removeObjectAtIndex:pos];
[_bundles removeObjectAtIndex:pos];
}
FREE_OBJECT(_path);
[super dealloc];
}
- (NSString *)bundlePath
{
return _path;
}
- classNamed:(NSString *)className
{
int j, class_count;
NSArray *classList;
Class *theClass = Nil;
if (!_codeLoaded) {
if (self != _mainBundle && ![self principalClass]) {
[NSException raise:NSGenericException
format:TEMP_STRING("Unable to get classes")];
/* NOT REACHED */
}
}
if (self == _mainBundle) {
theClass = objc_lookup_class([className cString]);
if (theClass && [[self class] bundleForClass:theClass] != _mainBundle)
theClass = Nil;
} else {
classList = [_bundleClasses objectAtIndex:
[_bundles indexOfObject:self]];
class_count = [classList count];
for (j = 0; j < class_count; j++) {
theClass = [classList objectAtIndex:j];
if ([theClass isEqual:objc_lookup_class([className cString])]) {
break;
}
theClass = Nil;
}
}
return theClass;
}
- principalClass
{
NSArray *classList;
if (self == _mainBundle) {
_codeLoaded = YES;
return nil; // the mainBundle does not have a principal class
}
if (!_codeLoaded) {
NSString *object = object_name(_path);
/* Link in the object file */
_loadingBundlePos = [_bundles indexOfObject:self];
if (objc_load_module([object cString],
stderr, _bundle_load_callback, NULL, NULL)) {
[NSException raise:NSGenericException
format:TEMP_STRING("Unable to load module")];
/* NOT REACHED */
} else
_codeLoaded = YES;
_loadingBundlePos = -1;
}
classList = [_bundleClasses objectAtIndex:[_bundles indexOfObject:self]];
if ([classList count])
return [classList objectAtIndex:0];
else
return nil;
}
- (NSString *)pathForResource:(NSString *)name
ofType:(NSString *)ext;
{
return [[self class] pathForResource:name
ofType:ext
inDirectory: _path
withVersion: 0];
}
+ (NSString *)pathForResource:(NSString *)name
ofType:(NSString *)ext
inDirectory:(NSString *)bundlePath
withVersion:(int)version;
{
struct stat statbuf;
NSString *path = nil;
if (!name || [name length] == 0) {
[NSException raise:NSInvalidArgumentException
format:TEMP_STRING("No resource name specified.")];
/* NOT REACHED */
}
if (_languages) {
unsigned i, count;
count = [_languages count];
for (i=0; i < count; i++) {
path = construct_path(bundlePath, [_languages objectAtIndex:i],
name, ext );
if ( stat([path cString], &statbuf) == 0)
break;
path = nil;
count++;
}
} else {
path = construct_path(bundlePath, TEMP_STRING("English"), name, ext );
if ( stat([path cString], &statbuf) != 0) {
path = nil;
}
}
if (!path) {
path = construct_path(bundlePath, nil, name, ext );
if ( stat([path cString], &statbuf) != 0) {
path = nil;
}
}
/* Note: path is already autoreleased */
return path;
}
+ (void)stripAfterLoading:(BOOL)flag
{
_stripAfterLoading = flag;
}
- (NSString *)localizedStringForKey:(NSString *)key
value:(NSString *)value
table:(NSString *)tableName
{
[self notImplemented:_cmd];
return 0;
}
- (unsigned)bundleVersion
{
return _bundleVersion;
}
- (void)setBundleVersion:(unsigned)version
{
_bundleVersion = version;
}
+ (void)setSystemLanguages:(NSArray *)languages
{
static NSString *separator;
if (!separator) separator = STATIC_STRING(" ");
if (_languages) {
FREE_OBJECT(_languages);
}
/* If called with a nil array, look in the environment for the
language list. The languages should separated by the "separator"
string.
*/
if (!languages) {
NSString *env = [NSString stringWithCString:getenv("LANGUAGE")];
if (env && [env length] != 0)
_languages = [[env componentsSeparatedByString:separator] retain];
} else
_languages = [languages retain];
}
// FIXME: this is here to please IndexedCollection - NSObject doesn't have it
- (int)compare:anotherObject
{
if ([self isEqual:anotherObject])
return 0;
// Ordering objects by their address is pretty useless,
// so subclasses should override this is some useful way.
else if (self > anotherObject)
return 1;
else
return -1;
}
@end

205
Source/NSException.m Normal file
View file

@ -0,0 +1,205 @@
/* NSException - Object encapsulation of a general exception handler
Copyright (C) 1993,1994 Free Software Foundation, Inc.
Written by: Adam Fedor <fedor@boulder.colorado.edu>
Date: Mar 1995
This file is part of the GNU Objective C Class 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <assert.h>
#include "NSException.h"
#include "NSObjectPrivate.h"
#include "NSString.h"
#include "NSValue.h"
#include "NSArray.h"
#include "NSCoder.h"
#include "NSDictionary.h"
#include "object_zone.h"
// FIXME: GNU gcc doesn't have static strings yet...
/*
NSString *NSInconsistentArchiveException
= @"NSInconsistentArchiveException";
NSString *NSGenericException
= @"NSGenericException";
NSString *NSInternalInconsistencyException
= @"NSInternalInconsistencyException";
NSString *NSInvalidArgumentException = @"NSInvalidArgumentException";
NSString *NSMallocException = @"NSMallocException";
NSString *NSRangeException = @"NSRangeException";
*/
NSString *NSInconsistentArchiveException;
NSString *NSGenericException;
NSString *NSInternalInconsistencyException;
NSString *NSInvalidArgumentException;
NSString *NSMallocException;
NSString *NSRangeException;
/* FIXME: Not thread safe - probably need one for each thread. */
static NSMutableArray *e_queue;
static NSUncaughtExceptionHandler *_NSUncaughtExceptionHandler;
static volatile void
_NSFoundationUncaughtExceptionHandler(NSException *exception)
{
fprintf(stderr, "Uncaught exception %s, reason: %s\n",
[[exception name] cString], [[exception reason] cString]);
/* FIXME: need to implement this:
NSLogError("Uncaught exception %@, reason: %@",
[exception name], [exception reason]);
*/
abort();
}
@implementation NSException
+ (NSException *)exceptionWithName:(NSString *)name reason:(NSString *)reason userInfo:(NSDictionary *)userInfo
{
return [[[self alloc] initWithName:name reason:reason
userInfo:userInfo] autorelease];
}
+ (volatile void)raise:(NSString *)name
format:(NSString *)format,...
{
va_list args;
va_start(args, format);
[self raise:name format:format arguments:args];
// FIXME: This probably doesn't matter, but va_end won't get called
va_end(args);
}
+ (volatile void)raise:(NSString *)name
format:(NSString *)format
arguments:(va_list)argList
{
NSString *reason;
NSException *except;
reason = [[NSString alloc] initWithFormat:format arguments:argList];
[reason autorelease];
except = [self exceptionWithName:name reason:reason userInfo:nil];
[except raise];
}
- (id)initWithName:(NSString *)name reason:(NSString *)reason userInfo:(NSDictionary *)userInfo
{
self = [super init];
e_name = [name retain];
e_reason = [reason retain];
e_info = [userInfo retain];
return self;
}
- (volatile void)raise
{
NSHandler *handler;
if (_NSUncaughtExceptionHandler == NULL)
_NSUncaughtExceptionHandler = _NSFoundationUncaughtExceptionHandler;
if (!e_queue) {
_NSUncaughtExceptionHandler(self);
return;
}
if ([e_queue count] == 0) {
_NSUncaughtExceptionHandler(self);
return;
}
[[e_queue lastObject] getValue:&handler];
handler->exception = self;
[e_queue removeLastObject];
longjmp(handler->jumpState, 1);
}
- (NSString *)name
{
return e_name;
}
- (NSString *)reason
{
return e_reason;
}
- (NSDictionary *)userInfo
{
return e_info;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeObject:e_name];
[aCoder encodeObject:e_reason];
[aCoder encodeObject:e_info];
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
e_name = [[aDecoder decodeObject] retain];
e_reason = [[aDecoder decodeObject] retain];
e_info = [[aDecoder decodeObject] retain];
return self;
}
- deepen
{
e_name = [e_name copyWithZone:[self zone]];
e_reason = [e_reason copyWithZone:[self zone]];
e_info = [e_info copyWithZone:[self zone]];
return self;
}
- copyWithZone:(NSZone *)zone
{
if (NSShouldRetainWithZone(self, zone))
return [self retain];
else
return [[super copyWithZone:zone] deepen];
}
@end
void
_NSAddHandler( NSHandler *handler )
{
if (!e_queue) {
e_queue = [[NSMutableArray arrayWithCapacity:8] retain];
}
[e_queue addObject:
[NSValue value:&handler withObjCType:@encode(NSHandler *)]];
}
void
_NSRemoveHandler( NSHandler *handler )
{
// FIXME: Should be NSAssert??
assert(e_queue);
assert([e_queue count] != 0);
[e_queue removeLastObject];
}