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