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 / objc_support.h < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-23  |  10.5 KB  |  387 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: objc_support.h,v $
  11.  * $Revision: 1.1.1.3 $
  12.  * $Date: 1996/10/23 17:19:46 $
  13.  *
  14.  * Created Tue Sep 10 14:11:38 1996.
  15.  */
  16.  
  17. #ifndef _objc_support_H
  18. #define _objc_support_H
  19.  
  20. #ifndef TEST_PYTHONIFICATION
  21.  
  22. #include "ObjC.h"
  23. #include "OC_PythonObject.h"
  24. #include "OC_PythonString.h"
  25. #include "OC_PythonInt.h"
  26.  
  27. /* These macros hides as much as possible the differences between the
  28.    GNU Runtime and the NeXT one. */
  29.  
  30. #ifdef GNU_RUNTIME
  31.  
  32. // Since we are actually using the GNUstep Base Library...
  33. #ifndef WITH_FOUNDATION
  34. #define WITH_FOUNDATION
  35. #endif
  36.  
  37. /* !!!! The GNU runtime support is completely untested (and does not work, yet!). !!!! */
  38.  
  39. #include <gnustep/base/mframe.h>
  40. #include <gnustep/base/NSException.h>
  41. #include <gnustep/base/NSString.h>
  42.  
  43. #define SELNAME(sel)    sel_get_name(sel)
  44. #define SELUID(str)    sel_get_uid(str)
  45. #define ISSELECTOR(s)    sel_is_mapped(s)
  46. #define NAMEOF(obj)    object_get_class_name(obj)
  47. #define LOOKUPCLASS(n)    objc_lookup_class(n)
  48. #define ISCLASS(o)    ((o) && CLS_ISCLASS(((struct objc_object *) o)->class_pointer))
  49. #define METHOD        Method_t
  50. #define CLASSMETH(c,s)    class_get_class_method(((struct objc_object *) c)->class_pointer, s)
  51. #define INSTMETH(i,s)    class_get_instance_method(((struct objc_object *) i)->class_pointer, s)
  52. #define METHNARGS(m)    method_get_number_of_arguments(m)
  53. #define METHSARGS(m)    method_get_size_of_arguments(m)
  54.  
  55. #else /* NeXT runtime */
  56.  
  57. #ifdef OpENstep            // XXX Is there such a macro under OPENSTEP?
  58.  
  59. #define WITH_FOUNDATION
  60.  
  61. #error OPENSTEP completely unsupported yet.
  62.  
  63. #else /* NS <= 3.3 */
  64.  
  65. #include <objc/objc-runtime.h>
  66. #include <objc/objc-load.h>
  67.  
  68. #define SELNAME(sel)    sel_getName(sel)
  69. #define ISCLASS(o)    (((Class) (o)) && CLS_GETINFO(((Class) (o))->isa, CLS_META))
  70. #define LOOKUPCLASS(n)    objc_lookUpClass(n)
  71. #define METHOD        Method
  72. #define CLASSMETH(c,s)    class_getClassMethod(c->isa, s)
  73. #define INSTMETH(i,s)    class_getInstanceMethod(i->isa, s)
  74. #define METHNARGS(m)    method_getNumberOfArguments(m)
  75. #define METHSARGS(m)    method_getSizeOfArguments(m)
  76.  
  77. #define _C_CONST    'r'
  78. #define _C_IN       'n'
  79. #define _C_INOUT    'N'
  80. #define _C_OUT      'o'
  81. #define _C_BYCOPY   'O'
  82. #define _C_ONEWAY   'V'
  83.  
  84. static inline const char *
  85. objc_skip_type_qualifiers (const char *type)
  86. {
  87.   while (*type == _C_CONST ||
  88.      *type == _C_IN ||
  89.      *type == _C_INOUT ||
  90.      *type == _C_OUT ||
  91.      *type == _C_BYCOPY ||
  92.      *type == _C_ONEWAY)
  93.     type++;
  94.   return type;
  95. }
  96.  
  97. extern int objc_sizeof_type (const char *type);
  98. extern const char *objc_skip_typespec (const char *type);
  99.  
  100. #endif /* OpENstep */
  101.  
  102. #endif /* GNU_RUNTIME */
  103.  
  104. #endif /* TEST_PYTHONIFICATION */
  105.  
  106. #define WITH_SINGLE_UNDERSCORE 0
  107. #define WITH_DOUBLE_UNDERSCORE 1
  108. #define WITH_BOTH 2
  109.  
  110. /* By setting this to 0 or 1 you select a different translation from
  111.    ObjC selector names to Python method names. If it is set to 0, or
  112.    not set at all, you get:
  113.      __privately:setName:forObject::
  114.          -> __privately_setName_forObject__
  115.      thisIs:a:Method:with:some:arguments:
  116.          -> thisIs_a_Method_with_some_arguments_
  117.      andThisIsNot
  118.          -> andThisIsNot
  119.      __this_A_Mixed_Style_Method:withArguments::several:of_them:
  120.          -> __this___A___Mixed___Style___Method_withArguments__several_of___them_
  121.    that is: underscore characters, not at beginning of the name, gets tripled;
  122.    colon characters, denoting an argument in ObjC, are replaced with a single
  123.    underscore.
  124.  
  125.    If set to 1, you get the currently default behaviour:
  126.      __privately:setName:forObject::
  127.          -> __privately__setName__forObject____
  128.      thisIs:a:Method:with:some:arguments:
  129.     -> thisIs__a__Method__with__some__arguments__
  130.      andThisIsNot
  131.     -> andThisIsNot
  132.      __this_A_Mixed_Style_Method:withArguments::several:of_them:
  133.        -> __this_A_Mixed_Style_Method__withArguments____several__of_them__
  134.    where only colon characters are replaced with a double underscore.
  135.  
  136.    If set to 2, the module will check with both methods. See
  137.    PYTHONIFY_FIRST_TRY. This latter mode is obviously SLOWER. */
  138. #define PYTHONIFICATION_METHOD WITH_BOTH
  139.  
  140. #if PYTHONIFICATION_METHOD == WITH_BOTH
  141.  
  142. /* By setting this to 0 or 1 you select the order that will be used to
  143.    do the pythonification of ObjC selector's names: when set to 0 the
  144.    code will try "single underscore" substition first, then "double
  145.    underscore"; when set to 1, the other way around. */
  146. #define PYTHONIFICATION_FIRST_TRY WITH_SINGLE_UNDERSCORE
  147.  
  148. #endif
  149.  
  150. #if PYTHONIFICATION_METHOD == WITH_DOUBLE_UNDERSCORE
  151. #define PYTHONIFIED_LENGTH(selnam,sellen,argc) (sellen+argc+1)
  152. #else
  153. static inline unsigned int
  154. _count_underscores (const char *s)
  155. {
  156.   unsigned int c = 0;
  157.  
  158.   while (*s)
  159.     if (*s++ == '_')
  160.       c++;
  161.   return c;
  162. }
  163.  
  164. #if PYTHONIFICATION_METHOD == WITH_SINGLE_UNDERSCORE
  165.  
  166. #define PYTHONIFIED_LENGTH(selnam,sellen,argc) (sellen+_count_underscores(selnam)*2+1)
  167.  
  168. #else /* WITH_BOTH */
  169.  
  170. #define PYTHONIFIED_LENGTH(selnam,sellen,argc) MAX((sellen+argc+1),\
  171.                            (sellen+_count_underscores(selnam)*2+1))
  172.  
  173. #endif
  174.  
  175. #endif
  176.  
  177. /*#F Converts the Python form 'thisIsObjC__message__with__' to the ObjC
  178.   equivalent 'thisIsObjC:message:with:'. You are responsible on
  179.   the size of @var{to}. */
  180. static inline void
  181. #if PYTHONIFICATION_METHOD == WITH_BOTH
  182. depythonify_objc_message (register const char *from, register char *to, int method)
  183. #else
  184. depythonify_objc_message (register const char *from, register char *to)
  185. #endif
  186. {
  187.   /* Copy initial underscores */
  188.   while (*from == '_')
  189.     *to++ = *from++;
  190.   
  191. #if PYTHONIFICATION_METHOD == WITH_BOTH
  192.   if (method == WITH_DOUBLE_UNDERSCORE)
  193. #endif
  194.  
  195. #if PYTHONIFICATION_METHOD != WITH_SINGLE_UNDERSCORE
  196.   while (*from)
  197.     {
  198.       if (*from == '_' && *(from+1) == '_')
  199.     {
  200.       *to++ = ':';
  201.       from++;
  202.     }
  203.       else
  204.     *to++ = *from;
  205.  
  206.       from++;
  207.     }
  208. #endif
  209.  
  210. #if PYTHONIFICATION_METHOD == WITH_BOTH
  211.   else 
  212. #endif
  213.  
  214. #if PYTHONIFICATION_METHOD != WITH_DOUBLE_UNDERSCORE
  215.   while (*from)
  216.     {
  217.       if (*from == '_' && *(from+1) == '_' && *(from+2) == '_')
  218.     {
  219.       *to++ = '_';
  220.       from += 2;
  221.     }
  222.       else if (*from == '_')
  223.     {
  224.       *to++ = ':';
  225.     }
  226.       else
  227.     *to++ = *from;
  228.  
  229.       from++;
  230.     }
  231. #endif
  232.  
  233.   *to = 0;
  234. }
  235.  
  236. /*#F Converts an ObjC message in the form 'thisIsObjC:message:with:' to
  237.   the Python form 'thisIsObjC__message__with__'. You are responsible on
  238.   the size of @var{to}. */
  239. static inline void
  240. #if PYTHONIFICATION_METHOD == WITH_BOTH
  241. pythonify_objc_message (register const char *from, register char *to, int method)
  242. #else
  243. pythonify_objc_message (register const char *from, register char *to)
  244. #endif
  245. {
  246.   /* Copy initial underscores */
  247.   while (*from == '_')
  248.     *to++ = *from++;
  249.   
  250. #if PYTHONIFICATION_METHOD == WITH_BOTH
  251.   if (method == WITH_DOUBLE_UNDERSCORE)
  252. #endif
  253.  
  254. #if PYTHONIFICATION_METHOD != WITH_SINGLE_UNDERSCORE
  255.   while (*from)
  256.     {
  257.       if (*from == ':')
  258.     {
  259.       *to++ = '_';
  260.       *to++ = '_';
  261.     }
  262.       else
  263.     *to++ = *from;
  264.  
  265.       from++;
  266.     }
  267. #endif
  268.  
  269. #if PYTHONIFICATION_METHOD == WITH_BOTH
  270.   else
  271. #endif
  272.  
  273. #if PYTHONIFICATION_METHOD != WITH_DOUBLE_UNDERSCORE
  274.   while (*from)
  275.     {
  276.       if (*from == '_')
  277.     {
  278.       *to++ = '_';
  279.       *to++ = '_';
  280.       *to++ = '_';
  281.     }
  282.       else if (*from == ':')
  283.     *to++ = '_';
  284.       else
  285.     *to++ = *from;
  286.  
  287.       from++;
  288.     }
  289. #endif
  290.   
  291.   *to = '\0';
  292. }
  293.  
  294. #ifndef TEST_PYTHONIFICATION
  295.  
  296. /*#F Takes a C value pointed by @var{datum} with its type encoded in
  297.   @var{type}, that should be coming from an ObjC @encode directive,
  298.   and returns an equivalent Python object where C structures and
  299.   arrays are represented as tuples. */
  300. extern PyObject *pythonify_c_value (const char *type,
  301.                     void *datum,
  302.                     ObjCMethod *self);
  303.  
  304. /*#F Takes a Python object @var{arg} and translate it into a C value
  305.   pointed by @var{datum} accordingly with the type specification
  306.   encoded in @var{type}, that should be coming from an ObjC @encode
  307.   directive.
  308.   Returns NULL on success, or a static error string describing the
  309.   error. */
  310. extern const char *depythonify_c_value (const char *type,
  311.                     PyObject *arg,
  312.                     void *datum);
  313.  
  314. /*#F Executes the ObjC method wrapped by @var{self}, applying it to
  315.   the arguments in @var{args}, then returns the ``pythonified''
  316.   result. */
  317. extern PyObject *execute_and_pythonify_objc_method (ObjCMethod *self,
  318.                             PyObject *args);
  319.  
  320. #else /* we are testing the pythonification */
  321.  
  322. #if PYTHONIFICATION_METHOD == WITH_BOTH
  323.  
  324. main()
  325. {
  326.   const char *sel1 = "__privately:setName:forObject::";
  327.   const char *sel2 = "thisIs:a:Method:with:some:arguments:";
  328.   const char *sel3 = "andThisIsNot";
  329.   const char *sel4 = "__this_A_Mixed_Style_Method:withArguments::several:of_them:";
  330.   char pythonified_ss[1000], pythonified_ds[1000];
  331.   char depythonified_ss[1000], depythonified_ds[1000];
  332.  
  333. #define P(sel) \
  334.   pythonify_objc_message (sel,pythonified_ss,WITH_SINGLE_UNDERSCORE); \
  335.   pythonify_objc_message (sel,pythonified_ds,WITH_DOUBLE_UNDERSCORE); 
  336. #define T(sel) \
  337.   P(sel)                                           \
  338.   printf ("%s\n\t->%s\n", sel, pythonified_ss);                           \
  339.   depythonify_objc_message (pythonified_ss, depythonified_ss, WITH_SINGLE_UNDERSCORE); \
  340.   depythonify_objc_message (pythonified_ss, depythonified_ds, WITH_DOUBLE_UNDERSCORE); \
  341.   printf ("\t\t->%s\n\t\t->%s\n", depythonified_ss, depythonified_ds);               \
  342.   printf ("\t->%s\n", pythonified_ds);                               \
  343.   depythonify_objc_message (pythonified_ds, depythonified_ss, WITH_SINGLE_UNDERSCORE); \
  344.   depythonify_objc_message (pythonified_ds, depythonified_ds, WITH_DOUBLE_UNDERSCORE); \
  345.   printf ("\t\t->%s\n\t\t->%s\n\t%s\n", depythonified_ss, depythonified_ds,           \
  346.       (!strcmp (sel, depythonified_ss) ||                           \
  347.        !strcmp (sel, depythonified_ds)) ? "Ok" : "WRONG!")
  348.  
  349.   T(sel1);
  350.   T(sel2);
  351.   T(sel3);
  352.   T(sel4);
  353. }
  354.  
  355. #else
  356.  
  357. main()
  358. {
  359.   const char *sel1 = "__privately:setName:forObject::";
  360.   const char *sel2 = "thisIs:a:Method:with:some:arguments:";
  361.   const char *sel3 = "andThisIsNot";
  362.   const char *sel4 = "__this_A_Mixed_Style_Method:withArguments::several:of_them:";
  363.   char pythonified[1000], depythonified[1000];
  364.  
  365. #define P(sel) pythonify_objc_message (sel,pythonified); \
  366.                depythonify_objc_message (pythonified, depythonified);
  367. #define T(sel) P(sel) printf ("%s\n\t-> %s\n\t-> %s\n\t%s\n", sel, pythonified, depythonified, \
  368.                   (strcmp (sel, depythonified) == 0 ? "Ok" : "WRONG!"))
  369.  
  370.   T(sel1);
  371.   T(sel2);
  372.   T(sel3);
  373.   T(sel4);
  374. }
  375.  
  376. #endif
  377.  
  378. #endif /* TEST_PYTHONIFICATION */
  379.  
  380. #endif /* _objc_support_H */
  381.  
  382. /*
  383. ** Local Variables:
  384. ** change-log-default-name:"../ChangeLog.PyObjC"
  385. ** End:
  386. */
  387.