home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gcc-2.7.2.1-base.tgz / gcc-2.7.2.1-base.tar / fsf / gcc / objc / Object.m < prev    next >
Text File  |  1995-06-15  |  8KB  |  390 lines

  1. /* The implementation of class Object for Objective-C.
  2.    Copyright (C) 1993, 1994, 1995 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, 59 Temple Place - Suite 330,
  19. Boston, 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.  
  32. extern void (*_objc_error)(id object, const char *format, va_list);
  33.  
  34. extern 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__
  326. extern 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
  390.