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