gcc50/csu: Skip depends step to avoid possible race
[dragonfly.git] / contrib / gcc-4.4 / libobjc / Object.m
1 /* The implementation of class Object for Objective-C.
2    Copyright (C) 1993, 1994, 1995, 1997, 2002, 2009 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 3, 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 Under Section 7 of GPL version 3, you are granted additional
17 permissions described in the GCC Runtime Library Exception, version
18 3.1, as published by the Free Software Foundation.
19
20 You should have received a copy of the GNU General Public License and
21 a copy of the GCC Runtime Library Exception along with this program;
22 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 <http://www.gnu.org/licenses/>.  */
24
25 #include <stdarg.h>
26 #include <errno.h>
27 #include "objc/Object.h"
28 #include "objc/Protocol.h"
29 #include "objc/objc-api.h"
30
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
115 - (int)compare:(id)anotherObject;
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.
121   else if ((id)self > anotherObject)
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 {
199   size_t i;
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 {
271   (void) argFrame; /* UNUSED */
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
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 {
365   (void) aStream; /* UNUSED */
366   // [super read: aStream];  
367   return self;
368 }
369
370 - write: (TypedStream*)aStream
371 {
372   (void) aStream; /* UNUSED */
373   // [super write: aStream];
374   return self;
375 }
376
377 - awake
378 {
379   // [super awake];
380   return self;
381 }
382
383 @end