7 * (c) 2004 Straylight/Edgeware
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of the Python interface to Catacomb.
14 * Catacomb/Python is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * Catacomb/Python is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with Catacomb/Python; if not, write to the Free Software Foundation,
26 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 /*----- Header files ------------------------------------------------------*/
31 #include "catacomb-python.h"
33 /*----- Main code ---------------------------------------------------------*/
35 static void setconstants(PyObject *mod)
37 static const struct { const char *name; unsigned long value; } consts[] = {
38 #define C(x) { #x, x }
39 C(FTY_PRIME), C(FTY_BINARY),
40 C(PGEN_PASS), C(PGEN_FAIL), C(PGEN_BEGIN), C(PGEN_TRY), C(PGEN_DONE),
43 C(PMODE_READ), C(PMODE_VERIFY),
44 C(KOPEN_READ), C(KOPEN_WRITE), C(KOPEN_NOFILE),
45 C(KEXP_FOREVER), C(KEXP_EXPIRE),
46 C(KF_ENCMASK), C(KENC_BINARY), C(KENC_MP), C(KENC_STRUCT),
47 C(KENC_ENCRYPT), C(KENC_STRING), C(KENC_EC),
48 C(KF_CATMASK), C(KCAT_SYMM), C(KCAT_PRIV), C(KCAT_PUB), C(KCAT_SHARE),
50 C(KF_BURN), C(KF_OPT),
51 #define ENTRY(tag, val, str) C(KERR_##tag),
60 for (i = 0; consts[i].name; i++) {
61 if (consts[i].value > LONG_MAX)
62 x = PyLong_FromUnsignedLong(consts[i].value);
64 x = PyInt_FromLong(consts[i].value);
65 PyModule_AddObject(mod, (/*unconst*/ char *)consts[i].name, x);
70 PyObject *getu##n(uint##n w) \
73 return (PyInt_FromLong(w)); \
75 return (PyLong_FromUnsignedLong(w)); \
79 PyObject *getbool(int b)
85 PyObject *abstract_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
87 PyErr_SetString(PyExc_TypeError, "can't instantiate this class");
91 int convulong(PyObject *o, void *pp)
94 unsigned long *p = pp;
99 if (i < 0) TYERR("must be nonnegative");
102 if ((t = PyNumber_Long(o)) == 0) goto end;
103 *p = PyLong_AsUnsignedLong(t);
105 if (PyErr_Occurred()) goto end;
113 int convu##n(PyObject *o, void *pp) \
118 if (!convulong(o, &u)) goto end; \
119 if (u > MASK##n) TYERR("out of range"); \
127 int convuint(PyObject *o, void *pp)
132 if (!convulong(o, &u)) goto end;
133 if (u > UINT_MAX) TYERR("out of range");
140 int convmpw(PyObject *o, void *pp)
145 if (!convulong(o, &u)) goto end;
146 if (u > MPW_MAX) TYERR("out of range");
153 int convszt(PyObject *o, void *pp)
158 if (!convulong(o, &u)) goto end;
159 if (u > ~(size_t)0) TYERR("out of range");
166 int convbool(PyObject *o, void *pp)
168 *(int *)pp = PyObject_IsTrue(o);
172 PyObject *mexp_common(PyObject *me, PyObject *arg,
174 PyObject *(*id)(PyObject *),
175 int (*fill)(void *, PyObject *,
176 PyObject *, PyObject *),
177 PyObject *(*exp)(PyObject *, void *, int),
178 void (*drop)(void *))
180 int i = 0, j, n, flat;
181 PyObject *qq, *x, *y, *z = 0;
184 if (PyTuple_Size(arg) == 1)
185 arg = PyTuple_GetItem(arg, 0);
187 if (!PySequence_Check(arg)) TYERR("not a sequence");
188 n = PySequence_Size(arg); if (!n) { z = id(me); goto end; }
189 x = PySequence_GetItem(arg, 0);
190 if (PySequence_Check(x))
193 if (n % 2) VALERR("must have even number of arguments");
199 v = xmalloc(n * efsz);
200 for (i = j = 0, vv = v; i < n; i++, vv += efsz) {
202 x = PySequence_GetItem(arg, j++);
203 y = PySequence_GetItem(arg, j++);
205 qq = PySequence_GetItem(arg, j++);
207 if (!PySequence_Check(qq) || PySequence_Size(qq) != 2) {
209 TYERR("want a sequence of pairs");
211 x = PySequence_GetItem(qq, 0);
212 y = PySequence_GetItem(qq, 1);
215 if (!x || !y) goto end;
216 if (fill(vv, me, x, y)) {
219 if (!PyErr_Occurred())
220 PyErr_SetString(PyExc_TypeError, "type mismatch");
230 for (j = 0, vv = v; j < i; j++, vv += efsz)
238 PyObject * mkexc(PyObject *mod, PyObject *base,
239 const char *name, PyMethodDef *mm)
241 PyObject *nameobj = 0;
247 if ((nameobj = PyString_FromFormat("%s.%s",
248 PyModule_GetName(mod),
250 (dict = PyDict_New()) == 0 ||
251 (exc = PyErr_NewException(PyString_AS_STRING(nameobj),
256 while (mm->ml_name) {
257 if ((func = PyCFunction_NewEx(mm, 0, mod)) == 0 ||
258 (meth = PyMethod_New(func, 0, exc)) == 0 ||
259 PyDict_SetItemString(dict, mm->ml_name, meth))
261 Py_DECREF(func); func = 0;
262 Py_DECREF(meth); meth = 0;
280 DA_DECL(method_v, PyMethodDef);
281 static method_v global_pymethods = DA_INIT;
282 void addmethods(const PyMethodDef *m)
286 for (n = 0; m[n].ml_name; n++);
287 DA_ENSURE(&global_pymethods, n);
288 memcpy(DA(&global_pymethods) + DA_LEN(&global_pymethods),
290 DA_EXTEND(&global_pymethods, n);
293 static const PyTypeObject emptytype = { 0 };
295 void *newtype(PyTypeObject *metaty,
296 const PyTypeObject *skel,
299 PyHeapTypeObject *ty =
300 (PyHeapTypeObject *)_PyObject_GC_Malloc(_PyObject_VAR_SIZE(metaty, 0));
301 if (!skel) skel = &emptytype;
302 memcpy(ty, skel, sizeof(*skel));
303 if (ty->type.tp_base) Py_INCREF(ty->type.tp_base);
304 #define COPY(blah) do { \
305 if (ty->type.tp_as_##blah) { \
306 memcpy(&ty->as_##blah, \
307 ty->type.tp_as_##blah, \
308 sizeof(ty->as_##blah)); \
309 ty->type.tp_as_##blah = &ty->as_##blah; \
318 ty->name = PyString_FromString(name);
319 else if (ty->type.tp_name)
320 ty->name = PyString_FromString(ty->type.tp_name);
322 ty->type.tp_name = PyString_AS_STRING(ty->name);
323 PyObject_INIT(&ty->type, metaty);
328 static PyObject *smallprimes(void)
330 PyObject *v = PyList_New(NPRIME);
333 for (i = 0; i < NPRIME; i++)
334 PyList_SetItem(v, i, PyInt_FromLong(primetab[i]));
338 PyTypeObject *inittype(PyTypeObject *tyskel)
340 PyTypeObject *ty = newtype(&PyType_Type, tyskel, 0);
341 ty->tp_flags |= Py_TPFLAGS_HEAPTYPE;
346 static PyObject *meth__ego(PyObject *me, PyObject *arg)
349 if (!PyArg_ParseTuple(arg, "s:_ego", &argv0))
351 if (strcmp(QUIS, "<UNNAMED>") == 0)
356 static PyMethodDef methods[] = {
357 #define METHNAME(func) meth_##func
358 METH (_ego, "_ego(ARGV0)")
363 void init_base(void) {
364 static const PyMethodDef mzero = { 0 };
368 DA_PUSH(&global_pymethods, mzero);
369 mod = Py_InitModule("catacomb._base", DA(&global_pymethods));
371 INSERT("smallprimes", smallprimes());
375 /*----- That's all, folks -------------------------------------------------*/