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),
50 for (i = 0; consts[i].name; i++) {
51 if (consts[i].value > LONG_MAX)
52 x = PyLong_FromUnsignedLong(consts[i].value);
54 x = PyInt_FromLong(consts[i].value);
55 PyModule_AddObject(mod, (/*unconst*/ char *)consts[i].name, x);
59 PyObject *getu32(uint32 w)
62 return (PyInt_FromLong(w));
64 return (PyLong_FromUnsignedLong(w));
67 PyObject *getbool(int b)
73 PyObject *abstract_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
75 PyErr_SetString(PyExc_TypeError, "can't instantiate this class");
79 int convulong(PyObject *o, void *pp)
82 unsigned long *p = pp;
87 if (i < 0) TYERR("must be nonnegative");
90 if ((t = PyNumber_Long(o)) == 0) goto end;
91 *p = PyLong_AsUnsignedLong(t);
93 if (PyErr_Occurred()) goto end;
100 int convu32(PyObject *o, void *pp)
105 if (!convulong(o, &u)) goto end;
106 if (u > 0xffffffff) TYERR("out of range");
113 int convuint(PyObject *o, void *pp)
118 if (!convulong(o, &u)) goto end;
119 if (u > UINT_MAX) TYERR("out of range");
126 int convmpw(PyObject *o, void *pp)
131 if (!convulong(o, &u)) goto end;
132 if (u > MPW_MAX) TYERR("out of range");
139 int convszt(PyObject *o, void *pp)
144 if (!convulong(o, &u)) goto end;
145 if (u > ~(size_t)0) TYERR("out of range");
152 int convbool(PyObject *o, void *pp)
154 *(int *)pp = PyObject_IsTrue(o);
158 PyObject *mexp_common(PyObject *me, PyObject *arg,
160 PyObject *(*id)(PyObject *),
161 int (*fill)(void *, PyObject *,
162 PyObject *, PyObject *),
163 PyObject *(*exp)(PyObject *, void *, int),
164 void (*drop)(void *))
166 int i = 0, j, n, flat;
167 PyObject *qq, *x, *y, *z = 0;
170 if (PyTuple_Size(arg) == 1)
171 arg = PyTuple_GetItem(arg, 0);
173 if (!PySequence_Check(arg)) TYERR("not a sequence");
174 n = PySequence_Size(arg); if (!n) { z = id(me); goto end; }
175 x = PySequence_GetItem(arg, 0);
176 if (PySequence_Check(x))
179 if (n % 2) VALERR("must have even number of arguments");
185 v = xmalloc(n * efsz);
186 for (i = j = 0, vv = v; i < n; i++, vv += efsz) {
188 x = PySequence_GetItem(arg, j++);
189 y = PySequence_GetItem(arg, j++);
191 qq = PySequence_GetItem(arg, j++);
193 if (!PySequence_Check(qq) || PySequence_Size(qq) != 2) {
195 TYERR("want a sequence of pairs");
197 x = PySequence_GetItem(qq, 0);
198 y = PySequence_GetItem(qq, 1);
201 if (!x || !y) goto end;
202 if (fill(vv, me, x, y)) {
205 if (!PyErr_Occurred())
206 PyErr_SetString(PyExc_TypeError, "type mismatch");
216 for (j = 0, vv = v; j < i; j++, vv += efsz)
224 DA_DECL(method_v, PyMethodDef);
225 static method_v global_pymethods = DA_INIT;
226 void addmethods(const PyMethodDef *m)
230 for (n = 0; m[n].ml_name; n++);
231 DA_ENSURE(&global_pymethods, n);
232 memcpy(DA(&global_pymethods) + DA_LEN(&global_pymethods),
234 DA_EXTEND(&global_pymethods, n);
237 static const PyTypeObject emptytype = { 0 };
239 void *newtype(PyTypeObject *metaty,
240 const PyTypeObject *skel,
243 PyHeapTypeObject *ty =
244 (PyHeapTypeObject *)_PyObject_GC_Malloc(_PyObject_VAR_SIZE(metaty, 0));
245 if (!skel) skel = &emptytype;
246 memcpy(ty, skel, sizeof(*skel));
247 if (ty->type.tp_base) Py_INCREF(ty->type.tp_base);
248 #define COPY(blah) do { \
249 if (ty->type.tp_as_##blah) { \
250 memcpy(&ty->as_##blah, \
251 ty->type.tp_as_##blah, \
252 sizeof(ty->as_##blah)); \
253 ty->type.tp_as_##blah = &ty->as_##blah; \
262 ty->name = PyString_FromString(name);
263 else if (ty->type.tp_name)
264 ty->name = PyString_FromString(ty->type.tp_name);
266 ty->type.tp_name = PyString_AS_STRING(ty->name);
267 PyObject_INIT(&ty->type, metaty);
272 static PyObject *smallprimes(void)
274 PyObject *v = PyList_New(NPRIME);
277 for (i = 0; i < NPRIME; i++)
278 PyList_SetItem(v, i, PyInt_FromLong(primetab[i]));
282 PyTypeObject *inittype(PyTypeObject *tyskel)
284 PyTypeObject *ty = newtype(&PyType_Type, tyskel, 0);
285 ty->tp_flags |= Py_TPFLAGS_HEAPTYPE;
290 void init_base(void) {
291 static const PyMethodDef mzero = { 0 };
294 DA_PUSH(&global_pymethods, mzero);
295 mod = Py_InitModule("catacomb._base", DA(&global_pymethods));
297 INSERT("smallprimes", smallprimes());
301 /*----- That's all, folks -------------------------------------------------*/