home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / Languages / python / PyObjC-0.47-MIHS / pyobjc-0.47-src / Modules / ObjCRuntime.m < prev    next >
Encoding:
Text File  |  1996-11-13  |  5.3 KB  |  229 lines

  1. /* Copyright (c) 1996 by Lele Gaifax.  All Rights Reserved
  2.  *
  3.  * This software may be used and distributed freely for any purpose
  4.  * provided that this notice is included unchanged on any and all
  5.  * copies. The author does not warrant or guarantee this software in
  6.  * any way.
  7.  *
  8.  * This file is part of the PyObjC package.
  9.  *
  10.  * $RCSfile: ObjCRuntime.m,v $
  11.  * $Revision: 1.1.1.1 $
  12.  * $Date: 1996/11/14 01:50:24 $
  13.  *
  14.  * Created Mon Oct 28 12:34:34 1996.
  15.  */
  16.  
  17. #include "ObjC.h"
  18. #include "objc_support.h"
  19.  
  20. static void
  21. ObjCRuntime_dealloc (ObjCRuntime *self)
  22. {
  23.   Py_DECREF (self->classes);
  24.   PyMem_DEL (self);
  25. }
  26.  
  27. extern PyObject *ObjC_load_object_files (PyObject *self, PyObject *args);
  28. extern char ObjC_load_object_files_doc[];
  29.  
  30. extern PyObject *ObjC_list_classes (PyObject *self, PyObject *args);
  31. extern char ObjC_list_classes_doc[];
  32.  
  33. static char ObjCRuntime_sel_is_mapped_doc[] =
  34. FUNDOC("Check whether the given selector is known by the Objective-C runtime.",
  35.        ".sel_is_mapped (SELNAME)",
  36.        "SELNAME\t: name of the selector",
  37.        "True if it is known, False otherwise");
  38. static PyObject *
  39. ObjCRuntime_sel_is_mapped (ObjCRuntime *self, PyObject *args)
  40. {
  41.   char *selname;
  42.  
  43.   if (PyArg_ParseTuple (args, "s;selector name", &selname))
  44.     {
  45.       SEL sel = SELUID(selname);
  46.  
  47.       if (ISSELECTOR (sel))
  48.     {
  49.       Py_INCREF (Py_True);
  50.       return Py_True;
  51.     }
  52.       else
  53.     {
  54.       Py_INCREF (Py_False);
  55.       return Py_False;
  56.     }
  57.     }
  58.  
  59.   return NULL;
  60. }
  61.  
  62. static PyMethodDef ObjCRuntime_methods[] =
  63. {
  64.   { "load_object_files",    (PyCFunction) ObjC_load_object_files,    METH_VARARGS,    ObjC_load_object_files_doc },
  65.   { "list_classes",        (PyCFunction) ObjC_list_classes,    METH_VARARGS,    ObjC_list_classes_doc },
  66.   { "sel_is_mapped",        (PyCFunction) ObjCRuntime_sel_is_mapped,METH_VARARGS,    ObjCRuntime_sel_is_mapped_doc },
  67.   { 0, 0, 0, 0 }
  68. };
  69.  
  70. static int
  71. fill_classes_cache (PyObject *dict)
  72. {
  73.   Class classid;
  74. #ifdef GNU_RUNTIME
  75.  
  76.   void *es = NULL;
  77. #define ENUMERATE_CLASSES(c) (c = objc_next_class (&es))
  78.  
  79. #else
  80.  
  81.   NXHashTable *class_hash = objc_getClasses();
  82.   NXHashState state = NXInitHashState (class_hash);
  83. #define ENUMERATE_CLASSES(c) (NXNextHashState (class_hash, &state, (void**) &c))
  84.  
  85. #endif
  86.   
  87.   while (ENUMERATE_CLASSES(classid))
  88.     {
  89.       PyObject *name = PyString_FromString ((char *) NAMEOF(classid));
  90.  
  91.       if (PyDict_GetItem (dict, name) == NULL)
  92.     {
  93.       ObjCObject *class = ObjCObject_new (classid);
  94.  
  95.       if (class == NULL || PyDict_SetItem (dict, name, (PyObject *) class) == -1)
  96.         {
  97.           Py_DECREF (name);
  98.           Py_DECREF (class);
  99.           return -1;
  100.         }
  101.  
  102.       Py_DECREF(class);
  103.     }
  104.  
  105.       Py_DECREF(name);
  106.     }
  107.  
  108.   return 0;
  109. }
  110.  
  111. static PyObject *
  112. ObjCRuntime_getattro (ObjCRuntime *self, PyObject *name)
  113. {
  114.   PyObject *attr;
  115.  
  116.   attr = PyDict_GetItem (self->classes, name);
  117.   if (!attr)
  118.     {
  119.       char *cname = PyString_AsString (name);
  120.  
  121.       PyErr_Clear();
  122.       if ((attr = Py_FindMethod (ObjCRuntime_methods, (PyObject *) self, cname)))
  123.     return attr;
  124.       else
  125.     {
  126.       PyErr_Clear();
  127.       if (!strcmp (cname, "kind"))
  128. #ifdef GNU_RUNTIME
  129.         return PyString_FromString ("GNU");
  130. #else
  131.         return PyString_FromString ("NeXT");
  132. #endif
  133.       else if (!strcmp (cname, "__dict__"))
  134.         {
  135.           if (fill_classes_cache (self->classes))
  136.         return NULL;
  137.           
  138.           Py_INCREF (self->classes);
  139.           return self->classes;
  140.         }
  141.       else if (!strcmp (cname, "__members__"))
  142.         {
  143.           const char *members[] = { "kind", "__dict__" };
  144.           PyObject *list;
  145.           unsigned int idx;
  146.           
  147.           idx = sizeof (members) / sizeof (members[0]);
  148.           list = PyList_New (idx);
  149.           while (idx--)
  150.         PyList_SetItem (list, idx, PyString_FromString ((char *) members[idx]));
  151.           return list;
  152.         }
  153.       else
  154.         {
  155.           id class = LOOKUPCLASS(cname);
  156.           
  157.           if (class)
  158.         {
  159.           attr =  (PyObject *) ObjCObject_new (class);
  160.           
  161.           PyDict_SetItem (self->classes, name, attr);
  162.         }
  163.           else
  164.         {
  165. #define ERRMSG "Objective-C class `%s' is unknown to the runtime"
  166.           char errmsg[sizeof ERRMSG + PyString_Size (name)];
  167.           
  168.           sprintf (errmsg, ERRMSG, cname);
  169.           PyErr_SetString (ObjC_Error, errmsg);
  170. #undef ERRMSG
  171.         }
  172.         }
  173.     }
  174.     }
  175.   else
  176.     Py_INCREF (attr);
  177.  
  178.   return attr;
  179. }
  180.  
  181. static
  182. PyTypeObject ObjCRuntime_Type =
  183. {
  184.   PyObject_HEAD_INIT(&PyType_Type)
  185.   0,                          /*ob_size*/
  186.   "ObjCRuntime",                  /*tp_name*/
  187.   sizeof(ObjCRuntime),                  /*tp_basicsize*/
  188.   0,                          /*tp_itemsize*/
  189.   
  190.   /* methods */
  191.   (destructor) ObjCRuntime_dealloc,          /*tp_dealloc*/
  192.   (printfunc) 0,                  /*tp_print*/
  193.   (getattrfunc) 0,                  /*tp_getattr*/
  194.   (setattrfunc) 0,                  /*tp_setattr*/
  195.   (cmpfunc) 0,                      /*tp_compare*/
  196.   (reprfunc) 0,                      /*tp_repr*/
  197.   0,                          /*tp_as_number*/
  198.   0,                          /*tp_as_sequence*/
  199.   0,                          /*tp_as_mapping*/
  200.   (hashfunc) 0,                      /*tp_hash*/
  201.   (ternaryfunc) 0,                  /*tp_call*/
  202.   (reprfunc) 0,                      /*tp_str*/
  203.   (getattrofunc) ObjCRuntime_getattro,          /*tp_getattro*/
  204.   (setattrofunc) 0,                  /*tp_setattro*/
  205.  
  206.   /* Space for future expansion */
  207.   0L,0L,
  208.   
  209.   "Wrapper around Objective-C Runtime"          /* Documentation string */
  210. };
  211.  
  212. ObjCRuntime *
  213. ObjCRuntime_new (void)
  214. {
  215.   ObjCRuntime *self = PyObject_NEW (ObjCRuntime, &ObjCRuntime_Type);
  216.  
  217.   if (self == NULL)
  218.     return NULL;
  219.  
  220.   self->classes = PyDict_New();
  221.   return self;
  222. }
  223.  
  224. /*
  225. ** Local Variables:
  226. ** change-log-default-name:"../ChangeLog.PyObjC"
  227. ** End:
  228. */
  229.