home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / gcc-2.4.5 / objc / Object.m < prev    next >
Encoding:
Text File  |  1993-05-05  |  7.4 KB  |  359 lines

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