*.c: Introduce a new input conversion for binary strings.
[pyke] / pyke.c
diff --git a/pyke.c b/pyke.c
index 883223a..d874763 100644 (file)
--- a/pyke.c
+++ b/pyke.c
@@ -101,6 +101,25 @@ end:
   return (0);
 }
 
+int convbin(PyObject *o, void *pp)
+{
+  struct bin *r = pp;
+
+  if (PyString_Check(o)) {
+    r->p = PyString_AS_STRING(o);
+    r->sz = PyString_GET_SIZE(o);
+    return (1);
+  }
+  if (PyUnicode_Check(o)) {
+    o = _PyUnicode_AsDefaultEncodedString(o, 0);
+    if (!o) return (0);
+    r->p = PyString_AS_STRING(o);
+    r->sz = PyString_GET_SIZE(o);
+    return (1);
+  }
+  return (PyObject_AsReadBuffer(o, &r->p, &r->sz) ? 0 : 1);
+}
+
 /*----- Miscellaneous utilities -------------------------------------------*/
 
 PyObject *abstract_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
@@ -218,7 +237,6 @@ void *newtype(PyTypeObject *metaty,
     (PyHeapTypeObject *)_PyObject_GC_Malloc(_PyObject_VAR_SIZE(metaty, 0));
   if (!skel) skel = &emptytype;
   memcpy(ty, skel, sizeof(*skel));
-  if (ty->ht_type.tp_base) Py_INCREF(ty->ht_type.tp_base);
 #define COPY(blah) do {                                                        \
     if (ty->ht_type.tp_as_##blah) {                                    \
       memcpy(&ty->as_##blah,                                           \
@@ -238,6 +256,7 @@ void *newtype(PyTypeObject *metaty,
     ty->ht_name = PyString_FromString(ty->ht_type.tp_name);
   if (ty->ht_name)
     ty->ht_type.tp_name = PyString_AS_STRING(ty->ht_name);
+  ty->ht_slots = 0;
   (void)PyObject_INIT(&ty->ht_type, metaty);
   Py_INCREF(metaty);
   return (ty);
@@ -249,9 +268,11 @@ void typeready(PyTypeObject *ty)
   PyDict_SetItemString(ty->tp_dict, "__module__", modname);
 }
 
-PyTypeObject *inittype(PyTypeObject *tyskel, PyTypeObject *meta)
+PyTypeObject *inittype(const PyTypeObject *tyskel,
+                      PyTypeObject *base, PyTypeObject *meta)
 {
   PyTypeObject *ty = newtype(meta, tyskel, 0);
+  if (base) { ty->tp_base = base; Py_INCREF(base); }
   ty->tp_flags |= Py_TPFLAGS_HEAPTYPE;
   typeready(ty);
   return (ty);
@@ -260,7 +281,7 @@ PyTypeObject *inittype(PyTypeObject *tyskel, PyTypeObject *meta)
 /*----- Populating modules ------------------------------------------------*/
 
 PyObject *mkexc(PyObject *mod, PyObject *base,
-               const char *name, PyMethodDef *mm)
+               const char *name, const PyMethodDef *mm)
 {
   PyObject *nameobj = 0;
   PyObject *dict = 0;
@@ -272,7 +293,8 @@ PyObject *mkexc(PyObject *mod, PyObject *base,
 
   if (mm) {
     while (mm->ml_name) {
-      if ((func = PyCFunction_NewEx(mm, 0, mod)) == 0 ||
+      if ((func = PyCFunction_NewEx((/*unconst*/ PyMethodDef *)mm,
+                                   0, mod)) == 0 ||
          (meth = PyMethod_New(func, 0, exc)) == 0 ||
          PyDict_SetItemString(dict, mm->ml_name, meth))
        goto fail;