2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / libobjc / Object.m
blob7425ff33877a034b4b2ba116e79a2c530e84e4b8
1 /* The implementation of class Object for Objective-C.
2    Copyright (C) 1993, 1994, 1995, 1997, 2002 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14 License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  */
21 /* As a special exception, if you link this library with files compiled
22    with GCC to produce an executable, this does not cause the resulting
23    executable to be covered by the GNU General Public License.  This
24    exception does not however invalidate any other reasons why the
25    executable file might be covered by the GNU General Public License. */
27 #include <stdarg.h>
28 #include "objc/Object.h"
29 #include "objc/Protocol.h"
30 #include "objc/objc-api.h"
32 extern int errno;
34 #define MAX_CLASS_NAME_LEN 256
36 @implementation Object
38 + initialize
40   return self;
43 - init
45   return self;
48 + new
50   return [[self alloc] init];
53 + alloc
55   return class_create_instance(self);
58 - free
60   return object_dispose(self);
63 - copy
65   return [[self shallowCopy] deepen];
68 - shallowCopy
70   return object_copy(self);
73 - deepen
75   return self;
78 - deepCopy
80   return [self copy];
83 - (Class)class
85   return object_get_class(self);
88 - (Class)superClass
90   return object_get_super_class(self);
93 - (MetaClass)metaClass
95   return object_get_meta_class(self);
98 - (const char *)name
100   return object_get_class_name(self);
103 - self
105   return self;
108 - (unsigned int)hash
110   return (size_t)self;
113 - (BOOL)isEqual:anObject
115   return self==anObject;
118 - (int)compare:anotherObject;
120   if ([self isEqual:anotherObject])
121     return 0;
122   // Ordering objects by their address is pretty useless, 
123   // so subclasses should override this is some useful way.
124   else if (self > anotherObject)
125     return 1;
126   else 
127     return -1;
130 - (BOOL)isMetaClass
132   return NO;
135 - (BOOL)isClass
137   return object_is_class(self);
140 - (BOOL)isInstance
142   return object_is_instance(self);
145 - (BOOL)isKindOf:(Class)aClassObject
147   Class class;
149   for (class = self->isa; class!=Nil; class = class_get_super_class(class))
150     if (class==aClassObject)
151       return YES;
152   return NO;
155 - (BOOL)isMemberOf:(Class)aClassObject
157   return self->isa==aClassObject;
160 - (BOOL)isKindOfClassNamed:(const char *)aClassName
162   Class class;
164   if (aClassName!=NULL)
165     for (class = self->isa; class!=Nil; class = class_get_super_class(class))
166       if (!strcmp(class_get_class_name(class), aClassName))
167         return YES;
168   return NO;
171 - (BOOL)isMemberOfClassNamed:(const char *)aClassName
173   return ((aClassName!=NULL)
174           &&!strcmp(class_get_class_name(self->isa), aClassName));
177 + (BOOL)instancesRespondTo:(SEL)aSel
179   return class_get_instance_method(self, aSel)!=METHOD_NULL;
182 - (BOOL)respondsTo:(SEL)aSel
184   return ((object_is_instance(self)
185            ?class_get_instance_method(self->isa, aSel)
186            :class_get_class_method(self->isa, aSel))!=METHOD_NULL);
189 + (IMP)instanceMethodFor:(SEL)aSel
191   return method_get_imp(class_get_instance_method(self, aSel));
194 // Indicates if the receiving class or instance conforms to the given protocol
195 // not usually overridden by subclasses
197 // Modified 9/5/94 to always search the class object's protocol list, rather
198 // than the meta class.
200 + (BOOL) conformsTo: (Protocol*)aProtocol
202   size_t i;
203   struct objc_protocol_list* proto_list;
204   id parent;
206   for (proto_list = ((Class)self)->protocols;
207        proto_list; proto_list = proto_list->next)
208     {
209       for (i=0; i < proto_list->count; i++)
210       {
211         if ([proto_list->list[i] conformsTo: aProtocol])
212           return YES;
213       }
214     }
216   if ((parent = [self superClass]))
217     return [parent conformsTo: aProtocol];
218   else
219     return NO;
222 - (BOOL) conformsTo: (Protocol*)aProtocol
224   return [[self class] conformsTo:aProtocol];
227 - (IMP)methodFor:(SEL)aSel
229   return (method_get_imp(object_is_instance(self)
230                          ?class_get_instance_method(self->isa, aSel)
231                          :class_get_class_method(self->isa, aSel)));
234 + (struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel
236   return ((struct objc_method_description *)
237            class_get_instance_method(self, aSel));
240 - (struct objc_method_description *)descriptionForMethod:(SEL)aSel
242   return ((struct objc_method_description *)
243            (object_is_instance(self)
244             ?class_get_instance_method(self->isa, aSel)
245             :class_get_class_method(self->isa, aSel)));
248 - perform:(SEL)aSel
250   IMP msg = objc_msg_lookup(self, aSel);
251   if (!msg)
252     return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
253   return (*msg)(self, aSel);
256 - perform:(SEL)aSel with:anObject
258   IMP msg = objc_msg_lookup(self, aSel);
259   if (!msg)
260     return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
261   return (*msg)(self, aSel, anObject);
264 - perform:(SEL)aSel with:anObject1 with:anObject2
266   IMP msg = objc_msg_lookup(self, aSel);
267   if (!msg)
268     return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
269   return (*msg)(self, aSel, anObject1, anObject2);
272 - (retval_t)forward:(SEL)aSel :(arglist_t)argFrame
274   (void) argFrame; /* UNUSED */
275   return (retval_t)[self doesNotRecognize: aSel];
278 - (retval_t)performv:(SEL)aSel :(arglist_t)argFrame
280   return objc_msg_sendv(self, aSel, argFrame);
283 + poseAs:(Class)aClassObject
285   return class_pose_as(self, aClassObject);
288 - (Class)transmuteClassTo:(Class)aClassObject
290   if (object_is_instance(self))
291     if (class_is_class(aClassObject))
292       if (class_get_instance_size(aClassObject)==class_get_instance_size(isa))
293         if ([self isKindOf:aClassObject])
294           {
295             Class old_isa = isa;
296             isa = aClassObject;
297             return old_isa;
298           }
299   return nil;
302 - subclassResponsibility:(SEL)aSel
304   return [self error:"subclass should override %s", sel_get_name(aSel)];
307 - notImplemented:(SEL)aSel
309   return [self error:"method %s not implemented", sel_get_name(aSel)];
312 - shouldNotImplement:(SEL)aSel
314   return [self error:"%s should not implement %s", 
315                      object_get_class_name(self), sel_get_name(aSel)];
318 - doesNotRecognize:(SEL)aSel
320   return [self error:"%s does not recognize %s",
321                      object_get_class_name(self), sel_get_name(aSel)];
324 - error:(const char *)aString, ...
326 #define FMT "error: %s (%s)\n%s\n"
327   char fmt[(strlen((char*)FMT)+strlen((char*)object_get_class_name(self))
328             +((aString!=NULL)?strlen((char*)aString):0)+8)];
329   va_list ap;
331   sprintf(fmt, FMT, object_get_class_name(self),
332                     object_is_instance(self)?"instance":"class",
333                     (aString!=NULL)?aString:"");
334   va_start(ap, aString);
335   objc_verror(self, OBJC_ERR_UNKNOWN, fmt, ap);
336   va_end(ap);
337   return nil;
338 #undef FMT
341 + (int)version
343   return class_get_version(self);
346 + setVersion:(int)aVersion
348   class_set_version(self, aVersion);
349   return self;
352 + (int)streamVersion: (TypedStream*)aStream
354   if (aStream->mode == OBJC_READONLY)
355     return objc_get_stream_class_version (aStream, self);
356   else
357     return class_get_version (self);
360 // These are used to write or read the instance variables 
361 // declared in this particular part of the object.  Subclasses
362 // should extend these, by calling [super read/write: aStream]
363 // before doing their own archiving.  These methods are private, in
364 // the sense that they should only be called from subclasses.
366 - read: (TypedStream*)aStream
368   (void) aStream; /* UNUSED */
369   // [super read: aStream];  
370   return self;
373 - write: (TypedStream*)aStream
375   (void) aStream; /* UNUSED */
376   // [super write: aStream];
377   return self;
380 - awake
382   // [super awake];
383   return self;
386 @end