From d4146fe4994b0d309346860b5f61960a82903e12 Mon Sep 17 00:00:00 2001 From: mccallum Date: Mon, 3 Apr 1995 20:49:14 +0000 Subject: [PATCH] Initial revision git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@251 72102866-910b-0410-8b05-ffd578937521 --- Headers/gnustep/base/NSCoder.h | 184 ++++++++++++++++ Headers/gnustep/base/NSConcreteNumber.h | 104 ++++++++++ Headers/gnustep/base/NSConcreteValue.h | 67 ++++++ Headers/gnustep/base/NSDictionary.h | 54 +++++ Headers/gnustep/base/NSLock.h | 9 + Headers/gnustep/base/NSSerialization.h | 34 +++ Headers/gnustep/base/NSTimer.h | 27 +++ Headers/gnustep/base/NSUtilities.h | 10 + Headers/gnustep/base/objc-load.h | 39 ++++ NSBundle.README | 17 ++ Source/NSCTemplateValue.m | 103 +++++++++ Source/NSConcreteNumber.m | 209 +++++++++++++++++++ Source/NSConcreteValue.m | 160 ++++++++++++++ Source/NSNumber.m | 265 ++++++++++++++++++++++++ Source/NSRange.m | 56 +++++ Source/dld-load.h | 140 +++++++++++++ Source/hpux-load.h | 77 +++++++ Source/null-load.h | 73 +++++++ Source/objc-load.c | 224 ++++++++++++++++++++ Source/simple-load.h | 85 ++++++++ Testing/values.m | 62 ++++++ 21 files changed, 1999 insertions(+) create mode 100644 Headers/gnustep/base/NSCoder.h create mode 100644 Headers/gnustep/base/NSConcreteNumber.h create mode 100644 Headers/gnustep/base/NSConcreteValue.h create mode 100644 Headers/gnustep/base/NSDictionary.h create mode 100644 Headers/gnustep/base/NSLock.h create mode 100644 Headers/gnustep/base/NSSerialization.h create mode 100644 Headers/gnustep/base/NSTimer.h create mode 100644 Headers/gnustep/base/NSUtilities.h create mode 100644 Headers/gnustep/base/objc-load.h create mode 100644 NSBundle.README create mode 100644 Source/NSCTemplateValue.m create mode 100644 Source/NSConcreteNumber.m create mode 100644 Source/NSConcreteValue.m create mode 100644 Source/NSNumber.m create mode 100644 Source/NSRange.m create mode 100644 Source/dld-load.h create mode 100644 Source/hpux-load.h create mode 100644 Source/null-load.h create mode 100644 Source/objc-load.c create mode 100644 Source/simple-load.h create mode 100644 Testing/values.m diff --git a/Headers/gnustep/base/NSCoder.h b/Headers/gnustep/base/NSCoder.h new file mode 100644 index 000000000..04a9c85ee --- /dev/null +++ b/Headers/gnustep/base/NSCoder.h @@ -0,0 +1,184 @@ +/* From: + * (Preliminary Documentation) Copyright (c) 1994 by NeXT Computer, Inc. + * All Rights Reserved. + * + * NSCoder + * + */ + +#ifndef __NSCoder__include__ +#define __NSCoder__include__ + +#include +#include +#include + +@class NSMutableData, NSData, NSString; + +@interface NSCoder : NSObject +{ + NSMutableData *_data; +} + +// Encoding Data + +- (void)encodeArrayOfObjCType:(const char *)types + count:(unsigned)count + at:(const void *)array; + /* + * Serializes data of Objective C types listed in types having count + * elements residing at address array. + */ + +- (void)encodeBycopyObject:(id)anObject; + /* + * Overridden by subclasses to serialize the supplied Objective C object so + * that a copy rather than a proxy of anObject is created upon + * deserialization. NSCoder's implementation simply invokes encodeObject:. + */ + +- (void)encodeConditionalObject:(id)anObject; + /* + * Overridden by subclasses to conditionally serialize the supplied + * Objective C object. The object should be serialized only if it is an + * inherent member of the larger data structure. NSCoder's implementation + * simply invokes encodeObject:. + */ + +- (void)encodeDataObject:(NSData *)data; + /* + * Serializes the NSData object data. + */ + +- (void)encodeObject:(id)anObject; + /* + * Serializes the supplied Objective C object. + */ + +- (void)encodePropertyList:(id)plist; + /* + * Serializes the supplied property list (NSData, NSArray, NSDictionary, or + * NSString objects). + */ + +- (void)encodePoint:(NSPoint)point; + /* + * Serializes the supplied point structure. + */ + +- (void)encodeRect:(NSRect)rect; + /* + * Serializes the supplied rectangle structure. + */ + +- (void)encodeRootObject:(id)rootObject; + /* + * Overridden by subclasses to start the serialization of an interconnected + * group of Objective C objects, starting with rootObject. NSCoder's + * implementation simply invokes encodeObject:. + */ + +- (void)encodeSize:(NSSize)size; + /* + * Serializes the supplied size structure. + */ + +- (void)encodeValueOfObjCType:(const char *)type + at:(const void *)address; + /* + * Serializes data of Objective C type type residing at address address. + */ + +- (void)encodeValuesOfObjCTypes:(const char *)types,...; + /* + * Serializes values corresponding to the Objective C types listed in types + * argument list. + */ + +// Decoding Data + +- (void)decodeArrayOfObjCType:(const char *)types + count:(unsigned)count + at:(void *)address; + /* + * Deserializes data of Objective C types listed in type having count + * elements residing at address address. + */ + +- (NSData *)decodeDataObject; + /* + * Deserializes and returns an NSData object. + */ + +- (id)decodeObject; + /* + * Deserializes an Objective C object. + */ + +- (id)decodePropertyList; + /* + * Deserializes a property list (NSData, NSArray, NSDictionary, or NSString + * objects). + */ + +- (NSPoint)decodePoint; + /* + * Deserializes a point structure. + */ + +- (NSRect)decodeRect; + /* + * Deserializes a rectangle structure. + */ + +- (NSSize)decodeSize; + /* + * Deserializes a size structure. + */ + +- (void)decodeValueOfObjCType:(const char *)type + at:(void *)address; + /* + * Deserializes data of Objective C type type residing at address address. + * You are responsible for releasing the resulting objects. + */ + +- (void)decodeValuesOfObjCTypes:(const char *)types,...; + /* + * Deserializes values corresponding to the Objective C types listed in + * types argument list. You are responsible for releasing the resulting + * objects. + */ + +// Managing Zones + +- (NSZone *)objectZone; + /* + * Returns the memory zone used by deserialized objects. For instances of + * NSCoder, this is the default memory zone, the one returned by + * NSDefaultMallocZone(). + */ + +- (void)setObjectZone:(NSZone *)zone; + /* + * Sets the memory zone used by deserialized objects. Instances of NSCoder + * always use the default memory zone, the one returned by + * NSDefaultMallocZone(), and so ignore this method. + */ + +// Getting a Version + +- (unsigned int)systemVersion; + /* + * Returns the system version number as of the time the archive was created. + */ + +- (unsigned int)versionForClassName:(NSString *)className; + /* + * Returns the version number of the class className as of the time it was + * archived. + */ + +@end + +#endif /* __NSCoder__include__ */ diff --git a/Headers/gnustep/base/NSConcreteNumber.h b/Headers/gnustep/base/NSConcreteNumber.h new file mode 100644 index 000000000..75309e5c8 --- /dev/null +++ b/Headers/gnustep/base/NSConcreteNumber.h @@ -0,0 +1,104 @@ +/* NSConcreteNumber - Interface for Concrete NSNumber classes + + Copyright (C) 1993,1994 Free Software Foundation, Inc. + + Written by: Adam Fedor + 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 + +@interface NSBoolNumber : NSNumber +{ + BOOL data; +} +@end + +@interface NSUCharNumber : NSNumber +{ + unsigned char data; +} +@end + +@interface NSCharNumber : NSNumber +{ + char data; +} +@end + +@interface NSUShortNumber : NSNumber +{ + unsigned short data; +} +@end + +@interface NSShortNumber : NSNumber +{ + short data; +} +@end + +@interface NSUIntNumber : NSNumber +{ + unsigned int data; +} +@end + +@interface NSIntNumber : NSNumber +{ + int data; +} +@end + +@interface NSULongNumber : NSNumber +{ + unsigned long data; +} +@end + +@interface NSLongNumber : NSNumber +{ + long data; +} +@end + +@interface NSULongLongNumber : NSNumber +{ + unsigned long long data; +} +@end + +@interface NSLongLongNumber : NSNumber +{ + long long data; +} +@end + +@interface NSFloatNumber : NSNumber +{ + float data; +} +@end + +@interface NSDoubleNumber : NSNumber +{ + double data; +} +@end + diff --git a/Headers/gnustep/base/NSConcreteValue.h b/Headers/gnustep/base/NSConcreteValue.h new file mode 100644 index 000000000..0d8d7d01c --- /dev/null +++ b/Headers/gnustep/base/NSConcreteValue.h @@ -0,0 +1,67 @@ +/* NSConcreteValue - Interface for Concrete NSValue classes + + Copyright (C) 1993,1994 Free Software Foundation, Inc. + + Written by: Adam Fedor + 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. +*/ + +#ifndef __NSConcreteValue_OBJECT_INCLUDE +#define __NSConcreteValue_OBJECT_INCLUDE + +#include + +@interface NSConcreteValue : NSValue +{ + void *data; + NSString *objctype; +} +@end + +@interface NSNonretainedObjectValue : NSValue +{ + id data; +} +@end + +@interface NSPointValue : NSValue +{ + NSPoint data; +} +@end + +@interface NSPointerValue : NSValue +{ + void *data; +} +@end + +@interface NSRectValue : NSValue +{ + NSRect data; +} +@end + +@interface NSSizeValue : NSValue +{ + NSSize data; +} +@end + +#endif diff --git a/Headers/gnustep/base/NSDictionary.h b/Headers/gnustep/base/NSDictionary.h new file mode 100644 index 000000000..ed830dcae --- /dev/null +++ b/Headers/gnustep/base/NSDictionary.h @@ -0,0 +1,54 @@ +/* NSDictionary.h + Basic dictionary container + Copyright 1993, 1994, NeXT, Inc. + NeXT, March 1993 +*/ + +#ifndef _NSDictionary_INCLUDE_ +#define _NSDictionary_INCLUDE_ + +#include +#include +#include + +@class NSArray; + +@interface NSDictionary : Dictionary + +//+ allocWithZone:(NSZone *)zone; +//+ dictionary; +//+ dictionaryWithObjects:(id *)objects forKeys:(NSString **)keys count:(unsigned)count; +//+ dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; +//- initWithObjects:(id *)objects forKeys:(NSString **)keys count:(unsigned)count; +//- initWithDictionary:(NSDictionary *)otherDictionary; +//- initWithContentsOfFile:(NSString *)path; + +//- (unsigned)count; +//- objectForKey:(NSString *)aKey; +//- (NSEnumerator *)keyEnumerator; +//- (BOOL)isEqualToDictionary:(NSDictionary *)other; +//- (NSString *)description; +//- (NSString *)descriptionWithIndent:(unsigned)level; +//- (NSArray *)allKeys; +//- (NSArray *)allValues; +//- (NSArray *)allKeysForObject:anObject; +//- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile; +//- (NSEnumerator *)objectEnumerator; + +@end + +@interface NSMutableDictionary: NSDictionary + +//+ allocWithZone:(NSZone *)zone; +//+ dictionaryWithCapacity:(unsigned)numItems; +//- initWithCapacity:(unsigned)numItems; + +//- (void)setObject:anObject forKey:(NSString *)aKey; +//- (void)removeObjectForKey:(NSString *)aKey; +//- (void)removeAllObjects; +//- (void)removeObjectsForKeys:(NSArray *)keyArray; +//- (void)addEntriesFromDictionary:(NSDictionary *)otherDictionary; + +@end + +#endif diff --git a/Headers/gnustep/base/NSLock.h b/Headers/gnustep/base/NSLock.h new file mode 100644 index 000000000..5efd5cf03 --- /dev/null +++ b/Headers/gnustep/base/NSLock.h @@ -0,0 +1,9 @@ +#ifndef __NSLock_h_OBJECTS_INCLUDE +#define __NSLock_h_OBJECTS_INCLUDE + +@protocol NSLocking +- (void) lock; +- (void) unlock; +@end + +endif /* __NSLock_h_OBJECTS_INCLUDE */ diff --git a/Headers/gnustep/base/NSSerialization.h b/Headers/gnustep/base/NSSerialization.h new file mode 100644 index 000000000..a1ef8e4b3 --- /dev/null +++ b/Headers/gnustep/base/NSSerialization.h @@ -0,0 +1,34 @@ +/* Protocol for NSSerialization for GNUStep + Copyright (C) 1994 NeXT Computer, Inc. + + 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 __NSSerialization_h_OBJECTS_INCLUDE +#define __NSSerialization_h_OBJECTS_INCLUDE + +@protocol NSObjCTypeSerializationCallBack +- (void) deserialzeObjectAt: (id*)object + ofObjCType: (const char *)type + fromData: (NSData*)data + atCursor: (unsigned*)cursor; +- (void) deserialzeObjectAt: (id*)object + ofObjCType: (const char *)type + intoData: (NSMutableData*)data; +@end + +endif /* __NSSerialization_h_OBJECTS_INCLUDE */ diff --git a/Headers/gnustep/base/NSTimer.h b/Headers/gnustep/base/NSTimer.h new file mode 100644 index 000000000..5adfdbd6a --- /dev/null +++ b/Headers/gnustep/base/NSTimer.h @@ -0,0 +1,27 @@ +/* Declarations for NSTimer for GNUStep + Copyright (C) 1994 NeXT Computer, Inc. + + 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 __NSTimer_include__ +#define __NSTimer_include__ + +/* Time interval difference between two dates. */ +typedef double NSTimeInterval; + +#endif diff --git a/Headers/gnustep/base/NSUtilities.h b/Headers/gnustep/base/NSUtilities.h new file mode 100644 index 000000000..c935965c5 --- /dev/null +++ b/Headers/gnustep/base/NSUtilities.h @@ -0,0 +1,10 @@ +#ifndef __NSUtilties_h_OBJECTS_INCLUDE +#define __NSUtilties_h_OBJECTS_INCLUDE + +#include + +@interface NSEnumerator : NSObject +- (id) nextObject; +@end + +endif /* __NSUtilties_h_OBJECTS_INCLUDE */ diff --git a/Headers/gnustep/base/objc-load.h b/Headers/gnustep/base/objc-load.h new file mode 100644 index 000000000..dc5e573ac --- /dev/null +++ b/Headers/gnustep/base/objc-load.h @@ -0,0 +1,39 @@ +/* + objc-load.h - Dynamically load in Obj-C modules (Classes, Categories) + + Copyright (C) 1993, Adam Fedor. + + $Id$ +*/ + +#ifndef __objc_load_h_INCLUDE +#define __objc_load_h_INCLUDE + +#include +#include + +extern char *objc_executable_location(); + +extern long objc_load_module( + const char *filename, + FILE *errorStream, + void (*loadCallback)(Class, Category*), + void **header, + char *debugFilename); + +extern long objc_unload_module( + FILE *errorStream, + void (*unloadCallback)(Class, Category*)); + +extern long objc_load_modules( + char *files[], + FILE *errorStream, + void (*callback)(Class*,Category*), + void **header, + char *debugFilename); + +extern long objc_unload_modules( + FILE *errorStream, + void (*unloadCallback)(Class*, Category*)); + +#endif /* __objc_load_h_INCLUDE */ diff --git a/NSBundle.README b/NSBundle.README new file mode 100644 index 000000000..d55994b3f --- /dev/null +++ b/NSBundle.README @@ -0,0 +1,17 @@ + +NSBundle problems: + + It requires a small but important change in the objc runtime (see + gcc-dynamic.patch for info. It may be possible to work around this, but it + is hard. I already submitted this to gcc-bug, but don't know the + status. + + It requires that the global variable NSArgv be defined and set to the + value of argv in main() in order to find the executable location. + + Linking with different linkers and on different systems is different + and may require some changes to the load flags, like -nostdlib, + -shared, -Xlinker -r, etc... Some of this can be taken care of in + the configure script. + + diff --git a/Source/NSCTemplateValue.m b/Source/NSCTemplateValue.m new file mode 100644 index 000000000..843ffaeaf --- /dev/null +++ b/Source/NSCTemplateValue.m @@ -0,0 +1,103 @@ +/* NSValue.h - Object encapsulation for C types. + Copyright (C) 1993,1994 Free Software Foundation, Inc. + + Written by: Adam Fedor + 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 +#include +#include +#include +#include + +/* This file should be run through a preprocessor with the macro TYPE_ORDER + defined to a number from 0 to 4 cooresponding to each value type */ +#if TYPE_ORDER == 0 +# define NSCTemplateValue NSNonretainedObjectValue +# define TYPE_METHOD nonretainedObjectValue +# define TYPE_NAME id +#elif TYPE_ORDER == 1 +# define NSCTemplateValue NSPointValue +# define TYPE_METHOD pointValue +# define TYPE_NAME NSPoint +#elif TYPE_ORDER == 2 +# define NSCTemplateValue NSPointerValue +# define TYPE_METHOD pointerValue +# define TYPE_NAME void * +#elif TYPE_ORDER == 3 +# define NSCTemplateValue NSRectValue +# define TYPE_METHOD rectValue +# define TYPE_NAME NSRect +#elif TYPE_ORDER == 4 +# define NSCTemplateValue NSSizeValue +# define TYPE_METHOD sizeValue +# define TYPE_NAME NSSize +#endif + +@implementation NSCTemplateValue + +// Allocating and Initializing + +- initValue:(const void *)value + withObjCType:(const char *)type +{ + typedef _dt = data; + self = [super init]; + data = *(_dt *)value; + return self; +} + +// Accessing Data +- (void)getValue:(void *)value +{ + if (!value) { + [NSException raise:NSInvalidArgumentException + format:@"Cannot copy value into NULL buffer"]; + /* NOT REACHED */ + } + memcpy( value, &data, objc_sizeof_type([self objCType]) ); +} + +- (const char *)objCType +{ + typedef _dt = data; + return @encode(_dt); +} + +- (TYPE_NAME)TYPE_METHOD +{ + return data; +} + +// NSCoding +- (void)encodeWithCoder:(NSCoder *)coder +{ +//FIXME [super encodeWithCoder:coder]; + [coder encodeValueOfObjCType:[self objCType] at:&data]; +} + +- (id)initWithCoder:(NSCoder *)coder +{ +//FIXME self = [super initWithCoder:coder]; + [coder decodeValueOfObjCType:[self objCType] at:&data]; + return self; +} + +@end diff --git a/Source/NSConcreteNumber.m b/Source/NSConcreteNumber.m new file mode 100644 index 000000000..4c9998fec --- /dev/null +++ b/Source/NSConcreteNumber.m @@ -0,0 +1,209 @@ +/* NSConcreteNumber - Object encapsulation of numbers + + Copyright (C) 1993,1994 Free Software Foundation, Inc. + + Written by: Adam Fedor + 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 +#include +#include +#include + +/* This file should be run through a preprocessor with the macro TYPE_ORDER + defined to a number from 0 to 12 cooresponding to each number type */ +#if TYPE_ORDER == 0 +# define NumberTemplate NSBoolNumber +# define TYPE_METHOD boolValue +# define TYPE_FORMAT @"%uc" +#elif TYPE_ORDER == 1 +# define NumberTemplate NSUCharNumber +# define TYPE_METHOD unsignedCharValue +# define TYPE_FORMAT @"%uc" +#elif TYPE_ORDER == 2 +# define NumberTemplate NSCharNumber +# define TYPE_METHOD charValue +# define TYPE_FORMAT @"%c" +#elif TYPE_ORDER == 3 +# define NumberTemplate NSUShortNumber +# define TYPE_METHOD unsignedShortValue +# define TYPE_FORMAT @"%hu" +#elif TYPE_ORDER == 4 +# define NumberTemplate NSShortNumber +# define TYPE_METHOD shortValue +# define TYPE_FORMAT @"%hd" +#elif TYPE_ORDER == 5 +# define NumberTemplate NSUIntNumber +# define TYPE_METHOD unsignedIntValue +# define TYPE_FORMAT @"%u" +#elif TYPE_ORDER == 6 +# define NumberTemplate NSIntNumber +# define TYPE_METHOD intValue +# define TYPE_FORMAT @"%d" +#elif TYPE_ORDER == 7 +# define NumberTemplate NSULongNumber +# define TYPE_METHOD unsignedLongValue +# define TYPE_FORMAT @"%lu" +#elif TYPE_ORDER == 8 +# define NumberTemplate NSLongNumber +# define TYPE_METHOD longValue +# define TYPE_FORMAT @"%ld" +#elif TYPE_ORDER == 9 +# define NumberTemplate NSULongLongNumber +# define TYPE_METHOD unsignedLongLongValue +# define TYPE_FORMAT @"%llu" +#elif TYPE_ORDER == 10 +# define NumberTemplate NSLongLongNumber +# define TYPE_METHOD longLongValue +# define TYPE_FORMAT @"%lld" +#elif TYPE_ORDER == 11 +# define NumberTemplate NSFloatNumber +# define TYPE_METHOD floatValue +# define TYPE_FORMAT @"%f" +#elif TYPE_ORDER == 12 +# define NumberTemplate NSDoubleNumber +# define TYPE_METHOD doubleValue +# define TYPE_FORMAT @"%g" +#endif + +@implementation NumberTemplate + +- initValue:(const void *)value withObjCType:(const char *)type; +{ + typedef _dt = data; + self = [super init]; + data = *(_dt *)value; + return self; +} + +- (BOOL)boolValue +{ + return data; +} + +- (char)charValue +{ + return data; +} + +- (double)doubleValue +{ + return data; +} + +- (float)floatValue +{ + return data; +} + +- (int)intValue +{ + return data; +} + +- (long long)longLongValue +{ + return data; +} + +- (long)longValue +{ + return data; +} + +- (short)shortValue +{ + return data; +} + +- (NSString *)stringValue +{ + return [NSString stringWithFormat:TYPE_FORMAT, data]; +} + +- (unsigned char)unsignedCharValue +{ + return data; +} + +- (unsigned int)unsignedIntValue +{ + return data; +} + +- (unsigned long long)unsignedLongLongValue +{ + return data; +} + +- (unsigned long)unsignedLongValue +{ + return data; +} + +- (unsigned short)unsignedShortValue +{ + return data; +} + +- (NSComparisonResult)compare:(NSNumber *)otherNumber +{ + typedef _dt = data; + _dt other_data = [otherNumber TYPE_METHOD]; + + if (data == other_data) + return NSOrderedSame; + else + return (data < other_data) ? NSOrderedAscending : NSOrderedDescending; +} + +// Override these from NSValue +- (void)getValue:(void *)value +{ + if (!value) { + [NSException raise:NSInvalidArgumentException + format:@"Cannot copy value into NULL pointer"]; + /* NOT REACHED */ + } + memcpy( value, &data, objc_sizeof_type([self objCType]) ); +} + +- (const char *)objCType +{ + typedef _dt = data; + return @encode(_dt); +} + +// NSCoding +- (void)encodeWithCoder:(NSCoder *)coder +{ +//FIXME [super encodeWithCoder:coder]; + [coder encodeValueOfObjCType:[self objCType] at:&data]; +} + +- (id)initWithCoder:(NSCoder *)coder +{ +//FIXME self = [super initWithCoder:coder]; + [coder decodeValueOfObjCType:[self objCType] at:&data]; + return self; +} + +@end + diff --git a/Source/NSConcreteValue.m b/Source/NSConcreteValue.m new file mode 100644 index 000000000..3a68f23af --- /dev/null +++ b/Source/NSConcreteValue.m @@ -0,0 +1,160 @@ +/* NSConcreteValue.h - Object encapsulation for C types. + Copyright (C) 1993,1994 Free Software Foundation, Inc. + + Written by: Adam Fedor + 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 +#include +#include +#include +#include +#include + +/* This is the real, general purpose value object. I've implemented all the + methods here (like pointValue) even though most likely, other concrete + subclasses were created to handle these types */ + +#define NS_RAISE_MALLOC \ + [NSException raise:NSMallocException \ + format:@"No memory left to allocate"] + +#define NS_CHECK_MALLOC(ptr) \ + if (!ptr) {NS_RAISE_MALLOC;} + +@implementation NSConcreteValue + +// NSCopying +- deepen +{ + void *old_ptr; + int size; + + size = objc_sizeof_type([objctype cString]); + old_ptr = data; + data = (void *)NSZoneMalloc([self zone], size); + NS_CHECK_MALLOC(data) + memcpy(data, old_ptr, size); + + objctype = [objctype copyWithZone:[self zone]]; + return self; +} + +// Allocating and Initializing + +- initValue:(const void *)value + withObjCType:(const char *)type +{ + int size; + + if (!value || !type) { + [NSException raise:NSInvalidArgumentException + format:@"Cannot create with NULL value or NULL type"]; + /* NOT REACHED */ + } + + self = [super init]; + + // FIXME: objc_sizeof_type will abort when it finds an invalid type, when + // we really want to just raise an exception + size = objc_sizeof_type(type); + if (size <= 0) { + [NSException raise:NSInternalInconsistencyException + format:@"Invalid Objective-C type"]; + /* NOT REACHED */ + } + + data = (void *)NSZoneMalloc([self zone], size); + NS_CHECK_MALLOC(data) + memcpy(data, value, size); + + objctype = [[NSString stringWithCString:type] retain]; + return self; +} + +- (void)dealloc +{ + [objctype release]; + NSZoneFree([self zone], data); + [super dealloc]; +} + +// Accessing Data +- (void)getValue:(void *)value +{ + if (!value) { + [NSException raise:NSInvalidArgumentException + format:@"Cannot copy value into NULL buffer"]; + /* NOT REACHED */ + } + memcpy( value, data, objc_sizeof_type([objctype cString]) ); +} + +- (const char *)objCType +{ + return [objctype cString]; +} + +// FIXME: need to check to make sure these hold the right values... +- (id)nonretainedObjectValue +{ + return *((id *)data); +} + +- (void *)pointerValue +{ + return *((void **)data); +} + +- (NSRect)rectValue +{ + return *((NSRect *)data); +} + +- (NSSize)sizeValue +{ + return *((NSSize *)data); +} + +- (NSPoint)pointValue +{ + return *((NSPoint *)data); +} + +// NSCoding +- (void)encodeWithCoder:(NSCoder *)coder +{ + +//FIXME [super encodeWithCoder:coder]; + // FIXME: Do we need to check for encoding void, void * or will + // NSCoder do this for us? + [coder encodeObject:objctype]; + [coder encodeValueOfObjCType:[objctype cString] at:&data]; +} + +- (id)initWithCoder:(NSCoder *)coder +{ +//FIXME self = [super initWithCoder:coder]; + objctype = [[coder decodeObject] retain]; + [coder decodeValueOfObjCType:[objctype cString] at:&data]; + return self; +} + +@end diff --git a/Source/NSNumber.m b/Source/NSNumber.m new file mode 100644 index 000000000..b8166ba63 --- /dev/null +++ b/Source/NSNumber.m @@ -0,0 +1,265 @@ +/* NSNumber - Object encapsulation of numbers + + Copyright (C) 1993,1994 Free Software Foundation, Inc. + + Written by: Adam Fedor + 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 +#include +#include +#include +#include + +@implementation NSNumber + +/* Returns the concrete class associated with the type encoding. Note + that we don't allow NSNumber to instantiate any class but its own + concrete subclasses (see check at end of method) */ ++ (Class)valueClassWithObjCType:(const char *)type +{ + Class theClass = Nil; + + switch (*type) { + case _C_CHR: + theClass = [NSCharNumber class]; + case _C_UCHR: + theClass = [NSUCharNumber class]; + case _C_SHT: + theClass = [NSShortNumber class]; + case _C_USHT: + theClass = [NSUShortNumber class]; + case _C_INT: + theClass = [NSIntNumber class]; + case _C_UINT: + theClass = [NSUIntNumber class]; + case _C_LNG: + theClass = [NSLongNumber class]; + case _C_ULNG: + theClass = [NSULongNumber class]; + case 'q': + theClass = [NSLongLongNumber class]; + case 'Q': + theClass = [NSULongLongNumber class]; + case _C_FLT: + theClass = [NSFloatNumber class]; + case _C_DBL: + theClass = [NSDoubleNumber class]; + default: + break; + } + + if (theClass == Nil && self == [NSNumber class]) { + [NSException raise:NSInvalidArgumentException + format:@"Invalid number type"]; + /* NOT REACHED */ + } else if (theClass == Nil) + theClass = [super valueClassWithObjCType:type]; + + return theClass; +} + ++ (NSNumber *)numberWithBool:(BOOL)value +{ + return [[[NSBoolNumber alloc] initValue:&value withObjCType:NULL] + autorelease]; +} + ++ (NSNumber *)numberWithChar:(char)value +{ + return [[[NSCharNumber alloc] initValue:&value withObjCType:NULL] + autorelease]; +} + ++ (NSNumber *)numberWithDouble:(double)value +{ + return [[[NSDoubleNumber alloc] initValue:&value withObjCType:NULL] + autorelease]; +} + ++ (NSNumber *)numberWithFloat:(float)value +{ + return [[[NSFloatNumber alloc] initValue:&value withObjCType:NULL] + autorelease]; +} + ++ (NSNumber *)numberWithInt:(int)value +{ + return [[[NSIntNumber alloc] initValue:&value withObjCType:NULL] + autorelease]; +} + ++ (NSNumber *)numberWithLong:(long)value +{ + return [[[NSNumber alloc] initValue:&value withObjCType:NULL] autorelease]; +} + ++ (NSNumber *)numberWithLongLong:(long long)value +{ + return [[[NSLongLongNumber alloc] initValue:&value withObjCType:NULL] + autorelease]; +} + ++ (NSNumber *)numberWithShort:(short)value +{ + return [[[NSShortNumber alloc] initValue:&value withObjCType:NULL] + autorelease]; +} + ++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value +{ + return [[[NSUCharNumber alloc] initValue:&value withObjCType:NULL] + autorelease]; +} + ++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value +{ + return [[[NSUIntNumber alloc] initValue:&value withObjCType:NULL] + autorelease]; +} + ++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value +{ + return [[[NSULongNumber alloc] initValue:&value withObjCType:NULL] + autorelease]; +} + ++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value +{ + return [[[NSULongLongNumber alloc] initValue:&value withObjCType:NULL] + autorelease]; +} + ++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value +{ + return [[[NSUShortNumber alloc] initValue:&value withObjCType:NULL] + autorelease]; +} + +/* All the rest of these methods must be implemented by a subclass */ +- (BOOL)boolValue +{ + [self doesNotRecognizeSelector:_cmd]; + return 0; +} + +- (char)charValue +{ + [self doesNotRecognizeSelector:_cmd]; + return 0; +} + +- (double)doubleValue +{ + [self doesNotRecognizeSelector:_cmd]; + return 0; +} + +- (float)floatValue +{ + [self doesNotRecognizeSelector:_cmd]; + return 0; +} + +- (int)intValue +{ + [self doesNotRecognizeSelector:_cmd]; + return 0; +} + +- (long long)longLongValue +{ + [self doesNotRecognizeSelector:_cmd]; + return 0; +} + +- (long)longValue +{ + [self doesNotRecognizeSelector:_cmd]; + return 0; +} + +- (short)shortValue +{ + [self doesNotRecognizeSelector:_cmd]; + return 0; +} + +- (NSString *)stringValue +{ + [self doesNotRecognizeSelector:_cmd]; + return 0; +} + +- (unsigned char)unsignedCharValue +{ + [self doesNotRecognizeSelector:_cmd]; + return 0; +} + +- (unsigned int)unsignedIntValue +{ + [self doesNotRecognizeSelector:_cmd]; + return 0; +} + +- (unsigned long long)unsignedLongLongValue +{ + [self doesNotRecognizeSelector:_cmd]; + return 0; +} + +- (unsigned long)unsignedLongValue +{ + [self doesNotRecognizeSelector:_cmd]; + return 0; +} + +- (unsigned short)unsignedShortValue +{ + [self doesNotRecognizeSelector:_cmd]; + return 0; +} + +- (NSComparisonResult)compare:(NSNumber *)otherNumber +{ + [self doesNotRecognizeSelector:_cmd]; + return 0; +} + +// NSCoding (done by subclasses) +- classForCoder +{ + return [self class]; +} + +- (void)encodeWithCoder:(NSCoder *)coder +{ +//FIXME [super encodeWithCoder:coder]; +} + +- (id)initWithCoder:(NSCoder *)coder +{ +//FIXME self = [super initWithCoder:coder]; + return self; +} + +@end + diff --git a/Source/NSRange.m b/Source/NSRange.m new file mode 100644 index 000000000..f4061fd15 --- /dev/null +++ b/Source/NSRange.m @@ -0,0 +1,56 @@ +/* NSRange - range functions + +*/ + +#include + +NSRange +NSMakeRange(float location, float length) +{ + NSRange range; + range.location = location; + range.length = length; + return range; +} + +/* Query a Range */ +BOOL +NSEqualRanges(NSRange range1, NSRange range2) +{ + return ((range1.location == range2.location) + && (range1.length == range2.length)); +} + +/* Compute a Range from Two Other Ranges */ +NSRange +NSUnionRange(NSRange aRange, NSRange bRange) +{ + NSRange range; + + range.location = MIN(aRange.location, bRange.location); + range.length = MAX(NSMaxRange(aRange), NSMaxRange(bRange)) + - range.location; + return range; +} + +NSRange +NSIntersectionRange (NSRange aRange, NSRange bRange) +{ + NSRange range; + + if (NSMaxRange(aRange) < bRange.location + || NSMaxRange(bRange) < aRange.location) + return NSMakeRange(0, 0); + + range.location = MAX(aRange.location, bRange.location); + range.length = MIN(NSMaxRange(aRange), NSMaxRange(bRange)) + - range.location; + return range; +} + +NSString * +NSStringFromRange(NSRange range) +{ + return [NSString stringWithFormat:@"{location = %d, length = %d}", + range.location, range.length]; +} diff --git a/Source/dld-load.h b/Source/dld-load.h new file mode 100644 index 000000000..2a4c7e2b7 --- /dev/null +++ b/Source/dld-load.h @@ -0,0 +1,140 @@ +/* + dld-load - Definitions and translations for dynamic loading with GNU dld. + + Copyright (C) 1995, Adam Fedor. + + BUGS: + - object files loaded by dld must be loaded with 'ld -r' rather + than 'gcc -nostdlib', because dld can't handle multiple symbols + like multiple CTOR_LISTS. So here we construct our own CTOR + list and return it when asked for (Ack! Pthet!). + - __dld_construct_ctor_list may find a constructor that belongs + to another module whose name is a super-string of the desired + module name. + + $Id$ +*/ + +#ifndef __dld_load_h_INCLUDE +#define __dld_load_h_INCLUDE + +#include + +/* This is the GNU gcc name for the CTOR list */ +#define DLD_CTOR_LIST "___CTOR_LIST__" + +/* The compiler generates a constructor function for each class. The function + has the prefix given below. +*/ +#define GLOBAL_PREFIX "_GLOBAL_$I$" + +/* Types defined appropriately for the dynamic linker */ +typedef char* dl_handle_t; +typedef unsigned long dl_symbol_t; + +static void **dld_ctor_list = 0; + +static void** +__dld_construct_ctor_list(dl_handle_t module) +{ + int i, ctors, length; + + length = 100; + ctors = 1; + if (dld_ctor_list) + free(dld_ctor_list); + dld_ctor_list = (void **) __objc_xmalloc(length * sizeof(void *)); + /* Find all symbols with the GLOBAL_PREFIX prefix */ + for (i=0; i < TABSIZE; i++) { + struct glosym *sym_entry = _dld_symtab[i]; + for (; sym_entry; sym_entry = sym_entry->link) { + if (strstr(sym_entry->name, GLOBAL_PREFIX) + && strstr(sym_entry->defined_by->filename, module)) { + dld_ctor_list[ctors] = (void **)sym_entry->value; + ctors++; + if (ctors > length) { + length *= 2; + dld_ctor_list = (void **) __objc_xrealloc(dld_ctor_list, + length * sizeof(void *)); + } + } + } + } + dld_ctor_list[ctors] = (void **)0; + dld_ctor_list[0] = (void **)(ctors - 1); + + return dld_ctor_list; +} + +/* Do any initialization necessary. Return 0 on success (or + if no initialization needed. +*/ +static int +__objc_dynamic_init(const char* exec_path) +{ + return dld_init(exec_path); +} + +/* Link in the module given by the name 'module'. Return a handle which can + be used to get information about the loded code. +*/ +static dl_handle_t +__objc_dynamic_link(const char* module, int mode, const char* debug_file) +{ + int error; + dl_handle_t handle; + + error = dld_link(module); + if (error) + return NULL; + handle = (dl_handle_t)__objc_xmalloc (strlen(module) + 1); + strcpy(handle, module); + return handle; +} + +/* Return the address of a symbol given by the name 'symbol' from the module + associated with 'handle' +*/ +static dl_symbol_t +__objc_dynamic_find_symbol(dl_handle_t handle, const char* symbol) +{ + if (strcmp(symbol, DLD_CTOR_LIST) == 0) { + return (dl_symbol_t)__dld_construct_ctor_list(handle); + } + return dld_get_bare_symbol(symbol); +} + +/* remove the code from memory associated with the module 'handle' */ +static int +__objc_dynamic_unlink(dl_handle_t handle) +{ + int error; + error = dld_unlink_by_file(handle, 0); + free(handle); + return error; +} + +/* Print an error message (prefaced by 'error_string') relevant to the + last error encountered +*/ +static void +__objc_dynamic_error(FILE *error_stream, const char *error_string) +{ + /* dld won't print to error stream, sorry */ + dld_perror(error_string); +} + +/* Debugging: define these if they are available */ +static int +__objc_dynamic_undefined_symbol_count(void) +{ + return dld_undefined_sym_count; +} + +static char** +__objc_dynamic_list_undefined_symbols(void) +{ + return dld_list_undefined_sym(); +} + +#endif /* __dld_load_h_INCLUDE */ diff --git a/Source/hpux-load.h b/Source/hpux-load.h new file mode 100644 index 000000000..99958ba6a --- /dev/null +++ b/Source/hpux-load.h @@ -0,0 +1,77 @@ +/* + hpux-load - Definitions and translations for dynamic loading with HP-UX + + Copyright (C) 1995, Adam Fedor. + + $Id$ +*/ + +#ifndef __hpux_load_h_INCLUDE +#define __hpux_load_h_INCLUDE + +#include + +/* Types defined appropriately for the dynamic linker */ +typedef shl_t dl_handle_t; +typedef void* dl_symbol_t; + +/* Do any initialization necessary. Return 0 on success (or + if no initialization needed. +*/ +static int +__objc_dynamic_init(const char* exec_path) +{ + return 0; +} + +/* Link in the module given by the name 'module'. Return a handle which can + be used to get information about the loded code. +*/ +static dl_handle_t +__objc_dynamic_link(const char* module, int mode, const char* debug_file) +{ + return (dl_handle_t)shl_load(module, 0, 0); +} + +/* Return the address of a symbol given by the name 'symbol' from the module + associated with 'handle' +*/ +static dl_symbol_t +__objc_dynamic_find_symbol(dl_handle_t handle, const char* symbol) +{ + int ok; + void *value; + ok = shl_findsym(&handle, symbol, 0, value); + return value; +} + +/* remove the code from memory associated with the module 'handle' */ +static int +__objc_dynamic_unlink(dl_handle_t handle) +{ + return shl_unload(handle); +} + +/* Print an error message (prefaced by 'error_string') relevant to the + last error encountered +*/ +static void +__objc_dynamic_error(FILE *error_stream, const char *error_string) +{ + fprintf(error_stream, "%s\n", error_string); +} + +/* Debugging: define these if they are available */ +static int +__objc_dynamic_undefined_symbol_count(void) +{ + return 0; +} + +static char** +__objc_dynamic_list_undefined_symbols(void) +{ + return NULL; +} + +#endif /* __HPUX_LOAD_INCLUDE__ */ diff --git a/Source/null-load.h b/Source/null-load.h new file mode 100644 index 000000000..36fb159ea --- /dev/null +++ b/Source/null-load.h @@ -0,0 +1,73 @@ +/* + null-load - NULL dynamic loader. Doesn't do anything. + + Copyright (C) 1995, Adam Fedor. + + $Id$ +*/ + +#ifndef __null_load_h_INCLUDE +#define __null_load_h_INCLUDE + + +/* Types defined appropriately for the dynamic linker */ +typedef void* dl_handle_t; +typedef void* dl_symbol_t; + +/* Do any initialization necessary. Return 0 on success (or + if no initialization needed. +*/ +static int +__objc_dynamic_init(const char* exec_path) +{ + return -1; +} + +/* Link in the module given by the name 'module'. Return a handle which can + be used to get information about the loded code. +*/ +static dl_handle_t +__objc_dynamic_link(const char* module, int mode, const char* debug_file) +{ + return 0; +} + +/* Return the address of a symbol given by the name 'symbol' from the module + associated with 'handle' +*/ +static dl_symbol_t +__objc_dynamic_find_symbol(dl_handle_t handle, const char* symbol) +{ + return 0; +} + +/* remove the code from memory associated with the module 'handle' */ +static int +__objc_dynamic_unlink(dl_handle_t handle) +{ + return 0; +} + +/* Print an error message (prefaced by 'error_string') relevant to the + last error encountered +*/ +static void +__objc_dynamic_error(FILE *error_stream, const char *error_string) +{ + fprintf(error_stream, "%s\n", error_string); +} + +/* Debugging: define these if they are available */ +static int +__objc_dynamic_undefined_symbol_count(void) +{ + return 0; +} + +static char** +__objc_dynamic_list_undefined_symbols(void) +{ + return NULL; +} + +#endif /* __null_load_h_INCLUDE */ diff --git a/Source/objc-load.c b/Source/objc-load.c new file mode 100644 index 000000000..de8cdb85e --- /dev/null +++ b/Source/objc-load.c @@ -0,0 +1,224 @@ +/* + objc-load - Dynamically load in Obj-C modules (Classes, Categories) + + Written by Adam Fedor, Pedja Bogdanovich + + $Id$ + + BUGS: + - unloading modules not implemented + - would like to raise exceptions without having to turn this into + a .m file (right now NSBundle does this for us, ok?) + +*/ + +#include +#include +#include +#include +#include + +/* include the interface to the dynamic linker */ +#include "dynamic-load.h" + +/* From the objc runtime -- needed when invalidating the dtable */ +extern void __objc_install_premature_dtable(Class); +extern void sarray_free(struct sarray*); +extern struct sarray *__objc_uninstalled_dtable; + +extern char *objc_find_executable(const char *name); + +/* This is the GNU name for the CTOR list */ +#define CTOR_LIST "___CTOR_LIST__" + +/* External variables needed to find the path to the executable program. */ +extern char **NSArgv; + +/* dynamic_loaded is YES if the dynamic loader was sucessfully initialized. */ +static BOOL dynamic_loaded; + +/* Our current callback function */ +void (*_objc_load_load_callback)(Class, Category*) = 0; + +/* List of modules we have loaded (by handle) */ +static struct objc_list *dynamic_handles = NULL; + +/* Check to see if there are any undefined symbols. Print them out. +*/ +static int +objc_check_undefineds(FILE *errorStream) +{ + int count = __objc_dynamic_undefined_symbol_count(); + + if (count != 0) { + int i; + char **undefs; + undefs = __objc_dynamic_list_undefined_symbols(); + if (errorStream) + fprintf(errorStream, "Undefined symbols:\n"); + for (i=0; i < count; i++) + if (errorStream) + fprintf(errorStream, " %s\n", undefs[i]); + return 1; + } + return 0; +} + +char * +objc_executable_location() +{ + return objc_find_executable(NSArgv[0]); +} + +/* Invalidate the dtable so it will be rebuild when a message is sent to + the object */ +static void +objc_invalidate_dtable(Class class) +{ + Class s; + + if (class->dtable == __objc_uninstalled_dtable) + return; + sarray_free(class->dtable); + __objc_install_premature_dtable(class); + for (s=class->subclass_list; s; s=s->sibling_class) + objc_invalidate_dtable(s); +} + +/* Initialize for dynamic loading */ +static int +objc_initialize_loading(FILE *errorStream) +{ + char *path; + + dynamic_loaded = NO; + path = objc_executable_location(); +#ifdef DEBUG + printf("Debug (objc-load): initializing dynamic loader for %s\n", path); +#endif + if (__objc_dynamic_init(path)) { + if (errorStream) + __objc_dynamic_error(errorStream, "Error (objc-load): Cannot initialize dynamic linker"); + return 1; + } else + dynamic_loaded = YES; + free(path); + + return 0; +} + +/* A callback received from the Object initializer (_objc_exec_class). + Do what we need to do and call our own callback. +*/ +static void +objc_load_callback(Class class, Category* category) +{ + /* Invalidate the dtable, so it will be rebuilt correctly */ + if (class != 0 && category != 0) { + objc_invalidate_dtable(class); + objc_invalidate_dtable(class->class_pointer); + } + + if (_objc_load_load_callback) + _objc_load_load_callback(class, category); +} + +long +objc_load_module( + const char *filename, + FILE *errorStream, + void (*loadCallback)(Class, Category*), + void **header, + char *debugFilename) + +{ + typedef void (*void_fn)(); + void_fn *ctor_list; + dl_handle_t handle; + int i; + + if (!dynamic_loaded) + if (objc_initialize_loading(errorStream)) + return 1; + + /* Link in the object file */ +#ifdef DEBUG + printf("Debug (objc-load): Linking file %s\n", filename); +#endif + handle = __objc_dynamic_link(filename, 1, debugFilename); + if (handle == 0) { + if (errorStream) + __objc_dynamic_error(errorStream, "Error (objc-load)"); + return 1; + } + dynamic_handles = list_cons(handle, dynamic_handles); + + /* If there are any undefined symbols, we can't load the bundle */ + if (objc_check_undefineds(errorStream)) { + __objc_dynamic_unlink(handle); + return 1; + } + + /* Get the constructor list and load in the objects */ + ctor_list = (void_fn *)__objc_dynamic_find_symbol(handle, CTOR_LIST); + if (!ctor_list) { + if (errorStream) + fprintf(errorStream, "Error (objc-load): Cannot load objects (no CTOR list)\n"); + return 1; + } + + _objc_load_load_callback = loadCallback; + _objc_load_callback = objc_load_callback; +#ifdef DEBUG + printf("Debug (objc-load): %d modules\n", (int)ctor_list[0]); +#endif + for (i=1; ctor_list[i]; i++) { +#ifdef DEBUG + printf("Debug (objc-load): Invoking CTOR %p\n", ctor_list[i]); +#endif + ctor_list[i](); + } + _objc_load_callback = 0; + _objc_load_load_callback = 0; + return 0; +} + +long +objc_unload_module( + FILE *errorStream, + void (*unloadCallback)(Class, Category*)) +{ + if (!dynamic_loaded) + return 1; + + if (errorStream) + fprintf(errorStream, "Warning: unloading modules not implemented\n"); + return 0; +} + +long objc_loadModules(char *files[],FILE *errorStream, + void (*callback)(Class,Category*), + void **header, + char *debugFilename) +{ + while (*files) { + if (objc_load_module(*files, errorStream, callback, + (void *)header, debugFilename)) + return 1; + files++; + } + return 0; +} + +long +objc_unloadModules( + FILE *errorStream, + void (*unloadCallback)(Class, Category*)) +{ + if (!dynamic_loaded) + return 1; + + if (errorStream) + fprintf(errorStream, "Warning: unloading modules not implemented\n"); + return 0; +} diff --git a/Source/simple-load.h b/Source/simple-load.h new file mode 100644 index 000000000..df6bd73c5 --- /dev/null +++ b/Source/simple-load.h @@ -0,0 +1,85 @@ +/* + simple-load - Definitions and translations for dynamic loading with + the simple dynamic liading library (dl). + + Copyright (C) 1995, Adam Fedor. + + BUGS: + - In SunOS 4.1, dlopen will only resolve references into the main + module and not into other modules loaded earlier. dlopen will exit + if there are undefined symbols. Later versions (e.g. 5.3) fix this + with RTLD_GLOBAL. + + $Id$ +*/ + +#ifndef __sunos_load_h_INCLUDE +#define __sunos_load_h_INCLUDE + +#include + +#ifndef RTLD_GLOBAL +#define RTLD_GLOBAL 0 +#endif + +/* Types defined appropriately for the dynamic linker */ +typedef void* dl_handle_t; +typedef void* dl_symbol_t; + +/* Do any initialization necessary. Return 0 on success (or + if no initialization needed. +*/ +static int +__objc_dynamic_init(const char* exec_path) +{ + return 0; +} + +/* Link in the module given by the name 'module'. Return a handle which can + be used to get information about the loded code. +*/ +static dl_handle_t +__objc_dynamic_link(const char* module, int mode, const char* debug_file) +{ + return (dl_handle_t)dlopen(module, RTLD_LAZY | RTLD_GLOBAL); +} + +/* Return the address of a symbol given by the name 'symbol' from the module + associated with 'handle' +*/ +static dl_symbol_t +__objc_dynamic_find_symbol(dl_handle_t handle, const char* symbol) +{ + return dlsym(handle, symbol); +} + +/* remove the code from memory associated with the module 'handle' */ +static int +__objc_dynamic_unlink(dl_handle_t handle) +{ + return dlclose(handle); +} + +/* Print an error message (prefaced by 'error_string') relevant to the + last error encountered +*/ +static void +__objc_dynamic_error(FILE *error_stream, const char *error_string) +{ + fprintf(error_stream, "%s:%s\n", error_string, dlerror()); +} + +/* Debugging: define these if they are available */ +static int +__objc_dynamic_undefined_symbol_count(void) +{ + return 0; +} + +static char** +__objc_dynamic_list_undefined_symbols(void) +{ + return NULL; +} + +#endif /* __sunos_load_h_INCLUDE */ diff --git a/Testing/values.m b/Testing/values.m new file mode 100644 index 000000000..4c508356b --- /dev/null +++ b/Testing/values.m @@ -0,0 +1,62 @@ +/* + Test NSValue, NSNumber, and related classes + +*/ + +#include +#include +#include +#include + + +int main() +{ + NSPoint p; + NSRect rect; + NSValue *v1, *v2; + NSNumber *n1, *n2; + + // Numbers + n1 = [NSNumber numberWithUnsignedShort:30]; + n2 = [NSNumber numberWithDouble:2.7]; + printf("Number(n1) as int %d, as float %f\n", + [n1 intValue], [n1 floatValue]); + printf("n1 times n2=%f as int to get %d\n", + [n2 floatValue], [n1 intValue]*[n2 intValue]); + printf("n2 as string: %s\n", [[n2 stringValue] cString]); + printf("n2 compare:n1 is %d\n", [n2 compare:n1]); + printf("n1 compare:n2 is %d\n", [n1 compare:n2]); + + + // Test values, Geometry + rect = NSMakeRect(1.0, 103.3, 40.0, 843.); + rect = NSIntersectionRect(rect, NSMakeRect(20, 78., 89., 30)); + v1 = [NSValue valueWithRect:rect]; + printf("Encoding for rect is %s\n", [v1 objCType]); + rect = [v1 rectValue]; + printf("Rect is %f %f %f %f\n", NSMinX(rect), NSMinY(rect), NSMaxX(rect), + NSMaxY(rect)); + v2 = [NSValue valueWithPoint:NSMakePoint(3,4)]; + v1 = [NSValue valueWithNonretainedObject:v2]; + [[v1 nonretainedObjectValue] getValue:&p]; + printf("point is %f %f\n", p.x, p.y); + + // Exceptions +NS_DURING + + NS_DURING + v2 = [NSValue value:NULL withObjCType:@encode(int)]; + NS_HANDLER + printf("Caught our exception, name %s and reason: %s\n", + [[exception name] cString], [[exception reason] cString]); + [exception raise]; + NS_ENDHANDLER + +NS_HANDLER + printf("Caught our reraised exception, name %s and reason: %s\n", + [[exception name] cString], [[exception reason] cString]); + +NS_ENDHANDLER + + return 0; +}