diff options
author | bje <bje@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-09-21 01:22:07 +0000 |
---|---|---|
committer | bje <bje@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-09-21 01:22:07 +0000 |
commit | 8a7d0ecc89848fa1b5bd4af83609f07ee93d11e3 (patch) | |
tree | 74295f11944f5c930aca90bb544749afb89e227c /libobjc/Object.m | |
parent | 6f52bf52570132d0a271a1c5b3990e051e6c5be3 (diff) | |
download | gcc-8a7d0ecc89848fa1b5bd4af83609f07ee93d11e3.tar.gz |
1998-09-21 Ben Elliston <bje@cygnus.com>
* New directory. Moved files from ../gcc/objc.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@22514 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libobjc/Object.m')
-rw-r--r-- | libobjc/Object.m | 387 |
1 files changed, 387 insertions, 0 deletions
diff --git a/libobjc/Object.m b/libobjc/Object.m new file mode 100644 index 00000000000..64b52f48368 --- /dev/null +++ b/libobjc/Object.m @@ -0,0 +1,387 @@ +/* The implementation of class Object for Objective-C. + Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc. + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +GNU CC 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 General Public +License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* As a special exception, if you link this library with files compiled + with GCC to produce an executable, this does not cause the resulting + executable to be covered by the GNU General Public License. This + exception does not however invalidate any other reasons why the + executable file might be covered by the GNU General Public License. */ + +#include <stdarg.h> +#include "objc/Object.h" +#include "objc/Protocol.h" +#include "objc/objc-api.h" + +extern int errno; + +#define MAX_CLASS_NAME_LEN 256 + +@implementation Object + ++ initialize +{ + return self; +} + +- init +{ + return self; +} + ++ new +{ + return [[self alloc] init]; +} + ++ alloc +{ + return class_create_instance(self); +} + +- free +{ + return object_dispose(self); +} + +- copy +{ + return [[self shallowCopy] deepen]; +} + +- shallowCopy +{ + return object_copy(self); +} + +- deepen +{ + return self; +} + +- deepCopy +{ + return [self copy]; +} + +- (Class)class +{ + return object_get_class(self); +} + +- (Class)superClass +{ + return object_get_super_class(self); +} + +- (MetaClass)metaClass +{ + return object_get_meta_class(self); +} + +- (const char *)name +{ + return object_get_class_name(self); +} + +- self +{ + return self; +} + +- (unsigned int)hash +{ + return (size_t)self; +} + +- (BOOL)isEqual:anObject +{ + return self==anObject; +} + +- (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; +} + +- (BOOL)isMetaClass +{ + return NO; +} + +- (BOOL)isClass +{ + return object_is_class(self); +} + +- (BOOL)isInstance +{ + return object_is_instance(self); +} + +- (BOOL)isKindOf:(Class)aClassObject +{ + Class class; + + for (class = self->isa; class!=Nil; class = class_get_super_class(class)) + if (class==aClassObject) + return YES; + return NO; +} + +- (BOOL)isMemberOf:(Class)aClassObject +{ + return self->isa==aClassObject; +} + +- (BOOL)isKindOfClassNamed:(const char *)aClassName +{ + Class class; + + if (aClassName!=NULL) + for (class = self->isa; class!=Nil; class = class_get_super_class(class)) + if (!strcmp(class_get_class_name(class), aClassName)) + return YES; + return NO; +} + +- (BOOL)isMemberOfClassNamed:(const char *)aClassName +{ + return ((aClassName!=NULL) + &&!strcmp(class_get_class_name(self->isa), aClassName)); +} + ++ (BOOL)instancesRespondTo:(SEL)aSel +{ + return class_get_instance_method(self, aSel)!=METHOD_NULL; +} + +- (BOOL)respondsTo:(SEL)aSel +{ + return ((object_is_instance(self) + ?class_get_instance_method(self->isa, aSel) + :class_get_class_method(self->isa, aSel))!=METHOD_NULL); +} + ++ (IMP)instanceMethodFor:(SEL)aSel +{ + return method_get_imp(class_get_instance_method(self, aSel)); +} + +// Indicates if the receiving class or instance conforms to the given protocol +// not usually overridden by subclasses +// +// Modified 9/5/94 to always search the class object's protocol list, rather +// than the meta class. + ++ (BOOL) conformsTo: (Protocol*)aProtocol +{ + int i; + struct objc_protocol_list* proto_list; + id parent; + + for (proto_list = ((Class)self)->protocols; + proto_list; proto_list = proto_list->next) + { + for (i=0; i < proto_list->count; i++) + { + if ([proto_list->list[i] conformsTo: aProtocol]) + return YES; + } + } + + if ((parent = [self superClass])) + return [parent conformsTo: aProtocol]; + else + return NO; +} + +- (BOOL) conformsTo: (Protocol*)aProtocol +{ + return [[self class] conformsTo:aProtocol]; +} + +- (IMP)methodFor:(SEL)aSel +{ + return (method_get_imp(object_is_instance(self) + ?class_get_instance_method(self->isa, aSel) + :class_get_class_method(self->isa, aSel))); +} + ++ (struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel +{ + return ((struct objc_method_description *) + class_get_instance_method(self, aSel)); +} + +- (struct objc_method_description *)descriptionForMethod:(SEL)aSel +{ + return ((struct objc_method_description *) + (object_is_instance(self) + ?class_get_instance_method(self->isa, aSel) + :class_get_class_method(self->isa, aSel))); +} + +- perform:(SEL)aSel +{ + IMP msg = objc_msg_lookup(self, aSel); + if (!msg) + return [self error:"invalid selector passed to %s", sel_get_name(_cmd)]; + return (*msg)(self, aSel); +} + +- perform:(SEL)aSel with:anObject +{ + IMP msg = objc_msg_lookup(self, aSel); + if (!msg) + return [self error:"invalid selector passed to %s", sel_get_name(_cmd)]; + return (*msg)(self, aSel, anObject); +} + +- perform:(SEL)aSel with:anObject1 with:anObject2 +{ + IMP msg = objc_msg_lookup(self, aSel); + if (!msg) + return [self error:"invalid selector passed to %s", sel_get_name(_cmd)]; + return (*msg)(self, aSel, anObject1, anObject2); +} + +- (retval_t)forward:(SEL)aSel :(arglist_t)argFrame +{ + return (retval_t)[self doesNotRecognize: aSel]; +} + +- (retval_t)performv:(SEL)aSel :(arglist_t)argFrame +{ + return objc_msg_sendv(self, aSel, argFrame); +} + ++ poseAs:(Class)aClassObject +{ + return class_pose_as(self, aClassObject); +} + +- (Class)transmuteClassTo:(Class)aClassObject +{ + if (object_is_instance(self)) + if (class_is_class(aClassObject)) + if (class_get_instance_size(aClassObject)==class_get_instance_size(isa)) + if ([self isKindOf:aClassObject]) + { + Class old_isa = isa; + isa = aClassObject; + return old_isa; + } + return nil; +} + +- subclassResponsibility:(SEL)aSel +{ + return [self error:"subclass should override %s", sel_get_name(aSel)]; +} + +- notImplemented:(SEL)aSel +{ + return [self error:"method %s not implemented", sel_get_name(aSel)]; +} + +- shouldNotImplement:(SEL)aSel +{ + return [self error:"%s should not implement %s", + object_get_class_name(self), sel_get_name(aSel)]; +} + +- doesNotRecognize:(SEL)aSel +{ + return [self error:"%s does not recognize %s", + object_get_class_name(self), sel_get_name(aSel)]; +} + +#ifdef __alpha__ +extern size_t strlen(const char*); +#endif + +- error:(const char *)aString, ... +{ +#define FMT "error: %s (%s)\n%s\n" + char fmt[(strlen((char*)FMT)+strlen((char*)object_get_class_name(self)) + +((aString!=NULL)?strlen((char*)aString):0)+8)]; + va_list ap; + + sprintf(fmt, FMT, object_get_class_name(self), + object_is_instance(self)?"instance":"class", + (aString!=NULL)?aString:""); + va_start(ap, aString); + objc_verror(self, OBJC_ERR_UNKNOWN, fmt, ap); + va_end(ap); + return nil; +#undef FMT +} + ++ (int)version +{ + return class_get_version(self); +} + ++ setVersion:(int)aVersion +{ + class_set_version(self, aVersion); + return self; +} + ++ (int)streamVersion: (TypedStream*)aStream +{ + if (aStream->mode == OBJC_READONLY) + return objc_get_stream_class_version (aStream, self); + else + return class_get_version (self); +} + +// These are used to write or read the instance variables +// declared in this particular part of the object. Subclasses +// should extend these, by calling [super read/write: aStream] +// before doing their own archiving. These methods are private, in +// the sense that they should only be called from subclasses. + +- read: (TypedStream*)aStream +{ + // [super read: aStream]; + return self; +} + +- write: (TypedStream*)aStream +{ + // [super write: aStream]; + return self; +} + +- awake +{ + // [super awake]; + return self; +} + +@end |