source: trunk/third/gcc/objc/Object.m @ 8834

Revision 8834, 8.1 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r8833, 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 Free Software Foundation, Inc.
3
4This file is part of GNU CC.
5
6GNU CC 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
11GNU CC is distributed in the hope that it will be useful, but WITHOUT
12ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13or FITNESS 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 GNU CC; 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 void (*_objc_error)(id object, const char *format, va_list);
33
34extern int errno;
35
36#define MAX_CLASS_NAME_LEN 256
37
38@implementation Object
39
40+ initialize
41{
42  return self;
43}
44
45- init
46{
47  return self;
48}
49
50+ new
51{
52  return [[self alloc] init];
53}
54
55+ alloc
56{
57  return class_create_instance(self);
58}
59
60- free
61{
62  return object_dispose(self);
63}
64
65- copy
66{
67  return [[self shallowCopy] deepen];
68}
69
70- shallowCopy
71{
72  return object_copy(self);
73}
74
75- deepen
76{
77  return self;
78}
79
80- deepCopy
81{
82  return [self copy];
83}
84
85- (Class)class
86{
87  return object_get_class(self);
88}
89
90- (Class)superClass
91{
92  return object_get_super_class(self);
93}
94
95- (MetaClass)metaClass
96{
97  return object_get_meta_class(self);
98}
99
100- (const char *)name
101{
102  return object_get_class_name(self);
103}
104
105- self
106{
107  return self;
108}
109
110- (unsigned int)hash
111{
112  return (size_t)self;
113}
114
115- (BOOL)isEqual:anObject
116{
117  return self==anObject;
118}
119
120- (int)compare:anotherObject;
121{
122  if ([self isEqual:anotherObject])
123    return 0;
124  // Ordering objects by their address is pretty useless,
125  // so subclasses should override this is some useful way.
126  else if (self > anotherObject)
127    return 1;
128  else
129    return -1;
130}
131
132- (BOOL)isMetaClass
133{
134  return NO;
135}
136
137- (BOOL)isClass
138{
139  return object_is_class(self);
140}
141
142- (BOOL)isInstance
143{
144  return object_is_instance(self);
145}
146
147- (BOOL)isKindOf:(Class)aClassObject
148{
149  Class class;
150
151  for (class = self->isa; class!=Nil; class = class_get_super_class(class))
152    if (class==aClassObject)
153      return YES;
154  return NO;
155}
156
157- (BOOL)isMemberOf:(Class)aClassObject
158{
159  return self->isa==aClassObject;
160}
161
162- (BOOL)isKindOfClassNamed:(const char *)aClassName
163{
164  Class class;
165
166  if (aClassName!=NULL)
167    for (class = self->isa; class!=Nil; class = class_get_super_class(class))
168      if (!strcmp(class_get_class_name(class), aClassName))
169        return YES;
170  return NO;
171}
172
173- (BOOL)isMemberOfClassNamed:(const char *)aClassName
174{
175  return ((aClassName!=NULL)
176          &&!strcmp(class_get_class_name(self->isa), aClassName));
177}
178
179+ (BOOL)instancesRespondTo:(SEL)aSel
180{
181  return class_get_instance_method(self, aSel)!=METHOD_NULL;
182}
183
184- (BOOL)respondsTo:(SEL)aSel
185{
186  return ((object_is_instance(self)
187           ?class_get_instance_method(self->isa, aSel)
188           :class_get_class_method(self->isa, aSel))!=METHOD_NULL);
189}
190
191+ (IMP)instanceMethodFor:(SEL)aSel
192{
193  return method_get_imp(class_get_instance_method(self, aSel));
194}
195
196// Indicates if the receiving class or instance conforms to the given protocol
197// not usually overridden by subclasses
198//
199// Modified 9/5/94 to always search the class object's protocol list, rather
200// than the meta class.
201
202+ (BOOL) conformsTo: (Protocol*)aProtocol
203{
204  int i;
205  struct objc_protocol_list* proto_list;
206  id parent;
207
208  for (proto_list = ((Class)self)->protocols;
209       proto_list; proto_list = proto_list->next)
210    {
211      for (i=0; i < proto_list->count; i++)
212      {
213        if ([proto_list->list[i] conformsTo: aProtocol])
214          return YES;
215      }
216    }
217
218  if (parent = [self superClass])
219    return [parent conformsTo: aProtocol];
220  else
221    return NO;
222}
223
224- (BOOL) conformsTo: (Protocol*)aProtocol
225{
226  return [[self class] conformsTo:aProtocol];
227}
228
229- (IMP)methodFor:(SEL)aSel
230{
231  return (method_get_imp(object_is_instance(self)
232                         ?class_get_instance_method(self->isa, aSel)
233                         :class_get_class_method(self->isa, aSel)));
234}
235
236+ (struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel
237{
238  return ((struct objc_method_description *)
239           class_get_instance_method(self, aSel));
240}
241
242- (struct objc_method_description *)descriptionForMethod:(SEL)aSel
243{
244  return ((struct objc_method_description *)
245           (object_is_instance(self)
246            ?class_get_instance_method(self->isa, aSel)
247            :class_get_class_method(self->isa, aSel)));
248}
249
250- perform:(SEL)aSel
251{
252  IMP msg = objc_msg_lookup(self, aSel);
253  if (!msg)
254    return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
255  return (*msg)(self, aSel);
256}
257
258- perform:(SEL)aSel with:anObject
259{
260  IMP msg = objc_msg_lookup(self, aSel);
261  if (!msg)
262    return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
263  return (*msg)(self, aSel, anObject);
264}
265
266- perform:(SEL)aSel with:anObject1 with:anObject2
267{
268  IMP msg = objc_msg_lookup(self, aSel);
269  if (!msg)
270    return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
271  return (*msg)(self, aSel, anObject1, anObject2);
272}
273
274- (retval_t)forward:(SEL)aSel :(arglist_t)argFrame
275{
276  return (retval_t)[self doesNotRecognize: aSel];
277}
278
279- (retval_t)performv:(SEL)aSel :(arglist_t)argFrame
280{
281  return objc_msg_sendv(self, aSel, argFrame);
282}
283
284+ poseAs:(Class)aClassObject
285{
286  return class_pose_as(self, aClassObject);
287}
288
289- (Class)transmuteClassTo:(Class)aClassObject
290{
291  if (object_is_instance(self))
292    if (class_is_class(aClassObject))
293      if (class_get_instance_size(aClassObject)==class_get_instance_size(isa))
294        if ([self isKindOf:aClassObject])
295          {
296            Class old_isa = isa;
297            isa = aClassObject;
298            return old_isa;
299          }
300  return nil;
301}
302
303- subclassResponsibility:(SEL)aSel
304{
305  return [self error:"subclass should override %s", sel_get_name(aSel)];
306}
307
308- notImplemented:(SEL)aSel
309{
310  return [self error:"method %s not implemented", sel_get_name(aSel)];
311}
312
313- shouldNotImplement:(SEL)aSel
314{
315  return [self error:"%s should not implement %s",
316                     object_get_class_name(self), sel_get_name(aSel)];
317}
318
319- doesNotRecognize:(SEL)aSel
320{
321  return [self error:"%s does not recognize %s",
322                     object_get_class_name(self), sel_get_name(aSel)];
323}
324
325#ifdef __alpha__
326extern size_t strlen(const char*);
327#endif
328
329- error:(const char *)aString, ...
330{
331#define FMT "error: %s (%s)\n%s\n"
332  char fmt[(strlen((char*)FMT)+strlen((char*)object_get_class_name(self))
333            +((aString!=NULL)?strlen((char*)aString):0)+8)];
334  va_list ap;
335
336  sprintf(fmt, FMT, object_get_class_name(self),
337                    object_is_instance(self)?"instance":"class",
338                    (aString!=NULL)?aString:"");
339  va_start(ap, aString);
340  (*_objc_error)(self, fmt, ap);
341  va_end(ap);
342  return nil;
343#undef FMT
344}
345
346+ (int)version
347{
348  return class_get_version(self);
349}
350
351+ setVersion:(int)aVersion
352{
353  class_set_version(self, aVersion);
354  return self;
355}
356
357+ (int)streamVersion: (TypedStream*)aStream
358{
359  if (aStream->mode == OBJC_READONLY)
360    return objc_get_stream_class_version (aStream, self);
361  else
362    return class_get_version (self);
363}
364
365// These are used to write or read the instance variables
366// declared in this particular part of the object.  Subclasses
367// should extend these, by calling [super read/write: aStream]
368// before doing their own archiving.  These methods are private, in
369// the sense that they should only be called from subclasses.
370
371- read: (TypedStream*)aStream
372{
373  // [super read: aStream]; 
374  return self;
375}
376
377- write: (TypedStream*)aStream
378{
379  // [super write: aStream];
380  return self;
381}
382
383- awake
384{
385  // [super awake];
386  return self;
387}
388
389@end
Note: See TracBrowser for help on using the repository browser.