*.c: Use Python's facilities for defining class and static methods.
[mLib-python] / pyke.h
diff --git a/pyke.h b/pyke.h
index b91b48d..66438a4 100644 (file)
--- a/pyke.h
+++ b/pyke.h
@@ -229,12 +229,12 @@ extern PyTypeObject *inittype(PyTypeObject */*skel*/,
 /* Macros for filling in `PyMethodDef' tables, ensuring that functions have
  * the expected signatures.
  */
-#define STD_METHOD(decor, func, doc)                                   \
-  { #func, decor(func), METH_VARARGS, doc },
-#define KEYWORD_METHOD(decor, func, doc)                               \
+#define STD_METHOD(decor, func, flags, doc)                            \
+  { #func, decor(func), METH_VARARGS | flags, doc },
+#define KEYWORD_METHOD(decor, func, flags, doc)                                \
   { #func,                                                             \
     CONVERT_CAREFULLY(PyCFunction, PyCFunctionWithKeywords, decor(func)), \
-    METH_VARARGS | METH_KEYWORDS,                                      \
+    METH_VARARGS | METH_KEYWORDS | flags,                              \
     doc },
 
 /* Convenience wrappers for filling in `PyMethodDef' tables, following
@@ -244,8 +244,12 @@ extern PyTypeObject *inittype(PyTypeObject */*skel*/,
  *
  * around the method table.
  */
-#define METH(func, doc) STD_METHOD(METHNAME, func, doc)
-#define KWMETH(func, doc) KEYWORD_METHOD(METHNAME, func, doc)
+#define METH(func, doc) STD_METHOD(METHNAME, func, 0, doc)
+#define KWMETH(func, doc) KEYWORD_METHOD(METHNAME, func, 0, doc)
+#define CMTH(func, doc) STD_METHOD(METHNAME, func, METH_CLASS, doc)
+#define KWCMTH(func, doc) KEYWORD_METHOD(METHNAME, func, METH_CLASS, doc)
+#define SMTH(func, doc) STD_METHOD(METHNAME, func, METH_STATIC, doc)
+#define KWSMTH(func, doc) KEYWORD_METHOD(METHNAME, func, METH_STATIC, doc)
 
 /* Convenience wrappers for filling in `PyGetSetDef' tables, following Pyke
  * naming convention.  Define `GETSETNAME' locally as
@@ -269,6 +273,20 @@ extern PyTypeObject *inittype(PyTypeObject */*skel*/,
 #define MEMBER(name, ty, f, doc)                                       \
   { #name, ty, offsetof(MEMBERSTRUCT, name), f, doc },
 
+/* Wrappers for filling in pointers in a `PyTypeObject' structure, (a)
+ * following Pyke naming convention, and (b) stripping `const' from the types
+ * without losing type safety.
+ */
+#define UNCONST_TYPE_SLOT(type, suffix, op, ty)                                \
+  CONVERT_CAREFULLY(type *, const type *, op ty##_py##suffix)
+#define PYGETSET(ty) UNCONST_TYPE_SLOT(PyGetSetDef, getset, NOTHING, ty)
+#define PYMETHODS(ty) UNCONST_TYPE_SLOT(PyMethodDef, methods, NOTHING, ty)
+#define PYMEMBERS(ty) UNCONST_TYPE_SLOT(PyMemberDef, members, NOTHING, ty)
+#define PYNUMBER(ty) UNCONST_TYPE_SLOT(PyNumberMethods, number, &, ty)
+#define PYSEQUENCE(ty) UNCONST_TYPE_SLOT(PySequenceMethods, sequence, &, ty)
+#define PYMAPPING(ty) UNCONST_TYPE_SLOT(PyMappingMethods, mapping, &, ty)
+#define PYBUFFER(ty) UNCONST_TYPE_SLOT(PyBufferProcs, buffer, &, ty)
+
 /*----- Populating modules ------------------------------------------------*/
 
 extern PyObject *modname;
@@ -278,7 +296,7 @@ extern PyObject *home_module;
   /* The overall module object. */
 
 extern PyObject *mkexc(PyObject */*mod*/, PyObject */*base*/,
-                      const char */*name*/, PyMethodDef */*methods*/);
+                      const char */*name*/, const PyMethodDef */*methods*/);
   /* Make and return an exception class called NAME, which will end up in
    * module MOD (though it is not added at this time).  The new class is a
    * subclass of BASE.  Attach the METHODS to it.
@@ -345,8 +363,8 @@ extern PyMethodDef *donemethods(void);
 
 /* Mapping methods. */
 #define GMAP_METMNAME(func) gmapmeth_##func
-#define GMAP_METH(func, doc) STD_METHOD(GMAP_METMNAME, func, doc)
-#define GMAP_KWMETH(func, doc) KEYWORD_METHOD(GMAP_METMNAME, func, doc)
+#define GMAP_METH(func, doc) STD_METHOD(GMAP_METMNAME, func, 0, doc)
+#define GMAP_KWMETH(func, doc) KEYWORD_METHOD(GMAP_METMNAME, func, 0, doc)
 #define GMAP_METHDECL(func, doc)                                       \
   extern PyObject *gmapmeth_##func(PyObject *, PyObject *);
 #define GMAP_KWMETHDECL(func, doc)                                     \
@@ -376,8 +394,8 @@ GMAP_DOMETHODS(GMAP_METHDECL, GMAP_KWMETHDECL)
 
 /* Mapping protocol implementation. */
 extern Py_ssize_t gmap_pysize(PyObject *); /* for `mp_length' */
-extern PySequenceMethods gmap_pysequence; /* for `tp_as_sequence' */
-extern PyMethodDef gmap_pymethods[]; /* all the standard methods */
+extern const PySequenceMethods gmap_pysequence; /* for `tp_as_sequence' */
+extern const PyMethodDef gmap_pymethods[]; /* all the standard methods */
 
 /*----- That's all, folks -------------------------------------------------*/