source: trunk/third/gcc/libobjc/Object.m @ 21199

Revision 21199, 8.1 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r21198, which included commits to RCS files with non-trunk default branches.
Line 
1/* The implementation of class Object for Objective-C.
2   Copyright (C) 1993, 1994, 1995, 1997, 2002 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT
12ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING.  If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA.  */
20
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. */
26
27#include <stdarg.h>
28#include "objc/Object.h"
29#include "objc/Protocol.h"
30#include "objc/objc-api.h"
31
32extern int errno;
33
34#define MAX_CLASS_NAME_LEN 256
35
36@implementation Object
37
38+ initialize
39{
40  return self;
41}
42
43- init
44{
45  return self;
46}
47
48+ new
49{
50  return [[self alloc] init];
51}
52
53+ alloc
54{
55  return class_create_instance(self);
56}
57
58- free
59{
60  return object_dispose(self);
61}
62
63- copy
64{
65  return [[self shallowCopy] deepen];
66}
67
68- shallowCopy
69{
70  return object_copy(self);
71}
72
73- deepen
74{
75  return self;
76}
77
78- deepCopy
79{
80  return [self copy];
81}
82
83- (Class)class
84{
85  return object_get_class(self);
86}
87
88- (Class)superClass
89{
90  return object_get_super_class(self);
91}
92
93- (MetaClass)metaClass
94{
95  return object_get_meta_class(self);
96}
97
98- (const char *)name
99{
100  return object_get_class_name(self);
101}
102
103- self
104{
105  return self;
106}
107
108- (unsigned int)hash
109{
110  return (size_t)self;
111}
112
113- (BOOL)isEqual:anObject
114{
115  return self==anObject;
116}
117
118- (int)compare:anotherObject;
119{
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;
128}
129
130- (BOOL)isMetaClass
131{
132  return NO;
133}
134
135- (BOOL)isClass
136{
137  return object_is_class(self);
138}
139
140- (BOOL)isInstance
141{
142  return object_is_instance(self);
143}
144
145- (BOOL)isKindOf:(Class)aClassObject
146{
147  Class class;
148
149  for (class = self->isa; class!=Nil; class = class_get_super_class(class))
150    if (class==aClassObject)
151      return YES;
152  return NO;
153}
154
155- (BOOL)isMemberOf:(Class)aClassObject
156{
157  return self->isa==aClassObject;
158}
159
160- (BOOL)isKindOfClassNamed:(const char *)aClassName
161{
162  Class class;
163
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;
169}
170
171- (BOOL)isMemberOfClassNamed:(const char *)aClassName
172{
173  return ((aClassName!=NULL)
174          &&!strcmp(class_get_class_name(self->isa), aClassName));
175}
176
177+ (BOOL)instancesRespondTo:(SEL)aSel
178{
179  return class_get_instance_method(self, aSel)!=METHOD_NULL;
180}
181
182- (BOOL)respondsTo:(SEL)aSel
183{
184  return ((object_is_instance(self)
185           ?class_get_instance_method(self->isa, aSel)
186           :class_get_class_method(self->isa, aSel))!=METHOD_NULL);
187}
188
189+ (IMP)instanceMethodFor:(SEL)aSel
190{
191  return method_get_imp(class_get_instance_method(self, aSel));
192}
193
194// Indicates if the receiving class or instance conforms to the given protocol
195// not usually overridden by subclasses
196//
197// Modified 9/5/94 to always search the class object's protocol list, rather
198// than the meta class.
199
200+ (BOOL) conformsTo: (Protocol*)aProtocol
201{
202  size_t i;
203  struct objc_protocol_list* proto_list;
204  id parent;
205
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    }
215
216  if ((parent = [self superClass]))
217    return [parent conformsTo: aProtocol];
218  else
219    return NO;
220}
221
222- (BOOL) conformsTo: (Protocol*)aProtocol
223{
224  return [[self class] conformsTo:aProtocol];
225}
226
227- (IMP)methodFor:(SEL)aSel
228{
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)));
232}
233
234+ (struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel
235{
236  return ((struct objc_method_description *)
237           class_get_instance_method(self, aSel));
238}
239
240- (struct objc_method_description *)descriptionForMethod:(SEL)aSel
241{
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)));
246}
247
248- perform:(SEL)aSel
249{
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);
254}
255
256- perform:(SEL)aSel with:anObject
257{
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);
262}
263
264- perform:(SEL)aSel with:anObject1 with:anObject2
265{
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);
270}
271
272- (retval_t)forward:(SEL)aSel :(arglist_t)argFrame
273{
274  (void) argFrame; /* UNUSED */
275  return (retval_t)[self doesNotRecognize: aSel];
276}
277
278- (retval_t)performv:(SEL)aSel :(arglist_t)argFrame
279{
280  return objc_msg_sendv(self, aSel, argFrame);
281}
282
283+ poseAs:(Class)aClassObject
284{
285  return class_pose_as(self, aClassObject);
286}
287
288- (Class)transmuteClassTo:(Class)aClassObject
289{
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;
300}
301
302- subclassResponsibility:(SEL)aSel
303{
304  return [self error:"subclass should override %s", sel_get_name(aSel)];
305}
306
307- notImplemented:(SEL)aSel
308{
309  return [self error:"method %s not implemented", sel_get_name(aSel)];
310}
311
312- shouldNotImplement:(SEL)aSel
313{
314  return [self error:"%s should not implement %s",
315                     object_get_class_name(self), sel_get_name(aSel)];
316}
317
318- doesNotRecognize:(SEL)aSel
319{
320  return [self error:"%s does not recognize %s",
321                     object_get_class_name(self), sel_get_name(aSel)];
322}
323
324- error:(const char *)aString, ...
325{
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;
330
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
339}
340
341+ (int)version
342{
343  return class_get_version(self);
344}
345
346+ setVersion:(int)aVersion
347{
348  class_set_version(self, aVersion);
349  return self;
350}
351
352+ (int)streamVersion: (TypedStream*)aStream
353{
354  if (aStream->mode == OBJC_READONLY)
355    return objc_get_stream_class_version (aStream, self);
356  else
357    return class_get_version (self);
358}
359
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.
365
366- read: (TypedStream*)aStream
367{
368  (void) aStream; /* UNUSED */
369  // [super read: aStream]; 
370  return self;
371}
372
373- write: (TypedStream*)aStream
374{
375  (void) aStream; /* UNUSED */
376  // [super write: aStream];
377  return self;
378}
379
380- awake
381{
382  // [super awake];
383  return self;
384}
385
386@end
Note: See TracBrowser for help on using the repository browser.