-include atom.pyx crc32.pyx report.pyx select.pyx sym.pyx unihash.pyx
-include codec.pyx.in grim.h atom.h atom-base.c array.c Makefile
+include mLib.pyx defs.pxi utils.pyx
+include codec.pyx.in grim.h atom.h array.h atom-base.c array.c Makefile
+include lbuf.pyx pkbuf.pyx mapping.pyx
+include atom.pyx crc32.pyx report.pyx sym.pyx assoc.pyx unihash.pyx
+include sel-base.pyx sel-file.pyx sel-timer.pyx conn.pyx
+include bres.pyx selbuf.pyx selpk.pyx sig.pyx ident.pyx
include debian/rules debian/control debian/changelog debian/copyright
PYTHON = python
prefix = /usr/local
-AUTOC = \
- select.c crc32.c atom.c report.c sym.c unihash.c \
- base64.c base32.c hex.c
-
GEN = base64.pyx base32.pyx hex.pyx
all: setup.py
clean: setup.py
$(PYTHON) setup.py clean
rm -rf build
- rm -f $(AUTOC) $(GEN) MANIFEST
+ rm -f mLib.c $(GEN) MANIFEST
dist: setup.py
$(PYTHON) setup.py sdist
#include <mLib/dstr.h>
#include <mLib/exc.h>
+#include "array.h"
#include "grim.h"
/*----- Data structures ---------------------------------------------------*/
#define DAITER_V(obj) DA_V(DAITER_DA(obj))
#define DAITER_I(obj) (((daiter_pyobj *)(obj))->i)
-static PyTypeObject da_pytype, daiter_pytype;
-
static int getseq(PyObject **pseq, PyObject ***v, size_t *n)
{
PyObject *seq = *pseq;
static void daiter_pydealloc(PyObject *me)
{ Py_DECREF(DAITER_DA(me)); PyObject_DEL(me); }
-static PyTypeObject daiter_pytype = {
+PyTypeObject daiter_pytype = {
PyObject_HEAD_INIT(0) 0, /* Header */
"array.ArrayIter", /* @tp_name@ */
sizeof(daiter_pyobj), /* @tp_basicsize@ */
da_pyput /* @mp_ass_subscript@ */
};
-static PyTypeObject da_pytype = {
+PyTypeObject da_pytype = {
PyObject_HEAD_INIT(0) 0, /* Header */
"array.Array", /* @tp_name@ */
sizeof(da_pyobj), /* @tp_basicsize@ */
/*----- Initialization ----------------------------------------------------*/
-static PyMethodDef emptymethods[] = { { 0 } };
-
-void initarray(void)
-{
- PyObject *mod = Py_InitModule("array", emptymethods);
- PyType_Ready(&da_pytype); PyType_Ready(&daiter_pytype);
- PyModule_AddObject(mod, "Array", (PyObject *)&da_pytype);
- PyModule_AddObject(mod, "ArrayIter", (PyObject *)&daiter_pytype);
-}
+void da_pysetup(void)
+ { PyType_Ready(&da_pytype); PyType_Ready(&daiter_pytype); }
/*----- That's all, folks -------------------------------------------------*/
--- /dev/null
+/* -*-c-*-
+ *
+ * $Id$
+ *
+ * Double-ended arrays
+ *
+ * (c) 2005 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------*
+ *
+ * This file is part of the Python interface to mLib.
+ *
+ * mLib/Python is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mLib/Python is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with mLib/Python; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef ARRAY_H
+#define ARRAY_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include <Python.h>
+
+extern void daysetup(void);
+extern PyTypeObject da_pytype, daiter_pytype;
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif
--- /dev/null
+# -*-pyrex-*-
+#
+# $Id$
+#
+# Association tables
+#
+# (c) 2005 Straylight/Edgeware
+#
+
+#----- Licensing notice -----------------------------------------------------
+#
+# This file is part of the Python interface to mLib.
+#
+# mLib/Python is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# mLib/Python is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with mLib/Python; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+cdef struct _assoc_entry:
+ sym_base _b
+ PyObject *v
+
+cdef class AssocTable (Mapping):
+ cdef assoc_table _t
+ cdef int _init(me) except -1:
+ assoc_create(&me._t)
+ return 0
+ cdef void *_find(me, object key, unsigned *f) except NULL:
+ cdef void *p
+ cdef int n
+ cdef _assoc_entry *e
+ cdef atom *a
+ a = ATOM_A(atom_pyintern(key))
+ PyObject_AsReadBuffer(key, &p, &n)
+ if f:
+ f[0] = 0
+ e = <_assoc_entry *>assoc_find(&me._t, a, PSIZEOF(e), f)
+ if not f[0]:
+ e.v = NULL
+ else:
+ e = <_assoc_entry *>assoc_find(&me._t, a, 0, NULL)
+ return <void *>e
+ cdef object _key(me, void *e):
+ return atom_pywrap(ASSOC_ATOM(e))
+ cdef object _value(me, void *e):
+ cdef _assoc_entry *ee
+ ee = <_assoc_entry *>e
+ Py_INCREF(ee.v)
+ return <object>ee.v
+ cdef void _setval(me, void *e, object val):
+ cdef _assoc_entry *ee
+ ee = <_assoc_entry *>e
+ if ee.v:
+ Py_DECREF(ee.v)
+ ee.v = <PyObject *>v
+ Py_INCREF(ee.v)
+ cdef void _del(me, void *e):
+ cdef _assoc_entry *ee
+ ee = <_assoc_entry *>e
+ if ee.v:
+ Py_DECREF(ee.v)
+ assoc_remove(&me._t, <void *>ee)
+ cdef _MapIterator _iter(me):
+ return _AssocIter(me)
+
+cdef class _AssocIter (_MapIterator):
+ cdef AssocTable t
+ cdef assoc_iter i
+ def __new__(me, AssocTable t):
+ me.t = t
+ assoc_mkiter(&me.i, &me.t._t)
+ cdef void *_next(me):
+ return assoc_next(&me.i)
+
+#----- That's all, folks ----------------------------------------------------
/*----- Data structures ---------------------------------------------------*/
-static PyTypeObject atom_pytype;
-
typedef struct entry {
assoc_base _b;
PyObject *a;
static long atom_pyhash(PyObject *me)
{ long h = ATOM_HASH(ATOM_A(me)); if (h == -1) h = -2; return (h); }
-static PyTypeObject atom_pytype = {
+PyTypeObject atom_pytype = {
PyObject_HEAD_INIT(0) 0, /* Header */
"atom.Atom", /* @tp_name@ */
sizeof(atom_pyobj), /* @tp_basicsize@ */
0 /* @tp_is_gc@ */
};
-PyObject *atom_pystartup(void)
-{
- assoc_create(&obarray);
- PyType_Ready(&atom_pytype);
- return ((PyObject *)&atom_pytype);
-}
+void atom_pysetup(void)
+ { assoc_create(&obarray); PyType_Ready(&atom_pytype); }
/*----- That's all, folks -------------------------------------------------*/
#define ATOM_PYCHECK(obj) PyObject_TypeCheck(obj, &atom_pytype)
#define ATOM_A(obj) (((atom_pyobj *)(obj))->a)
+extern PyTypeObject atom_pytype;
+
/*----- Functions provided ------------------------------------------------*/
extern PyObject *atom_pywrap(atom *);
extern PyObject *atom_pyintern(PyObject *);
-extern PyObject *atom_pystartup(void);
+extern void atom_pysetup(void);
/*----- That's all, folks -------------------------------------------------*/
# along with mLib/Python; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-cdef extern from 'atom.h':
- ctypedef struct atom:
- pass
- ctypedef struct atom_iter:
- pass
- ctypedef struct atom_table:
- pass
- atom_table *ATOM_GLOBAL
- void atom_mkiter(atom_iter *i, atom_table *t)
- atom *atom_next(atom_iter *)
- atom_pystartup()
- atom_pywrap(atom *a)
- atom_pyintern(obj)
- atom *ATOM_A(obj)
-
-cdef extern from 'mLib/assoc.h':
- ctypedef struct assoc_table:
- pass
- ctypedef struct assoc_base:
- pass
- ctypedef struct assoc_iter:
- pass
- void assoc_create(assoc_table *t)
- void assoc_destroy(assoc_table *t)
- void *assoc_find(assoc_table *t, atom *a, int sz, unsigned *f)
- void assoc_remove(assoc_table *t, void *b)
- atom *ASSOC_ATOM(void *b)
- void assoc_mkiter(assoc_iter *i, assoc_table *t)
- void *assoc_next(assoc_iter *i)
-
-cdef extern from 'grim.h':
- int PSIZEOF(void *p)
-
-cdef extern from 'Python.h':
- int PyObject_AsReadBuffer(obj, void **buf, int *len) except -1
- PyString_FromStringAndSize(char *p, int n)
- ctypedef struct PyObject:
- pass
- void Py_INCREF(PyObject *obj)
- void Py_DECREF(PyObject *obj)
-
cdef class AtomIter:
cdef atom_iter _i
def __new__(me):
def atoms():
return AtomIter()
-cdef struct entry:
- assoc_base _b
- PyObject *v
-
-cdef entry *_find(assoc_table *t, object key, unsigned *f) except ?NULL:
- cdef void *p
- cdef int n
- cdef entry *e
- cdef atom *a
- a = ATOM_A(atom_pyintern(key))
- if f:
- f[0] = 0
- e = <entry *>assoc_find(t, a, PSIZEOF(e), f)
- if not f[0]:
- e.v = NULL
- else:
- e = <entry *>assoc_find(t, a, 0, NULL)
- return e
-
-cdef _key(entry *e):
- return atom_pywrap(ASSOC_ATOM(<void *>e))
-
-cdef _eget(entry *e):
- Py_INCREF(e.v)
- return <object>e.v
-
-cdef void _eset(entry *e, v):
- if e.v:
- Py_DECREF(e.v)
- e.v = <PyObject *>v
- Py_INCREF(e.v)
-
-cdef void _edel(assoc_table *t, entry *e):
- if e.v:
- Py_DECREF(e.v)
- assoc_remove(t, <void *>e)
-
-cdef class Table:
- cdef assoc_table _t
- def __new__(me, *hunoz, **hukairz):
- assoc_create(&me._t)
- def __init__(me, stuff = None, **kw):
- me.update(stuff, **kw)
- def __getitem__(me, key):
- cdef entry *e
- e = _find(&me._t, key, NULL)
- if not e:
- raise KeyError, key
- return _eget(e)
- def __setitem__(me, key, value):
- cdef unsigned f
- _eset(_find(&me._t, key, &f), value)
- def __delitem__(me, key):
- cdef entry *e
- cdef unsigned f
- e = _find(&me._t, key, &f)
- if not e:
- raise KeyError, key
- _edel(&me._t, e)
- def get(me, key, default = None):
- cdef entry *e
- e = _find(&me._t, key, NULL)
- if not e:
- return default
- return _eget(e)
- def setdefault(me, key, default = None):
- cdef entry *e
- cdef unsigned f
- e = _find(&me._t, key, &f)
- if f:
- return _eget(e)
- else:
- _eset(e, default)
- return default
- def pop(me, key, default = None):
- cdef entry *e
- e = _find(&me._t, key, NULL)
- if not e:
- return default
- rc = _eget(e)
- _edel(&me._t, e)
- return rc
- def popitem(me):
- cdef entry *e
- cdef assoc_iter i
- assoc_mkiter(&i, &me._t)
- e = <entry *>assoc_next(&i)
- if not e:
- raise ValueError, 'popitem(): table is empty'
- return _key(e), _eget(e)
- def keys(me):
- cdef assoc_iter i
- cdef entry *e
- l = []
- assoc_mkiter(&i, &me._t)
- while 1:
- e = <entry *>assoc_next(&i)
- if not e:
- break
- l.append(_key(e))
- return l
- def values(me):
- cdef assoc_iter i
- cdef entry *e
- l = []
- assoc_mkiter(&i, &me._t)
- while 1:
- e = <entry *>assoc_next(&i)
- if not e:
- break
- l.append(_eget(e))
- return l
- def items(me):
- cdef assoc_iter i
- cdef entry *e
- l = []
- assoc_mkiter(&i, &me._t)
- while 1:
- e = <entry *>assoc_next(&i)
- if not e:
- break
- l.append((_key(e), _eget(e)))
- return l
- def clear(me):
- cdef assoc_iter i
- cdef entry *e
- assoc_mkiter(&i, &me._t)
- while 1:
- e = <entry *>assoc_next(&i)
- if not e:
- break
- _edel(&me._t, e)
- return me
- def __dealloc__(me):
- cdef assoc_iter i
- cdef entry *e
- assoc_mkiter(&i, &me._t)
- while 1:
- e = <entry *>assoc_next(&i)
- if not e:
- break
- _edel(&me._t, e)
- assoc_destroy(&me._t)
- def iterkeys(me):
- return KeyIter(me)
- def __iter__(me):
- return KeyIter(me)
- def itervalues(me):
- return ValueIter(me)
- def iteritems(me):
- return ItemIter(me)
- def update(me, stuff = None, **kw):
- if stuff is None:
- pass
- elif hasattr(stuff, 'keys'):
- for k in stuff:
- me[k] = stuff[k]
- else:
- for k, v in stuff:
- me[k] = v
- for k, v in kw.iteritems():
- me[k] = kw[k]
- return me
-
-cdef class KeyIter:
- cdef Table _t
- cdef assoc_iter _i
- def __new__(me, Table t):
- me._t = t
- assoc_mkiter(&me._i, &t._t)
- def __iter__(me):
- return me
- def __next__(me):
- cdef entry *e
- e = <entry *>assoc_next(&me._i)
- if not e:
- raise StopIteration
- return _key(e)
-
-cdef class ValueIter:
- cdef Table _t
- cdef assoc_iter _i
- def __new__(me, Table t):
- me._t = t
- assoc_mkiter(&me._i, &t._t)
- def __iter__(me):
- return me
- def __next__(me):
- cdef entry *e
- e = <entry *>assoc_next(&me._i)
- if not e:
- raise StopIteration
- return _eget(e)
-
-cdef class ItemIter:
- cdef Table _t
- cdef assoc_iter _i
- def __new__(me, Table t):
- me._t = t
- assoc_mkiter(&me._i, &t._t)
- def __iter__(me):
- return me
- def __next__(me):
- cdef entry *e
- e = <entry *>assoc_next(&me._i)
- if not e:
- raise StopIteration
- return _key(e), _eget(e)
-
-Atom = atom_pystartup()
-
#----- That's all, folks ----------------------------------------------------
--- /dev/null
+# -*-pyrex-*-
+#
+# $Id$
+#
+# Background name resolution
+#
+# (c) 2005 Straylight/Edgeware
+#
+
+#----- Licensing notice -----------------------------------------------------
+#
+# This file is part of the Python interface to mLib.
+#
+# mLib/Python is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# mLib/Python is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with mLib/Python; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+cdef class SelResolve:
+ cdef bres_client r
+ cdef int _activep
+ cdef _resolved
+ cdef _failed
+ def __init__(me, *hunoz, **hukairz):
+ raise TypeError, 'abstract class'
+ property activep:
+ def __get__(me):
+ return _tobool(me._activep)
+ def kill(me):
+ if not me._activep:
+ raise ValueError, 'already dead'
+ me._dead()
+ bres_abort(&me.r)
+ return me
+ cdef _dead(me):
+ me._activep = 0
+ me.dead()
+ def dead(me):
+ pass
+ property resolvedproc:
+ def __get__(me):
+ return me._resolved
+ def __set__(me, proc):
+ me._resolved = _checkcallable(proc, 'resolved proc')
+ def __del__(me):
+ me._resolved = None
+ property failedproc:
+ def __get__(me):
+ return me._failed
+ def __set__(me, proc):
+ me._failed = _checkcallable(proc, 'failed proc')
+ def __del__(me):
+ me._failed = None
+ def resolved(me, name, aliases, addrs):
+ return _maybecall(me._resolved, (name, aliases, addrs))
+ def failed(me):
+ return _maybecall(me._failed, ())
+
+cdef class SelResolveByName (SelResolve):
+ def __new__(me, char *name, resolvedproc = None, failedproc = None,
+ *hunoz, **hukairz):
+ bres_byname(&me.r, name, _resfunc, <void *>me)
+ me._resolved = _checkcallable(resolvedproc, 'resolved proc')
+ me._failed = _checkcallable(failedproc, 'failed proc')
+ me._activep = 1
+ def __init__(me, name, resolvedproc = None, failedproc = None):
+ pass
+
+cdef class SelResolveByAddr (SelResolve):
+ def __new__(me, char *addr, resolvedproc = None, failedproc = None,
+ *hunoz, **hukairz):
+ cdef in_addr ia
+ if not inet_aton(addr, &ia):
+ raise TypeError, 'bad IP address'
+ bres_byaddr(&me.r, ia, _resfunc, <void *>me)
+ me._resolved = _checkcallable(resolvedproc, 'resolved proc')
+ me._failed = _checkcallable(failedproc, 'failed proc')
+ me._activep = 1
+ def __init__(me, addr, resolvedproc = None, failedproc = None):
+ pass
+
+cdef void _resfunc(hostent *h, void *arg):
+ cdef SelResolve r
+ cdef int i
+ r = <SelResolve>arg
+ r._dead()
+ if h is NULL:
+ r.failed(r)
+ else:
+ alias = []
+ addr = []
+ i = 0
+ while h.h_aliases[i]:
+ alias.append(h.h_aliases[i])
+ i = i + 1
+ i = 0
+ while h.h_addr_list[i]:
+ addr.append(inet_ntoa((<in_addr *>h.h_addr_list[i])[0]))
+ i = i + 1
+ r.resolved(h.h_name, alias, addr)
+
+bres_exec(NULL)
+bres_init(&_sel)
+
+#----- That's all, folks ----------------------------------------------------
#----- External dependencies ------------------------------------------------
-cdef extern from 'stddef.h':
- ctypedef int size_t
-
-cdef extern from 'mLib/dstr.h':
- ctypedef struct dstr:
- char *buf
- int len
- void DCREATE(dstr *d)
- void dstr_destroy(dstr *d)
-
-cdef extern from 'mLib/alloc.h':
- char *xstrdup(char *p)
- void xfree(void *p)
-
cdef extern from 'mLib/%PREFIX%.h':
ctypedef struct %PREFIX%_ctx:
char *indent
int maxline
- void %PREFIX%_init(%PREFIX%_ctx *b)
- void %PREFIX%_encode(%PREFIX%_ctx *b, void *p, size_t sz, dstr *d)
- void %PREFIX%_decode(%PREFIX%_ctx *b, void *p, size_t sz, dstr *d)
-
-cdef extern from 'Python.h':
- int PyObject_AsReadBuffer(obj, void **buf, int *len) except -1
- object PyString_FromStringAndSize(char *p, int len)
+ void _%PREFIX%_init "%PREFIX%_init"(%PREFIX%_ctx *b)
+ void _%PREFIX%_encode "%PREFIX%_encode"(%PREFIX%_ctx *b,
+ void *p, size_t sz, dstr *d)
+ void _%PREFIX%_decode"%PREFIX%_decode"(%PREFIX%_ctx *b,
+ void *p, size_t sz, dstr *d)
-cdef class Encode:
+cdef class %CLASS%Encode:
cdef %PREFIX%_ctx ctx
def __new__(me, *hunoz, **hukairz):
- %PREFIX%_init(&me.ctx)
+ _%PREFIX%_init(&me.ctx)
me.ctx.indent = NULL
def __init__(me, indent = '\n', maxline = 72):
if me.ctx.indent:
DCREATE(&d)
try:
PyObject_AsReadBuffer(text, &p, &len)
- %PREFIX%_encode(&me.ctx, p, len, &d)
+ _%PREFIX%_encode(&me.ctx, p, len, &d)
rc = PyString_FromStringAndSize(d.buf, d.len)
finally:
dstr_destroy(&d)
cdef dstr d
DCREATE(&d)
try:
- %PREFIX%_encode(&me.ctx, NULL, 0, &d)
+ _%PREFIX%_encode(&me.ctx, NULL, 0, &d)
rc = PyString_FromStringAndSize(d.buf, d.len)
finally:
dstr_destroy(&d)
return rc
-def encode(text, *arg, **kw):
- e = Encode(*arg, **kw)
+def %PREFIX%_encode(text, *arg, **kw):
+ e = %CLASS%Encode(*arg, **kw)
return e.encode(text) + e.done()
-cdef class Decode:
+cdef class %CLASS%Decode:
cdef %PREFIX%_ctx ctx
def __new__(me, *hunoz, **hukairz):
- %PREFIX%_init(&me.ctx)
+ _%PREFIX%_init(&me.ctx)
me.ctx.indent = NULL
def decode(me, text):
cdef void *p
DCREATE(&d)
try:
PyObject_AsReadBuffer(text, &p, &len)
- %PREFIX%_decode(&me.ctx, p, len, &d)
+ _%PREFIX%_decode(&me.ctx, p, len, &d)
rc = PyString_FromStringAndSize(d.buf, d.len)
finally:
dstr_destroy(&d)
cdef dstr d
DCREATE(&d)
try:
- %PREFIX%_decode(&me.ctx, NULL, 0, &d)
+ _%PREFIX%_decode(&me.ctx, NULL, 0, &d)
rc = PyString_FromStringAndSize(d.buf, d.len)
finally:
dstr_destroy(&d)
return rc
-def decode(text, *arg, **kw):
- d = Decode(*arg, **kw)
+def %PREFIX%_decode(text, *arg, **kw):
+ d = %CLASS%Decode(*arg, **kw)
return e.decode(text) + d.done()
#----- That's all, folks ----------------------------------------------------
--- /dev/null
+# -*-pyrex-*-
+#
+# $Id$
+#
+# Non-blocking connections
+#
+# (c) 2005 Straylight/Edgeware
+#
+
+#----- Licensing notice -----------------------------------------------------
+#
+# This file is part of the Python interface to mLib.
+#
+# mLib/Python is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# mLib/Python is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with mLib/Python; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+cdef class SelConnect:
+ cdef conn c
+ cdef int _activep
+ cdef readonly object socket
+ cdef _connected
+ cdef _error
+ def __new__(me, sk, connectedproc = None, errorproc = None,
+ *hunoz, **hukairz):
+ conn_fd(&me.c, &_sel, sk.fileno(), _connfunc, <void *>me)
+ me._activep = 1
+ me.socket = sk
+ me._connected = _checkcallable(connectedproc, 'connected proc')
+ me._error = _checkcallable(errorproc, 'error proc')
+ def __dealloc__(me):
+ if me._activep:
+ conn_kill(&me.c)
+ property activep:
+ def __get__(me):
+ return _tobool(me._activep)
+ property connectedproc:
+ def __get__(me):
+ return me._connected
+ def __set__(me, proc):
+ me._connected = _checkcallable(proc, 'connected proc')
+ def __del__(me):
+ me._connected = None
+ property errorproc:
+ def __get__(me):
+ return me._error
+ def __set__(me, proc):
+ me._error = _checkcallable(proc, 'error proc')
+ def __del__(me):
+ me._error = None
+ def kill(me):
+ if not me._activep:
+ raise ValueError, 'already dead'
+ conn_kill(&me.c);
+ me._dead()
+ return me
+ cdef _dead(me):
+ me._activep = 0
+ me.dead()
+ def dead(me):
+ pass
+ def connected(me):
+ return _maybecall(me._connected, ())
+ def error(me, errno, strerror):
+ return _maybecall(me._error, ())
+
+cdef void _connfunc(int fd, void *arg):
+ cdef SelConnect c
+ c = <SelConnect>arg
+ c._dead()
+ if fd == -1:
+ c.socket = None
+ c.error(errno, strerror(errno))
+ else:
+ c.connected()
+
+#----- That's all, folks ----------------------------------------------------
# along with mLib/Python; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-cdef extern from 'mLib/crc32.h':
- ctypedef int uint32
- uint32 c_crc32 "crc32" (uint32 a, void *p, int sz)
-
-cdef extern from 'limits.h':
- enum:
- LONG_MAX
-
-cdef extern from 'Python.h':
- int PyObject_AsReadBuffer(obj, void **buf, int *len) except -1
- PyInt_FromLong(long i)
- PyLong_FromUnsignedLong(unsigned long i)
-
-cdef _u32(uint32 x):
- if x < LONG_MAX:
- return PyInt_FromLong(x)
- else:
- return PyLong_FromUnsignedLong(x)
-
cdef class CRC32:
cdef uint32 _a
def __new__(me, *hunoz, **hukairz):
--- /dev/null
+python-mlib (1.0.0) experimental; urgency=low
+
+ * Debianization!
+
+ -- Mark Wooding <mdw@distorted.org.uk> Thu, 13 Oct 2005 18:14:18 +0100
--- /dev/null
+Source: python-mlib
+Section: libs
+Priority: extra
+Build-Depends:
+ mlib-dev,
+ python, python2.3, python2.3-pyrex, python2.4, python2.4-pyrex
+Maintainer: Mark Wooding <mdw@distorted.org.uk>
+Standards-Version: 3.1.1
+
+Package: python-mlib
+Architecture: all
+Depends: ${python:Depends}
+Description: A library of miscellaneous stuff
+ The mLib library provides various handy utilities, including
+ * yet another options parser, like GNU getopt but more so;
+ * a simple but efficient universal hashing family;
+ * a suite for writing event-driven select-based servers;
+ * a simple exception-handling system, based on longjmp;
+ * dynamically resizing strings and arrays;
+ * a resizing hashtable;
+ * base64 and hex encoding and decoding; and
+ * a simple background DNS resolver.
+ .
+ This is a dummy package to pull in the right bindings for the default Debian
+ version of Python.
+ .
+ Not all of the features of mLib are available (or, indeed, very useful) in
+ Python. For example, Python has its own exception system, and different
+ ideas about how strings work.
+
+Package: python2.3-mlib
+Architecture: any
+Depends: ${shlibs:Depends}, ${python:Depends}
+Description: A library of miscellaneous stuff
+ The mLib library provides various handy utilities, including
+ * yet another options parser, like GNU getopt but more so;
+ * a simple but efficient universal hashing family;
+ * a suite for writing event-driven select-based servers;
+ * a simple exception-handling system, based on longjmp;
+ * dynamically resizing strings and arrays;
+ * a resizing hashtable;
+ * base64 and hex encoding and decoding; and
+ * a simple background DNS resolver.
+ .
+ This package provides Python bindings for mLib, for Python version 2.3.
+ .
+ Not all of the features of mLib are available (or, indeed, very useful) in
+ Python. For example, Python has its own exception system, and different
+ ideas about how strings work.
+
+Package: python2.4-mlib
+Architecture: any
+Depends: ${shlibs:Depends}, ${python:Depends}
+Description: A library of miscellaneous stuff
+ The mLib library provides various handy utilities, including
+ * yet another options parser, like GNU getopt but more so;
+ * a simple but efficient universal hashing family;
+ * a suite for writing event-driven select-based servers;
+ * a simple exception-handling system, based on longjmp;
+ * dynamically resizing strings and arrays;
+ * a resizing hashtable;
+ * base64 and hex encoding and decoding; and
+ * a simple background DNS resolver.
+ .
+ This package provides Python bindings for mLib, for Python version 2.4.
+ .
+ Not all of the features of mLib are available (or, indeed, very useful) in
+ Python. For example, Python has its own exception system, and different
+ ideas about how strings work.
--- /dev/null
+mLib-python is copyright (c) 2003 Straylight/Edgeware.
+
+mLib-python is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+mLib-python is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have a copy of the GNU General Public License in
+/usr/share/common-licenses/GPL; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+USA.
--- /dev/null
+#! /usr/bin/make -f
+
+export DH_COMPAT = 4
+
+DEFVERSION = 2.3
+VERSIONS = $(DEFVERSION) 2.4
+
+build: build-stamp
+
+build-stamp:
+ for v in $(VERSIONS); do python$$v setup.py build; done
+ touch build-stamp
+
+clean:
+ dh_clean
+ make clean
+ rm -rf build build-stamp
+
+install: build
+ dh_clean
+ for v in $(VERSIONS); do \
+ python$$v setup.py build; \
+ python$$v setup.py install --root=debian/python$$v-mlib; \
+ done
+ mkdir -p debian/python-mlib
+
+binary-indep: install
+ dh_testdir -i
+ dh_testroot -i
+ dh_compress -i
+ dh_installdocs -i
+ dh_python -i
+ dh_gencontrol -i
+ dh_fixperms -i
+ dh_installdeb -i
+ dh_md5sums -i
+ dh_builddeb -i
+
+binary-arch: install
+ dh_testdir -a
+ dh_testroot -a
+ dh_compress -a
+ dh_installdocs -a
+ dh_strip -a
+ dh_shlibdeps -a
+ dh_python -a
+ dh_gencontrol -a
+ dh_fixperms -a
+ dh_installdeb -a
+ dh_md5sums -a
+ dh_builddeb -a
+
+binary: binary-indep binary-arch
+
+source:
+ rm -rf dist/*.tar.gz dist/=deb=
+ python setup.py sdist
+ mkdir dist/=deb=
+ cd dist/=deb=; tar xvfz ../*.tar.gz
+ d=`pwd`; cd ..; dpkg-source -i -i'/\.svn/' -b $$d/dist/=deb=/*
+ rm -rf dist/=deb=
+
+.PHONY: binary binary-arch binary-indep clean install source build
--- /dev/null
+# -*-pyrex-*-
+#
+# $Id$
+#
+# Basic definitions, used all over
+#
+# (c) 2005 Straylight/Edgeware
+#
+
+#----- Licensing notice -----------------------------------------------------
+#
+# This file is part of the Python interface to mLib.
+#
+# mLib/Python is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# mLib/Python is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with mLib/Python; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#----- C library ------------------------------------------------------------
+
+cdef extern from 'errno.h':
+ int errno
+ enum:
+ EINTR
+ EAGAIN
+cdef extern from 'limits.h':
+ enum:
+ LONG_MAX
+cdef extern from 'math.h':
+ double modf(double x, double *i)
+cdef extern from 'stddef.h':
+ ctypedef int size_t
+cdef extern from 'string.h':
+ void memcpy(void *p, void *q, size_t n)
+ char *strerror(int err)
+
+#----- Unix interface -------------------------------------------------------
+
+cdef extern from 'sys/types.h':
+ pass
+cdef extern from 'sys/time.h':
+ struct timeval:
+ int tv_sec
+ int tv_usec
+
+cdef extern from 'sys/socket.h':
+ struct sockaddr:
+ int sa_family
+ enum:
+ AF_INET
+ int getsockname(int fd, sockaddr *pa, size_t *psz)
+ int getpeername(int fd, sockaddr *pa, size_t *psz)
+cdef extern from 'arpa/inet.h':
+ struct in_addr:
+ int s_addr
+ int inet_aton(char *rp, in_addr *ia)
+ char *inet_ntoa(in_addr ia)
+cdef extern from 'netinet/in.h':
+ struct sockaddr_in:
+ int sin_family
+ in_addr sin_addr
+ int sin_port
+ int htons(int x)
+ int htonl(int x)
+ int ntohs(int x)
+ int ntohl(int x)
+cdef extern from 'netdb.h':
+ struct hostent:
+ char *h_name
+ char **h_aliases
+ int h_addrtype
+ int h_length
+ char **h_addr_list
+ char *h_addr
+ int h_errno
+
+#----- Python ---------------------------------------------------------------
+
+cdef extern from 'Python.h':
+
+ object PyString_FromStringAndSize(char *p, int len)
+ int PyString_AsStringAndSize(obj, char **p, int *len) except -1
+ int PyObject_AsReadBuffer(obj, void **buf, int *len) except -1
+ int PyObject_TypeCheck(obj, ty)
+ object PyInt_FromLong(long i)
+ object PyLong_FromUnsignedLong(unsigned long i)
+
+ ctypedef struct PyObject:
+ pass
+ ctypedef struct PyTypeObject:
+ pass
+ void Py_INCREF(PyObject *obj)
+ void Py_DECREF(PyObject *obj)
+
+#----- mLib basic stuff -----------------------------------------------------
+
+cdef extern from 'mLib/alloc.h':
+ char *xstrdup(char *p)
+ void *xmalloc(size_t sz)
+ void xfree(void *p)
+
+cdef extern from 'mLib/bits.h':
+ ctypedef int uint32
+
+cdef extern from 'mLib/dstr.h':
+ ctypedef struct dstr:
+ char *buf
+ int len
+ void DCREATE(dstr *d)
+ void dstr_destroy(dstr *d)
+
+#----- CRC32 ----------------------------------------------------------------
+
+cdef extern from 'mLib/crc32.h':
+ uint32 c_crc32 "crc32" (uint32 a, void *p, int sz)
+
+#----- Universal hashing ----------------------------------------------------
+
+cdef extern from 'mLib/unihash.h':
+ ctypedef struct unihash_info:
+ pass
+ void unihash_setkey(unihash_info *i, uint32 k)
+ uint32 UNIHASH_INIT(unihash_info *i)
+ uint32 unihash_hash(unihash_info *i, uint32 a, void *p, int sz)
+ unihash_info unihash_global
+
+#----- Symbol tables --------------------------------------------------------
+
+cdef extern from 'mLib/sym.h':
+ ctypedef struct sym_table:
+ pass
+ ctypedef struct sym_base:
+ pass
+ ctypedef struct sym_iter:
+ pass
+ void sym_create(sym_table *t)
+ void sym_destroy(sym_table *t)
+ void *sym_find(sym_table *t, char *n, long l, int sz, unsigned *f)
+ void sym_remove(sym_table *t, void *b)
+ char *SYM_NAME(void *b)
+ int SYM_LEN(void *b)
+ void sym_mkiter(sym_iter *i, sym_table *t)
+ void *sym_next(sym_iter *i)
+
+#----- Atom stuff -----------------------------------------------------------
+
+# --- Atoms ---
+#
+# Partly written in `real' C.
+
+cdef extern from 'atom.h':
+ ctypedef struct atom:
+ pass
+ ctypedef struct atom_iter:
+ pass
+ ctypedef struct atom_table:
+ pass
+ atom_table *ATOM_GLOBAL
+ void atom_mkiter(atom_iter *i, atom_table *t)
+ atom *atom_next(atom_iter *)
+ void atom_pysetup()
+ atom_pywrap(atom *a)
+ atom_pyintern(obj)
+ atom *ATOM_A(obj)
+ PyTypeObject atom_pytype
+
+# --- Association tables ---
+
+cdef extern from 'mLib/assoc.h':
+ ctypedef struct assoc_table:
+ pass
+ ctypedef struct assoc_base:
+ pass
+ ctypedef struct assoc_iter:
+ pass
+ void assoc_create(assoc_table *t)
+ void assoc_destroy(assoc_table *t)
+ void *assoc_find(assoc_table *t, atom *a, int sz, unsigned *f)
+ void assoc_remove(assoc_table *t, void *b)
+ atom *ASSOC_ATOM(void *b)
+ void assoc_mkiter(assoc_iter *i, assoc_table *t)
+ void *assoc_next(assoc_iter *i)
+
+#----- Double-ended arrays --------------------------------------------------
+
+cdef extern from 'array.h':
+ void da_pysetup()
+ PyTypeObject da_pytype
+ PyTypeObject daiter_pytype
+
+#----- Line buffer ----------------------------------------------------------
+
+cdef extern from 'mLib/lbuf.h':
+ cdef struct lbuf:
+ int f
+ int delim
+ size_t sz
+ enum:
+ LBUF_ENABLE
+ _LBUF_CRLF "LBUF_CRLF"
+ _LBUF_STRICTCRLF "LBUF_STRICTCRLF"
+ void lbuf_flush(lbuf *b, char *p, size_t len)
+ void lbuf_close(lbuf *b)
+ size_t lbuf_free(lbuf *b, char **p)
+ void lbuf_setsize(lbuf *b, size_t sz)
+ void lbuf_enable(lbuf *b)
+ void lbuf_disable(lbuf *b)
+ void lbuf_init(lbuf *b,
+ void (*func)(char *s, size_t len, void *arg), void *arg)
+ void lbuf_destroy(lbuf *b)
+
+#----- Packet buffer --------------------------------------------------------
+
+cdef extern from 'mLib/pkbuf.h':
+ ctypedef struct pkbuf:
+ int f
+ int want
+ enum:
+ PKBUF_ENABLE
+ void pkbuf_flush(pkbuf *pk, unsigned char *p, size_t len)
+ void pkbuf_close(pkbuf *pk)
+ size_t pkbuf_free(pkbuf *pk, unsigned char **p)
+ void pkbuf_want(pkbuf *pk, size_t sz)
+ void pkbuf_init(pkbuf *b,
+ void (*func)(unsigned char *s, size_t len,
+ pkbuf *pk, size_t *keep, void *arg),
+ void *arg)
+ void pkbuf_destroy(pkbuf *b)
+
+#----- Select stuff ---------------------------------------------------------
+
+# --- Basics ---
+
+cdef extern from 'mLib/sel.h':
+ ctypedef struct sel_state:
+ pass
+ ctypedef struct sel_file:
+ int fd
+ ctypedef struct sel_timer:
+ pass
+ enum:
+ _SEL_READ "SEL_READ"
+ _SEL_WRITE "SEL_WRITE"
+ _SEL_EXC "SEL_EXC"
+ void sel_init(sel_state *s)
+ void sel_initfile(sel_state *s, sel_file *f, int fd, unsigned mode,
+ void (*func)(int fd, unsigned mode, void *arg),
+ void *arg)
+ void sel_force(sel_file *f)
+ void sel_addfile(sel_file *f)
+ void sel_rmfile(sel_file *f)
+ void sel_addtimer(sel_state *s, sel_timer *t, timeval *tv,
+ void (*func)(timeval *tv, void *arg),
+ void *arg)
+ void sel_rmtimer(sel_timer *t)
+ int sel_select(sel_state *s) except *
+
+# --- Non-blocking connection ---
+
+cdef extern from 'mLib/conn.h':
+ ctypedef struct conn:
+ pass
+ int conn_fd(conn *c, sel_state *s, int fd,
+ void (*func)(int fd, void *arg), void *arg)
+ void conn_kill(conn *c)
+
+# --- Background name resolver ---
+
+cdef extern from 'mLib/bres.h':
+ ctypedef struct bres_client:
+ pass
+ void bres_byname(bres_client *r, char *name,
+ void (*func)(hostent *h, void *arg), void *arg)
+ void bres_byaddr(bres_client *r, in_addr addr,
+ void (*func)(hostent *h, void *arg), void *arg)
+ void bres_abort(bres_client *r)
+ void bres_exec(char *null)
+ void bres_init(sel_state *s)
+
+# --- In-band signal handling ---
+
+cdef extern from 'mLib/sig.h':
+ ctypedef struct sig:
+ pass
+ void sig_add(sig *s, int n, void (*func)(int n, void *arg), void *arg)
+ void sig_remove(sig *s)
+ void sig_init(sel_state *s)
+
+# --- Line buffer ---
+
+cdef extern from 'mLib/selbuf.h':
+ ctypedef struct selbuf:
+ sel_file reader
+ lbuf b
+ void selbuf_enable(selbuf *b)
+ void selbuf_disable(selbuf *b)
+ void selbuf_setsize(selbuf *b, size_t sz)
+ void selbuf_init(selbuf *b, sel_state *s, int fd,
+ void (*func)(char *s, size_t len, void *arg), void *arg)
+ void selbuf_destroy(selbuf *b)
+
+# --- Packet buffer ---
+
+cdef extern from 'mLib/selpk.h':
+ ctypedef struct selpk:
+ sel_file reader
+ pkbuf pk
+ void selpk_enable(selpk *b)
+ void selpk_disable(selpk *b)
+ void selpk_want(selpk *b, size_t sz)
+ void selpk_init(selpk *b, sel_state *s, int fd,
+ void (*func)(unsigned char *p, size_t n,
+ pkbuf *pk, size_t *keep, void *arg),
+ void *arg)
+ void selpk_destroy(selpk *b)
+
+# --- Ident client ---
+
+cdef extern from 'mLib/ident.h':
+ ctypedef struct ident_request:
+ pass
+ enum:
+ IDENT_USERID
+ IDENT_ERROR
+ IDENT_BAD
+ struct ident_userid:
+ char *os
+ char *user
+ union ident_u:
+ ident_userid userid
+ char *error
+ ctypedef struct ident_reply:
+ int sport
+ int dport
+ int type
+ ident_u u
+ void ident(ident_request *rq, sel_state *s,
+ sockaddr_in *local, sockaddr_in *remote,
+ void (*func)(ident_reply *r, void *arg),
+ void *arg)
+ void ident_abort(ident_request *rq)
+
+#----- Error reporting ------------------------------------------------------
+
+cdef extern from 'mLib/quis.h':
+ void _ego "ego"(char *prog)
+ char *_quis "quis"()
+cdef extern from 'mLib/report.h':
+ void _moan "moan"(char *f, char *msg)
+
+#----- Internal utilities ---------------------------------------------------
+
+cdef extern from 'grim.h':
+ int PSIZEOF(void *x)
+
+#----- That's all, folks ----------------------------------------------------
#include <Python.h>
-/*----- Functions provided ------------------------------------------------*/
+/*----- Utilities ---------------------------------------------------------*/
#define PSIZEOF(x) sizeof(*x)
-/*----- Utilities ---------------------------------------------------------*/
-
#define RETURN_OBJ(obj) do { Py_INCREF(obj); return (obj); } while (0)
#define RETURN_ME RETURN_OBJ(me)
#define RETURN_NONE RETURN_OBJ(Py_None)
--- /dev/null
+# -*-pyrex-*-
+#
+# $Id$
+#
+# Ident client
+#
+# (c) 2005 Straylight/Edgeware
+#
+
+#----- Licensing notice -----------------------------------------------------
+#
+# This file is part of the Python interface to mLib.
+#
+# mLib/Python is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# mLib/Python is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with mLib/Python; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+import socket
+
+cdef _inaddr_frompy(sockaddr_in *sin, addr):
+ cdef int port
+ if len(addr) != 2:
+ raise TypeError, 'want address/port pair'
+ a = addr[0]
+ if not inet_aton(a, &sin.sin_addr):
+ raise TypeError, 'bad IP address'
+ port = addr[1]
+ if not (0 <= port < 65536):
+ raise TypeError, 'port number out of range'
+ sin.sin_port = htons(port)
+
+cdef _inaddr_topy(sockaddr_in *sin):
+ return inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)
+
+cdef class SelIdentify:
+ cdef ident_request irq
+ cdef int _activep
+ cdef readonly localaddr
+ cdef readonly remoteaddr
+ cdef _user
+ cdef _bad
+ cdef _error
+ cdef _failed
+ cdef _bogus
+ def __new__(me, sk,
+ userproc = None, bogusproc = None,
+ badproc = None, errorproc = None, failedproc = None,
+ *hunoz, **hukairz):
+ cdef sockaddr_in s_in, s_out
+ cdef size_t sz_in, sz_out
+ cdef int fd
+ if PyObject_TypeCheck(sk, socket.SocketType):
+ fd = sk.fileno()
+ sz_in = PSIZEOF(&s_in)
+ sz_out = PSIZEOF(&s_out)
+ if getsockname(fd, <sockaddr *>&s_in, &sz_in) or \
+ getpeername(fd, <sockaddr *>&s_out, &sz_out):
+ _oserror()
+ if s_in.sin_family != AF_INET or s_out.sin_family != AF_INET:
+ raise TypeError, 'must be internet socket'
+ elif len(sk) != 2:
+ raise TypeError, 'want pair of addresses'
+ else:
+ _inaddr_frompy(&s_in, sk[0])
+ _inaddr_frompy(&s_out, sk[1])
+ ident(&me.irq, &_sel, &s_in, &s_out, _identfunc, <void *>me)
+ me.localaddr = _inaddr_topy(&s_in)
+ me.remoteaddr = _inaddr_topy(&s_out)
+ me._activep = 1
+ me._user = _checkcallable(userproc, 'user proc')
+ me._bad = _checkcallable(badproc, 'bad proc')
+ me._error = _checkcallable(errorproc, 'error proc')
+ me._failed = _checkcallable(failedproc, 'failed proc')
+ me._bogus = _checkcallable(bogusproc, 'bogus proc')
+ def __dealloc__(me):
+ if me._activep:
+ ident_abort(&me.irq)
+ property activep:
+ def __get__(me):
+ return _tobool(me._activep)
+ property userproc:
+ def __get__(me):
+ return me._user
+ def __set__(me, proc):
+ me._user = _checkcallable(proc, 'user proc')
+ def __del__(me):
+ me._user = None
+ property eofproc:
+ def __get__(me):
+ return me._eof
+ def __set__(me, proc):
+ me._eof = _checkcallable(proc, 'eof proc')
+ def __del__(me):
+ me._eof = None
+ property badproc:
+ def __get__(me):
+ return me._bad
+ def __set__(me, proc):
+ me._bad = _checkcallable(proc, 'bad proc')
+ def __del__(me):
+ me._bad = None
+ property errorproc:
+ def __get__(me):
+ return me._error
+ def __set__(me, proc):
+ me._error = _checkcallable(proc, 'error proc')
+ def __del__(me):
+ me._error = None
+ property failedproc:
+ def __get__(me):
+ return me._failed
+ def __set__(me, proc):
+ me._failed = _checkcallable(proc, 'failed proc')
+ def __del__(me):
+ me._failed = None
+ property bogusproc:
+ def __get__(me):
+ return me._bogus
+ def __set__(me, proc):
+ me._bogus = _checkcallable(proc, 'bogus proc')
+ def __del__(me):
+ me._bogus = None
+ def kill(me):
+ if not me._activep:
+ raise ValueError, 'already disabled'
+ ident_abort(&me.irq)
+ me._dead()
+ def _dead(me):
+ me._activep = 0
+ me.dead()
+ def dead(me):
+ pass
+ def user(me, os, user):
+ return _maybecall(me._user, (os, user))
+ def bad(me):
+ if me._bad is not None:
+ return me._bad()
+ return me.bogus()
+ def error(me, error):
+ if me._error is not None:
+ return me._error(error)
+ return me.bogus()
+ def failed(me, errno, strerror):
+ if me._failed is not None:
+ return me._failed(errno, strerror)
+ return me.bogus()
+ def bogus(me):
+ return _maybecall(me._bogus, ())
+
+cdef void _identfunc(ident_reply *i, void *arg):
+ cdef SelIdentify id
+ id = <SelIdentify>arg
+ id._dead()
+ if i.type == IDENT_BAD:
+ id.bad()
+ elif i.type == IDENT_ERROR:
+ id.error(i.u.error)
+ elif i.type == IDENT_USERID:
+ id.user(i.u.userid.os, i.u.userid.user)
+
+#----- That's all, folks ----------------------------------------------------
--- /dev/null
+# -*-pyrex-*-
+#
+# $Id$
+#
+# Line buffering
+#
+# (c) 2005 Straylight/Edgeware
+#
+
+#----- Licensing notice -----------------------------------------------------
+#
+# This file is part of the Python interface to mLib.
+#
+# mLib/Python is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# mLib/Python is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with mLib/Python; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+LBUF_CRLF = _LBUF_CRLF
+LBUF_STRICTCRLF = _LBUF_STRICTCRLF
+
+cdef class LineBuffer:
+ cdef lbuf b
+ cdef _line
+ cdef _eof
+ def __new__(me, lineproc = None, eofproc = None, *hunoz, **hukairz):
+ lbuf_init(&me.b, _lbfunc, <void *>me)
+ me._line = _checkcallable(lineproc, 'line proc')
+ me._eof = _checkcallable(eofproc, 'eof proc')
+ def __dealloc__(me):
+ lbuf_destroy(&me.b)
+ property activep:
+ def __get__(me):
+ return _tobool(me.b.f & LBUF_ENABLE)
+ property delim:
+ def __get__(me):
+ if me.b.delim == _LBUF_CRLF or me.b.delim == _LBUF_STRICTCRLF:
+ return me.b.delim
+ else:
+ return chr(me.b.delim)
+ def __set__(me, d):
+ if d == _LBUF_CRLF or d == _LBUF_STRICTCRLF:
+ me.b.delim = d
+ else:
+ me.b.delim = ord(d)
+ property size:
+ def __get__(me):
+ return me.b.sz
+ def __set__(me, sz):
+ if sz <= 0:
+ raise TypeError, 'size must be positive'
+ lbuf_setsize(&me.b, sz)
+ property lineproc:
+ def __get__(me):
+ return me._line
+ def __set__(me, proc):
+ me._line = _checkcallable(proc, 'line proc')
+ def __del__(me):
+ me._line = None
+ property eofproc:
+ def __get__(me):
+ return me._eof
+ def __set__(me, proc):
+ me._eof = _checkcallable(proc, 'eof proc')
+ def __del__(me):
+ me._eof = None
+ def enable(me):
+ if me.b.f & LBUF_ENABLE:
+ raise ValueError, 'already enabled'
+ me.b.f = me.b.f | LBUF_ENABLE
+ me.enabled()
+ return me
+ def disable(me):
+ if not (me.b.f & LBUF_ENABLE):
+ raise ValueError, 'already disabled'
+ me.b.f = me.b.f & ~LBUF_ENABLE
+ me.disabled()
+ return me
+ def close(me):
+ if not (me.b.f & LBUF_ENABLE):
+ raise ValueError, 'buffer disabled'
+ lbuf_close(&me.b)
+ return me
+ property free:
+ def __get__(me):
+ cdef char *p
+ return lbuf_free(&me.b, &p)
+ def flush(me, str):
+ cdef int len
+ cdef char *p
+ cdef char *q
+ cdef size_t n
+ PyString_AsStringAndSize(str, &p, &len)
+ while len > 0:
+ n = lbuf_free(&me.b, &q)
+ if n > len:
+ n = len
+ memcpy(q, p, n)
+ p = p + n
+ len = len - n
+ if not (me.b.f & LBUF_ENABLE):
+ break
+ lbuf_flush(&me.b, q, n)
+ return PyString_FromStringAndSize(p, len)
+ def enabled(me):
+ pass
+ def disabled(me):
+ pass
+ def line(me, line):
+ return _maybecall(me._line, (line,))
+ def eof(me):
+ return _maybecall(me._eof, ())
+
+cdef void _lbfunc(char *s, size_t n, void *arg):
+ cdef LineBuffer sb
+ sb = <LineBuffer>arg
+ if s is NULL:
+ sb.eof()
+ else:
+ sb.line(PyString_FromStringAndSize(s, n))
+
+#----- That's all, folks ----------------------------------------------------
--- /dev/null
+# -*-pyrex-*-
+#
+# $Id$
+#
+# Main driver for mLib module
+#
+# (c) 2005 Straylight/Edgeware
+#
+
+#----- Licensing notice -----------------------------------------------------
+#
+# This file is part of the Python interface to mLib.
+#
+# mLib/Python is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# mLib/Python is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with mLib/Python; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#----- External stuff -------------------------------------------------------
+
+include 'defs.pxi'
+
+#----- Various facilities ---------------------------------------------------
+
+# --- Internal utilities ---
+
+include 'utils.pyx'
+
+# --- Hashing ---
+
+include 'crc32.pyx'
+include 'unihash.pyx'
+
+# --- Data structures ---
+
+include 'mapping.pyx'
+include 'sym.pyx'
+include 'atom.pyx'
+include 'assoc.pyx'
+
+# --- Encodings ---
+
+include 'base64.pyx'
+include 'base32.pyx'
+include 'hex.pyx'
+
+# --- Error reporting ---
+
+include 'report.pyx'
+
+# --- Buffering ---
+
+include 'lbuf.pyx'
+include 'pkbuf.pyx'
+
+# --- Select stuff ---
+
+include 'sel-base.pyx'
+include 'sel-file.pyx'
+include 'sel-timer.pyx'
+include 'conn.pyx'
+include 'bres.pyx'
+include 'sig.pyx'
+include 'selbuf.pyx'
+include 'selpk.pyx'
+include 'ident.pyx'
+
+#----- Set-up stuff ---------------------------------------------------------
+
+cdef object _tyobj(PyTypeObject *ty):
+ cdef PyObject *obj
+ obj = <PyObject *>ty
+ Py_INCREF(obj)
+ return <object>obj
+
+da_pysetup()
+Array = _tyobj(&da_pytype)
+ArrayIter = _tyobj(&daiter_pytype)
+
+atom_pysetup()
+Atom = _tyobj(&atom_pytype)
+
+#----- That's all, folks ----------------------------------------------------
--- /dev/null
+# -*-pyrex-*-
+#
+# $Id$
+#
+# Common mapping stuff
+#
+# (c) 2005 Straylight/Edgeware
+#
+
+#----- Licensing notice -----------------------------------------------------
+#
+# This file is part of the Python interface to mLib.
+#
+# mLib/Python is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# mLib/Python is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with mLib/Python; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+cdef class Mapping
+
+cdef class _MapIterator:
+ cdef void *_next(me):
+ return NULL
+
+cdef class Mapping:
+
+ ## Subclasses must implement these
+ cdef int _init(me) except -1:
+ raise TypeError, 'abstract class'
+ cdef void *_find(me, object key, unsigned *f) except NULL:
+ raise SystemError, 'unimplemented _find'
+ cdef object _key(me, void *e):
+ return None
+ cdef object _value(me, void *e):
+ return None
+ cdef void _setval(me, void *e, object val):
+ pass
+ cdef void _del(me, void *e):
+ pass
+ cdef _MapIterator _iter(me):
+ raise SystemError, 'unimplemented _iter'
+
+ ## Initialization
+ def __new__(me, *hunoz, **hukairz):
+ me._init()
+ def __init__(me, stuff = None, **kw):
+ me.update(stuff, kw)
+
+ ## Bulk update
+ def update(me, stuff = None, **kw):
+ cdef unsigned f
+ if stuff is None:
+ pass
+ elif hasattr(stuff, 'itemiter'):
+ for k, v in stuff.itemiter:
+ me._setval(me._find(k, &f), v)
+ elif hasattr(stuff, 'keys'):
+ for k in stuff.keys():
+ me._setval(me._find( k, &f), stuff[k])
+ else:
+ for k, v in stuff:
+ me._setval(me._find(k, &f), v)
+ for k, v in kw.iteritems():
+ me._setval(me._find(k, &f), v)
+ return me
+
+ ## Item access
+ def __getitem__(me, key):
+ cdef void *e
+ e = me._find(key, NULL)
+ if not e:
+ raise KeyError, key
+ return me._value(e)
+ def __setitem__(me, key, value):
+ cdef unsigned f
+ me._setval(me._find(key, &f), value)
+ def __delitem__(me, key):
+ cdef void *e
+ cdef unsigned f
+ e = me._find(key, &f)
+ if not e:
+ raise KeyError, key
+ me._del(e)
+ def get(me, key, default = None):
+ cdef void *e
+ e = me._find(key, NULL)
+ if not e:
+ return default
+ return me._value(e)
+ def setdefault(me, key, default = None):
+ cdef void *e
+ cdef unsigned f
+ e = me._find(key, &f)
+ if f:
+ return me._value(e)
+ else:
+ me._setval(e, default)
+ return default
+ def pop(me, key, default = None):
+ cdef void *e
+ e = me._find(key, NULL)
+ if not e:
+ return default
+ rc = me._value(e)
+ me._del(e)
+ return rc
+ def popitem(me):
+ cdef _MapIterator i
+ cdef void *e
+ i = me._iter()
+ e = i._next()
+ if not e:
+ raise ValueError, 'popitem(): table is empty'
+ return me._key(e), me._value(e)
+
+ ## Lists of items
+ cdef object _list(me, object (*func)(Mapping m, void *e)):
+ cdef _MapIterator i
+ cdef void *e
+ i = me._iter()
+ l = []
+ while 1:
+ e = i._next()
+ if not e:
+ break
+ l.append(func(me, e))
+ return l
+
+ def keys(me):
+ return me._list(_map_key)
+ def values(me):
+ return me._list(_map_value)
+ def items(me):
+ return me._list(_map_item)
+
+ def clear(me):
+ cdef _MapIterator i
+ cdef void *e
+ i = me._iter()
+ while 1:
+ e = i._next()
+ if not e:
+ break
+ me._del(e)
+ return me
+
+ ## Iteration
+ def __iter__(me):
+ return MapKeyIter(me)
+ def iterkeys(me):
+ return MapKeyIter(me)
+ def itervalues(me):
+ return MapValueIter(me)
+ def iteritems(me):
+ return MapItemIter(me)
+
+cdef class MapIterBase:
+ cdef Mapping m
+ cdef object (*func)(Mapping m, void *e)
+ cdef _MapIterator i
+ cdef int _init(me) except -1:
+ raise TypeError, 'abstract class'
+ def __new__(me):
+ me.i = m._iter()
+ me._init()
+ def __next__(me):
+ cdef void *e
+ e = me.i._next()
+ if not e:
+ raise StopIteration
+ return me.func(me.m, e)
+cdef class MapKeyIter (MapIterBase):
+ cdef int _init(me) except -1:
+ me.func = _map_key
+ return 0
+cdef class MapValueIter (MapIterBase):
+ cdef int _init(me) except -1:
+ me.func = _map_value
+ return 0
+cdef class MapItemIter (MapIterBase):
+ cdef int _init(me) except -1:
+ me.func = _map_item
+ return 0
+
+cdef object _map_key(Mapping m, void *e):
+ return m._key(e)
+cdef object _map_value(Mapping m, void *e):
+ return m._value(e)
+cdef object _map_item(Mapping m, void *e):
+ return m._key(e), m._value(e)
+
+#----- That's all, folks ----------------------------------------------------
--- /dev/null
+# -*-pyrex-*-
+#
+# $Id$
+#
+# Packet buffering
+#
+# (c) 2005 Straylight/Edgeware
+#
+
+#----- Licensing notice -----------------------------------------------------
+#
+# This file is part of the Python interface to mLib.
+#
+# mLib/Python is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# mLib/Python is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with mLib/Python; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+cdef class PacketBuffer:
+ cdef pkbuf pk
+ cdef _packet
+ cdef _eof
+ def __new__(me, packetproc = None, eofproc = None, *hunoz, **hukairz):
+ pkbuf_init(&me.pk, _pkfunc, <void *>me)
+ me._packet = _checkcallable(packetproc, 'packet proc')
+ me._eof = _checkcallable(eofproc, 'eof proc')
+ def __dealloc__(me):
+ pkbuf_destroy(&me.pk)
+ property activep:
+ def __get__(me):
+ return _tobool(me.pk.f & PKBUF_ENABLE)
+ property want:
+ def __get__(me):
+ return me.pk.want
+ def __set__(me, want):
+ if want <= 0:
+ raise TypeError, 'want must be positive'
+ pkbuf_want(&me.pk, pk)
+ property packetproc:
+ def __get__(me):
+ return me._packet
+ def __set__(me, proc):
+ me._line = _checkcallable(proc, 'packet proc')
+ def __del__(me):
+ me._line = None
+ property eofproc:
+ def __get__(me):
+ return me._eof
+ def __set__(me, proc):
+ me._eof = _checkcallable(proc, 'eof proc')
+ def __del__(me):
+ me._eof = None
+ def enable(me):
+ if me.pk.f & PKBUF_ENABLE:
+ raise ValueError, 'already enabled'
+ me.pk.f = me.pk.f | PKBUF_ENABLE
+ me.enabled()
+ return me
+ def disable(me):
+ if not (me.pk.f & PKBUF_ENABLE):
+ raise ValueError, 'already disabled'
+ me.pk.f = me.pk.f & ~PKBUF_ENABLE
+ me.disabled()
+ return me
+ def close(me):
+ if not (me.pk.f & PKBUF_ENABLE):
+ raise ValueError, 'buffer disabled'
+ pkbuf_close(&me.pk)
+ return me
+ property free:
+ def __get__(me):
+ cdef unsigned char *p
+ return pkbuf_free(&me.pk, &p)
+ def flush(me, str):
+ cdef int len
+ cdef unsigned char *p
+ cdef unsigned char *q
+ cdef size_t n
+ PyObject_AsReadBuffer(str, <void **>&p, &len)
+ while len > 0:
+ n = pkbuf_free(&me.pk, &q)
+ if n > len:
+ n = len
+ memcpy(q, p, n)
+ p = p + n
+ len = len - n
+ if not (me.pk.f & PKBUF_ENABLE):
+ break
+ pkbuf_flush(&me.pk, q, n)
+ return PyString_FromStringAndSize(<char *>p, len)
+ def enabled(me):
+ pass
+ def disabled(me):
+ pass
+ def packet(me, pk):
+ return _maybecall(me._packet, (pk,))
+ def eof(me):
+ return _maybecall(me._eof, ())
+
+cdef void _pkfunc(unsigned char *p, size_t n, pkbuf *pk,
+ size_t *keep, void *arg):
+ cdef PacketBuffer pb
+ cdef void *rp
+ cdef int rn
+ pb = <PacketBuffer>arg
+ if p is NULL:
+ pb.eof()
+ else:
+ r = pb.packet(PyString_FromStringAndSize(<char *>p, n))
+ if r is not None:
+ PyObject_AsReadBuffer(r, &rp, &rn)
+ if rn > n:
+ raise ValueError, 'remaining buffer too large'
+ if rn:
+ memcpy(p + n - rn, rp, rn)
+ keep[0] = rn
+
+#----- That's all, folks ----------------------------------------------------
# along with mLib/Python; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-cdef extern from 'mLib/quis.h':
- void _ego "ego"(char *prog)
- char *_quis "quis"()
-
-cdef extern from 'mLib/report.h':
- void _moan "moan"(char *f, char *msg)
-
-import sys
-
quis = '<UNNAMED>'
-def ego(prog):
- _ego(prog)
+cdef char *_progstring
+_progstring = NULL
+
+def ego(char *prog):
+ global quis, _progstring
+ if _progstring:
+ xfree(_progstring)
+ _progstring = xstrdup(prog)
+ _ego(_progstring)
quis = _quis()
-def moan(msg):
+def moan(char *msg):
_moan('%s', msg)
-def die(msg, rc = 1):
+def die(char *msg, rc = 126):
_moan('%s', msg)
- sys.exit(rc)
+ raise SystemExit, rc
#----- That's all, folks ----------------------------------------------------
--- /dev/null
+# -*-pyrex-*-
+#
+# $Id$
+#
+# Select basic stuff
+#
+# (c) 2005 Straylight/Edgeware
+#
+
+#----- Licensing notice -----------------------------------------------------
+#
+# This file is part of the Python interface to mLib.
+#
+# mLib/Python is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# mLib/Python is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with mLib/Python; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+cdef sel_state _sel
+
+def select():
+ if sel_select(&_sel) and errno != EINTR and errno != EAGAIN:
+ _oserror()
+
+sel_init(&_sel)
+
+#----- That's all, folks ----------------------------------------------------
--- /dev/null
+# -*-pyrex-*-
+#
+# $Id$
+#
+# File selectors
+#
+# (c) 2005 Straylight/Edgeware
+#
+
+#----- Licensing notice -----------------------------------------------------
+#
+# This file is part of the Python interface to mLib.
+#
+# mLib/Python is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# mLib/Python is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with mLib/Python; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+SEL_READ = _SEL_READ
+SEL_WRITE = _SEL_WRITE
+SEL_EXCEPT = _SEL_EXC
+
+cdef class SelFile:
+ cdef sel_file f
+ cdef int _activep
+ cdef readonly unsigned mode
+ cdef _readyfunc
+ def __new__(me, fd, int mode = SEL_READ, readyproc = None,
+ *hunoz, **hukairz):
+ if (mode != _SEL_READ and
+ mode != _SEL_WRITE and
+ mode != _SEL_EXC):
+ raise ValueError, 'bad select mode'
+ sel_initfile(&_sel, &me.f, _getfd(fd), mode, _filefunc, <void *>me)
+ me._activep = 0
+ me.mode = mode
+ me._ready = _checkcallable(readyproc, 'ready proc')
+ def __dealloc__(me):
+ if me._activep:
+ sel_rmfile(&me.f)
+ property fd:
+ def __get__(me):
+ return me.f.fd
+ property activep:
+ def __get__(me):
+ return _tobool(me._activep)
+ property readyproc:
+ def __get__(me):
+ return me._ready
+ def __set__(me, proc):
+ me._ready = _checkcallable(proc, 'ready proc')
+ def __del__(me):
+ me._ready = None
+ def enable(me):
+ if me._activep:
+ raise ValueError, 'already enabled'
+ sel_addfile(&me.f)
+ me._enabled()
+ return me
+ def disable(me):
+ if not me._activep:
+ raise ValueError, 'already disabled'
+ sel_rmfile(&me.f)
+ me._disabled()
+ return me
+ def force(me):
+ sel_force(&me.f)
+ return me
+ cdef _enabled(me):
+ me._activep = 1
+ me.enabled()
+ cdef _disabled(me):
+ me._activep = 0
+ me.disabled()
+ def enabled(me):
+ pass
+ def disabled(me):
+ pass
+ def ready(me):
+ return _maybecall(me._ready, ())
+
+cdef void _filefunc(int fd, unsigned mode, void *arg):
+ cdef SelFile sf
+ sf = <SelFile>arg
+ sf.ready()
+
+#----- That's all, folks ----------------------------------------------------
--- /dev/null
+# -*-pyrex-*-
+#
+# $Id$
+#
+# Timer selectors
+#
+# (c) 2005 Straylight/Edgeware
+#
+
+#----- Licensing notice -----------------------------------------------------
+#
+# This file is part of the Python interface to mLib.
+#
+# mLib/Python is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# mLib/Python is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with mLib/Python; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+cdef double _tvtofloat(timeval *tv):
+ return tv.tv_sec + (tv.tv_usec / 1000000)
+cdef void _floattotv(timeval *tv, double t):
+ cdef double s, us
+ us = modf(t, &s)
+ tv.tv_sec = s
+ tv.tv_usec = us * 1000000
+
+cdef class SelTimer:
+ cdef sel_timer t
+ cdef int _activep
+ cdef readonly double time
+ cdef _timer
+ def __new__(me, double when, timerproc = None, *hunoz, **hukairz):
+ cdef timeval tv
+ _floattotv(&tv, when)
+ sel_addtimer(&_sel, &me.t, &tv, _timerfunc, <void *>me)
+ me._activep = 1
+ me.time = when
+ me._timer = _checkcallable(timerproc, 'timer proc')
+ def __dealloc__(me):
+ if me._activep:
+ sel_rmtimer(&me.t)
+ property activep:
+ def __get__(me):
+ return _tobool(me._activep)
+ property timerproc:
+ def __get__(me):
+ return me._timer
+ def __set__(me, proc):
+ me._timer = _checkcallable(proc, 'timer proc')
+ def __del__(me):
+ me._timer = None
+ def kill(me):
+ if not me._activep:
+ raise ValueError, 'already dead'
+ sel_rmtimer(&me.t)
+ me._dead()
+ return me
+ cdef _dead(me):
+ me._activep = 0
+ me.dead()
+ def dead(me):
+ pass
+ def timer(me, now):
+ return _maybecall(me._timer, ())
+
+cdef void _timerfunc(timeval *now, void *arg):
+ cdef SelTimer st
+ st = <SelTimer>arg
+ st._dead()
+ st.timer(_tvtofloat(now))
+
+#----- That's all, folks ----------------------------------------------------
--- /dev/null
+# -*-pyrex-*-
+#
+# $Id$
+#
+# Selecting line-buffers
+#
+# (c) 2005 Straylight/Edgeware
+#
+
+#----- Licensing notice -----------------------------------------------------
+#
+# This file is part of the Python interface to mLib.
+#
+# mLib/Python is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# mLib/Python is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with mLib/Python; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+cdef class SelLineBuffer:
+ cdef selbuf b
+ cdef _line
+ cdef _eof
+ def __new__(me, fd, lineproc = None, eofproc = None, *hunoz, **hukairz):
+ selbuf_init(&me.b, &_sel, _getfd(fd), _selbfunc, <void *>me)
+ selbuf_disable(&me.b)
+ me._line = _checkcallable(lineproc, 'line proc')
+ me._eof = _checkcallable(eofproc, 'eof proc')
+ def __dealloc__(me):
+ selbuf_destroy(&me.b)
+ property activep:
+ def __get__(me):
+ return _tobool(me.b.b.f & LBUF_ENABLE)
+ property fd:
+ def __get__(me):
+ return me.b.reader.fd
+ property delim:
+ def __get__(me):
+ if me.b.b.delim == _LBUF_CRLF or me.b.b.delim == _LBUF_STRICTCRLF:
+ return me.b.b.delim
+ else:
+ return chr(me.b.b.delim)
+ def __set__(me, d):
+ if d == _LBUF_CRLF or d == _LBUF_STRICTCRLF:
+ me.b.b.delim = d
+ else:
+ me.b.b.delim = ord(d)
+ property size:
+ def __get__(me):
+ return me.b.b.sz
+ def __set__(me, sz):
+ if sz <= 0:
+ raise TypeError, 'size must be positive'
+ selbuf_setsize(&me.b, sz)
+ property lineproc:
+ def __get__(me):
+ return me._line
+ def __set__(me, proc):
+ me._line = _checkcallable(proc, 'line proc')
+ def __del__(me):
+ me._line = None
+ property eofproc:
+ def __get__(me):
+ return me._eof
+ def __set__(me, proc):
+ me._eof = _checkcallable(proc, 'eof proc')
+ def __del__(me):
+ me._eof = None
+ def enable(me):
+ if me.b.b.f & LBUF_ENABLE:
+ raise ValueError, 'already enabled'
+ selbuf_enable(&me.b)
+ me.enabled()
+ return me
+ def disable(me):
+ if not (me.b.b.f & LBUF_ENABLE):
+ raise ValueError, 'already disabled'
+ selbuf_disable(&me.b)
+ me.disabled()
+ return me
+ def enabled(me):
+ pass
+ def disabled(me):
+ pass
+ def line(me, line):
+ return _maybecall(me._line, (line,))
+ def eof(me):
+ return _maybecall(me._eof, ())
+
+cdef void _selbfunc(char *s, size_t n, void *arg):
+ cdef SelLineBuffer sb
+ sb = <SelLineBuffer>arg
+ if s is NULL:
+ sb.eof()
+ else:
+ sb.line(PyString_FromStringAndSize(s, n))
+
+#----- That's all, folks ----------------------------------------------------
+++ /dev/null
-# -*-pyrex-*-
-#
-# $Id$
-#
-# Selectery
-#
-# (c) 2005 Straylight/Edgeware
-#
-
-#----- Licensing notice -----------------------------------------------------
-#
-# This file is part of the Python interface to mLib.
-#
-# mLib/Python is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# mLib/Python is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with mLib/Python; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#----- External dependencies ------------------------------------------------
-
-cdef extern from 'stddef.h':
- ctypedef int size_t
-cdef extern from 'string.h':
- void memcpy(void *p, void *q, size_t n)
-cdef extern from 'errno.h':
- int errno
- enum:
- EINTR
- EAGAIN
-cdef extern from 'math.h':
- double modf(double x, double *i)
-cdef extern from 'string.h':
- char *strerror(int err)
-cdef extern from 'sys/time.h':
- struct timeval:
- int tv_sec
- int tv_usec
-cdef extern from 'sys/types.h':
- pass
-cdef extern from 'sys/socket.h':
- struct sockaddr:
- int sa_family
- enum:
- AF_INET
- int getsockname(int fd, sockaddr *pa, size_t *psz)
- int getpeername(int fd, sockaddr *pa, size_t *psz)
-cdef extern from 'arpa/inet.h':
- struct in_addr:
- int s_addr
- int inet_aton(char *rp, in_addr *ia)
- char *inet_ntoa(in_addr ia)
-cdef extern from 'netinet/in.h':
- struct sockaddr_in:
- int sin_family
- in_addr sin_addr
- int sin_port
- int htons(int x)
- int htonl(int x)
- int ntohs(int x)
- int ntohl(int x)
-cdef extern from 'netdb.h':
- struct hostent:
- char *h_name
- char **h_aliases
- int h_addrtype
- int h_length
- char **h_addr_list
- char *h_addr
- int h_errno
-
-cdef extern from 'mLib/sel.h':
- ctypedef struct sel_state:
- pass
- ctypedef struct sel_file:
- int fd
- ctypedef struct sel_timer:
- pass
- enum:
- SEL_READ
- SEL_WRITE
- SEL_EXC
- void sel_init(sel_state *s)
- void sel_initfile(sel_state *s, sel_file *f, int fd, unsigned mode,
- void (*func)(int fd, unsigned mode, void *arg),
- void *arg)
- void sel_force(sel_file *f)
- void sel_addfile(sel_file *f)
- void sel_rmfile(sel_file *f)
- void sel_addtimer(sel_state *s, sel_timer *t, timeval *tv,
- void (*func)(timeval *tv, void *arg),
- void *arg)
- void sel_rmtimer(sel_timer *t)
- int sel_select(sel_state *s) except *
-
-cdef extern from 'mLib/conn.h':
- ctypedef struct conn:
- pass
- int conn_fd(conn *c, sel_state *s, int fd,
- void (*func)(int fd, void *arg), void *arg)
- void conn_kill(conn *c)
-
-cdef extern from 'mLib/bres.h':
- ctypedef struct bres_client:
- pass
- void bres_byname(bres_client *r, char *name,
- void (*func)(hostent *h, void *arg), void *arg)
- void bres_byaddr(bres_client *r, in_addr addr,
- void (*func)(hostent *h, void *arg), void *arg)
- void bres_abort(bres_client *r)
- void bres_exec(char *null)
- void bres_init(sel_state *s)
-
-cdef extern from 'mLib/sig.h':
- ctypedef struct sig:
- pass
- void sig_add(sig *s, int n, void (*func)(int n, void *arg), void *arg)
- void sig_remove(sig *s)
- void sig_init(sel_state *s)
-
-cdef extern from 'mLib/lbuf.h':
- cdef struct lbuf:
- int f
- int delim
- size_t sz
- enum:
- LBUF_ENABLE
- LBUF_CRLF
- LBUF_STRICTCRLF
-
-cdef extern from 'mLib/selbuf.h':
- ctypedef struct selbuf:
- sel_file reader
- lbuf b
- void selbuf_enable(selbuf *b)
- void selbuf_disable(selbuf *b)
- void selbuf_setsize(selbuf *b, size_t sz)
- void selbuf_init(selbuf *b, sel_state *s, int fd,
- void (*func)(char *s, size_t len, void *arg), void *arg)
- void selbuf_destroy(selbuf *b)
-
-cdef extern from 'mLib/pkbuf.h':
- ctypedef struct pkbuf:
- int f
- int want
- enum:
- PKBUF_ENABLE
-
-cdef extern from 'mLib/selpk.h':
- ctypedef struct selpk:
- sel_file reader
- pkbuf pk
- void selpk_enable(selpk *b)
- void selpk_disable(selpk *b)
- void selpk_want(selpk *b, size_t sz)
- void selpk_init(selpk *b, sel_state *s, int fd,
- void (*func)(unsigned char *p, size_t n,
- pkbuf *pk, size_t *keep, void *arg),
- void *arg)
- void selpk_destroy(selpk *b)
-
-cdef extern from 'mLib/ident.h':
- ctypedef struct ident_request:
- pass
- enum:
- IDENT_USERID
- IDENT_ERROR
- IDENT_BAD
- struct ident_userid:
- char *os
- char *user
- union ident_u:
- ident_userid userid
- char *error
- ctypedef struct ident_reply:
- int sport
- int dport
- int type
- ident_u u
- void ident(ident_request *rq, sel_state *s,
- sockaddr_in *local, sockaddr_in *remote,
- void (*func)(ident_reply *r, void *arg),
- void *arg)
- void ident_abort(ident_request *rq)
-
-cdef extern from 'Python.h':
- object PyString_FromStringAndSize(char *p, int len)
- int PyString_AsStringAndSize(obj, char **p, int *len) except -1
- int PyObject_AsReadBuffer(obj, void **buf, int *len) except -1
- int PyObject_TypeCheck(obj, ty)
-
-cdef extern from 'grim.h':
- int PSIZEOF(void *x)
-
-import socket
-import signal
-
-#----- Utility functions ----------------------------------------------------
-
-cdef _oserror():
- raise OSError, (errno, strerror(errno))
-
-cdef object _tobool(int i):
- if i:
- return True
- else:
- return False
-
-cdef int _getfd(object fdobj):
- try:
- return fdobj
- except TypeError:
- return fdobj.fileno()
-
-#----- The global select state ----------------------------------------------
-
-cdef sel_state sel
-
-sel_init(&sel)
-bres_init(&sel)
-bres_exec(NULL)
-sig_init(&sel)
-
-def select():
- if sel_select(&sel) and errno != EINTR and errno != EAGAIN:
- _oserror()
-
-#----- File selectors -------------------------------------------------------
-
-READ = SEL_READ
-WRITE = SEL_WRITE
-EXCEPT = SEL_EXC
-
-cdef class File:
- cdef sel_file f
- cdef int _activep
- cdef readonly unsigned mode
- def __new__(me, fd, int mode = SEL_READ):
- if (mode != SEL_READ and
- mode != SEL_WRITE and
- mode != SEL_EXC):
- raise ValueError, 'bad select mode'
- sel_initfile(&sel, &me.f, _getfd(fd), mode, _filefunc, <void *>me)
- me._activep = 0
- me.mode = mode
- def __dealloc__(me):
- if me._activep:
- sel_rmfile(&me.f)
- property fd:
- def __get__(me):
- return me.f.fd
- property activep:
- def __get__(me):
- return _tobool(me._activep)
- def enable(me):
- if me._activep:
- raise ValueError, 'already enabled'
- sel_addfile(&me.f)
- me._activep = 1
- return me
- def disable(me):
- if not me._activep:
- raise ValueError, 'already disabled'
- sel_rmfile(&me.f)
- me._activep = 0
- return me
- def force(me):
- sel_force(&me.f)
- return me
- def ready(me):
- pass
-
-cdef void _filefunc(int fd, unsigned mode, void *arg):
- cdef File sf
- sf = <File>arg
- sf.ready()
-
-#----- Timer selectors ------------------------------------------------------
-
-cdef double _tvtofloat(timeval *tv):
- return tv.tv_sec + (tv.tv_usec / 1000000)
-cdef void _floattotv(timeval *tv, double t):
- cdef double s, us
- us = modf(t, &s)
- tv.tv_sec = s
- tv.tv_usec = us * 1000000
-
-cdef class Timer:
- cdef sel_timer t
- cdef int _activep
- cdef readonly double time
- def __new__(me, double when):
- cdef timeval tv
- _floattotv(&tv, when)
- sel_addtimer(&sel, &me.t, &tv, _timerfunc, <void *>me)
- me._activep = 1
- me.time = when
- def __dealloc__(me):
- if me._activep:
- sel_rmtimer(&me.t)
- property activep:
- def __get__(me):
- return _tobool(me._activep)
- def kill(me):
- if not me._activep:
- raise ValueError, 'already dead'
- sel_rmtimer(&me.t)
- me._activep = 0
- return me
- def timer(me, now):
- pass
-
-cdef void _timerfunc(timeval *now, void *arg):
- cdef Timer st
- st = <Timer>arg
- st._activep = 0
- st.timer(_tvtofloat(now))
-
-#----- Connections ----------------------------------------------------------
-
-cdef class Connect:
- cdef conn c
- cdef int _activep
- cdef readonly object socket
- def __new__(me, sk):
- conn_fd(&me.c, &sel, sk.fileno(), _connfunc, <void *>me)
- me._activep = 1
- me.socket = sk
- def __dealloc__(me):
- if me._activep:
- conn_kill(&me.c)
- property activep:
- def __get__(me):
- return _tobool(me._activep)
- def kill(me):
- if not me._activep:
- raise ValueError, 'already dead'
- conn_kill(&me.c);
- me._activep = 0
- return me
- def connected(me):
- pass
- def error(me, errno, strerror):
- pass
-
-cdef void _connfunc(int fd, void *arg):
- cdef Connect c
- c = <Connect>arg
- c._activep = 0
- if fd == -1:
- c.socket = None
- c.error(errno, strerror(errno))
- else:
- c.connected()
-
-#----- Background name resolution -------------------------------------------
-
-cdef class Resolve:
- cdef bres_client r
- cdef int _activep
- def __init__(me, *hunoz, **hukairz):
- raise TypeError, 'abstract class'
- property activep:
- def __get__(me):
- return _tobool(me._activep)
- def kill(me):
- if not me._activep:
- raise ValueError, 'already dead'
- bres_abort(&me.r)
- return me
- def resolved(me, h):
- pass
- def failed(me):
- pass
-
-cdef class ResolveByName (Resolve):
- def __new__(me, char *name):
- bres_byname(&me.r, name, _resfunc, <void *>me)
- me._activep = 1
- def __init__(me, name):
- pass
-
-cdef class ResolveByAddr (Resolve):
- def __new__(me, char *addr):
- cdef in_addr ia
- if not inet_aton(addr, &ia):
- raise TypeError, 'bad IP address'
- bres_byaddr(&me.r, ia, _resfunc, <void *>me)
- me._activep = 1
- def __init__(me, addr):
- pass
-
-cdef void _resfunc(hostent *h, void *arg):
- cdef Resolve r
- cdef int i
- r = <Resolve>arg
- r._activep = 0
- if h is NULL:
- r.failed(r)
- else:
- alias = []
- addr = []
- i = 0
- while h.h_aliases[i]:
- alias.append(h.h_aliases[i])
- i = i + 1
- i = 0
- while h.h_addr_list[i]:
- addr.append(inet_ntoa((<in_addr *>h.h_addr_list[i])[0]))
- i = i + 1
- r.resolved(h.h_name, alias, addr)
-
-#----- Signal handling ------------------------------------------------------
-
-cdef class Signal:
- cdef sig s
- cdef int _activep
- cdef readonly int signal
- def __new__(me, int sig):
- if sig < 0 or sig >= signal.NSIG:
- raise ValueError, 'signal number out of range'
- me.signal = sig
- me._activep = 0
- def __dealloc__(me):
- if me._activep:
- sig_remove(&me.s)
- def enable(me):
- if me._activep:
- raise ValueError, 'already enabled'
- sig_add(&me.s, me.signal, _sigfunc, <void *>me)
- me._activep = 1
- return me
- def disable(me):
- if not me._activep:
- raise ValueError, 'already disabled'
- sig_remove(&me.s)
- me._activep = 0
- return me
- def signalled(me):
- pass
-
-cdef void _sigfunc(int sig, void *arg):
- cdef Signal s
- s = <Signal>arg
- s.signalled()
-
-#----- Line buffers ---------------------------------------------------------
-
-CRLF = LBUF_CRLF
-STRICTCRLF = LBUF_STRICTCRLF
-
-cdef class LineBuffer:
- cdef selbuf b
- def __new__(me, fd):
- selbuf_init(&me.b, &sel, _getfd(fd), _lbfunc, <void *>me)
- selbuf_disable(&me.b)
- def __dealloc__(me):
- selbuf_destroy(&me.b)
- property activep:
- def __get__(me):
- return _tobool(me.b.b.f & LFBUF_ENABLE)
- property delim:
- def __get__(me):
- if me.b.b.delim == LBUF_CRLF or me.b.b.delim == LBUF_STRICTCRLF:
- return me.b.b.delim
- else:
- return chr(me.b.b.delim)
- def __set__(me, d):
- if d == LBUF_CRLF or d == LBUF_STRICTCRLF:
- me.b.b.delim = d
- else:
- me.b.b.delim = ord(d)
- property size:
- def __get__(me):
- return me.b.b.sz
- def __set__(me, sz):
- selbuf_setsize(&me.b, sz)
- def enable(me):
- if me.b.b.f & LBUF_ENABLE:
- raise ValueError, 'already enabled'
- selbuf_enable(&me.b)
- return me
- def disable(me):
- if not (me.b.b.f & LBUF_ENABLE):
- raise ValueError, 'already disabled'
- selbuf_disable(&me.b)
- return me
- def line(me, line):
- pass
- def eof(me):
- pass
-
-cdef void _lbfunc(char *s, size_t n, void *arg):
- cdef LineBuffer sb
- sb = <LineBuffer>arg
- if s is NULL:
- sb.eof()
- else:
- sb.line(PyString_FromStringAndSize(s, n))
-
-#----- Packet buffers -------------------------------------------------------
-
-cdef class PacketBuffer:
- cdef selpk p
- def __new__(me, fd):
- selpk_init(&me.p, &sel, _getfd(fd), _pkfunc, <void *>me)
- selpk_disable(&me.p)
- def __dealloc__(me):
- selpk_destroy(&me.p)
- property activep:
- def __get__(me):
- return _to_bool(me.p.pk.f & PKBUF_ENABLE)
- property want:
- def __get__(me):
- return me.p.pk.want
- def __set__(me, n):
- selpk_want(&me.p, n)
- def enable(me):
- if me.p.pk.f & PKBUF_ENABLE:
- raise ValueError, 'already enabled'
- selpk_enable(&me.p)
- return me
- def disable(me):
- if not (me.p.pk.f & PKBUF_ENABLE):
- raise ValueError, 'already disabled'
- selpk_disable(&me.p)
- return me
- def packet(me, pk):
- return None
- def eof(me):
- pass
-
-cdef void _pkfunc(unsigned char *p, size_t n, pkbuf *pk,
- size_t *keep, void *arg):
- cdef PacketBuffer pb
- cdef void *rp
- cdef int rn
- pb = <PacketBuffer>arg
- if p is NULL:
- pb.eof()
- else:
- r = pb.packet(PyString_FromStringAndSize(<char *>p, n))
- if r is not None:
- PyObject_AsReadBuffer(r, &rp, &rn)
- if rn > n:
- raise ValueError, 'remaining buffer too large'
- if rn:
- memcpy(p + n - rn, rp, rn)
- keep[0] = rn
-
-#----- Ident client ---------------------------------------------------------
-
-cdef _inaddr_frompy(sockaddr_in *sin, addr):
- cdef int port
- if len(addr) != 2:
- raise TypeError, 'want address/port pair'
- a = addr[0]
- if not inet_aton(a, &sin.sin_addr):
- raise TypeError, 'bad IP address'
- port = addr[1]
- if not (0 <= port < 65536):
- raise TypeError, 'port number out of range'
- sin.sin_port = htons(port)
-
-cdef _inaddr_topy(sockaddr_in *sin):
- return inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)
-
-cdef class Identify:
- cdef ident_request irq
- cdef int _activep
- cdef readonly localaddr
- cdef readonly remoteaddr
- def __new__(me, sk):
- cdef sockaddr_in s_in, s_out
- cdef size_t sz_in, sz_out
- cdef int fd
- if PyObject_TypeCheck(sk, socket.SocketType):
- fd = sk.fileno()
- sz_in = PSIZEOF(&s_in)
- sz_out = PSIZEOF(&s_out)
- if getsockname(fd, <sockaddr *>&s_in, &sz_in) or \
- getpeername(fd, <sockaddr *>&s_out, &sz_out):
- _oserror()
- if s_in.sin_family != AF_INET or s_out.sin_family != AF_INET:
- raise TypeError, 'must be internet socket'
- elif len(sk) != 2:
- raise TypeError, 'want pair of addresses'
- else:
- _inaddr_frompy(&s_in, sk[0])
- _inaddr_frompy(&s_out, sk[1])
- ident(&me.irq, &sel, &s_in, &s_out, _identfunc, <void *>me)
- me.localaddr = _inaddr_topy(&s_in)
- me.remoteaddr = _inaddr_topy(&s_out)
- me._activep = 1
- def __dealloc__(me):
- if me._activep:
- ident_abort(&me.irq)
- property activep:
- def __get__(me):
- return _tobool(me._activep)
- def kill(me):
- if not me._activep:
- raise ValueError, 'already disabled'
- ident_abort(&me.irq)
- me._activep = 0
- def user(me, os, user):
- pass
- def bad(me):
- pass
- def error(me, error):
- pass
- def failed(me, errno, strerror):
- pass
-
-cdef void _identfunc(ident_reply *i, void *arg):
- cdef Identify id
- id = <Identify>arg
- id._activep = 0
- if i.type == IDENT_BAD:
- ii.bad()
- elif i.type == IDENT_ERROR:
- ii.error(i.u.error)
- elif i.type == IDENT_USER:
- ii.user(i.u.userid.os, i.u.userid.user)
-
-#----- That's all, folks ----------------------------------------------------
--- /dev/null
+# -*-pyrex-*-
+#
+# $Id$
+#
+# Selecting packet-buffer
+#
+# (c) 2005 Straylight/Edgeware
+#
+
+#----- Licensing notice -----------------------------------------------------
+#
+# This file is part of the Python interface to mLib.
+#
+# mLib/Python is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# mLib/Python is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with mLib/Python; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+cdef class SelPacketBuffer:
+ cdef selpk p
+ cdef _packet
+ cdef _eof
+ def __new__(me, fd, packetproc = None, eofproc = None, *hunoz, **hukairz):
+ selpk_init(&me.p, &_sel, _getfd(fd), _selpkfunc, <void *>me)
+ selpk_disable(&me.p)
+ me._packet = _checkcallable(packetproc, 'packet proc')
+ me._eof = _checkcallable(eofproc, 'eof proc')
+ def __dealloc__(me):
+ selpk_destroy(&me.p)
+ property activep:
+ def __get__(me):
+ return _to_bool(me.p.pk.f & PKBUF_ENABLE)
+ property fd:
+ def __get__(me):
+ return me.p.reader.fd
+ property want:
+ def __get__(me):
+ return me.p.pk.want
+ def __set__(me, n):
+ if n <= 0:
+ raise TypeError, 'size must be positive'
+ selpk_want(&me.p, n)
+ property lineproc:
+ def __get__(me):
+ return me._line
+ def __set__(me, proc):
+ me._line = _checkcallable(proc, 'line proc')
+ def __del__(me):
+ me._line = None
+ property eofproc:
+ def __get__(me):
+ return me._eof
+ def __set__(me, proc):
+ me._eof = _checkcallable(proc, 'eof proc')
+ def __del__(me):
+ me._eof = None
+ def enable(me):
+ if me.p.pk.f & PKBUF_ENABLE:
+ raise ValueError, 'already enabled'
+ selpk_enable(&me.p)
+ me.enabled()
+ return me
+ def disable(me):
+ if not (me.p.pk.f & PKBUF_ENABLE):
+ raise ValueError, 'already disabled'
+ selpk_disable(&me.p)
+ me.disabled()
+ return me
+ def enabled(me):
+ pass
+ def disabled(me):
+ pass
+ def packet(me, pk):
+ return _maybecall(me._packet, (pk,))
+ def eof(me):
+ return _maybecall(me._eof, ())
+
+cdef void _selpkfunc(unsigned char *p, size_t n, pkbuf *pk,
+ size_t *keep, void *arg):
+ cdef SelPacketBuffer pb
+ cdef void *rp
+ cdef int rn
+ pb = <SelPacketBuffer>arg
+ if p is NULL:
+ pb.eof()
+ else:
+ r = pb.packet(PyString_FromStringAndSize(<char *>p, n))
+ if r is not None:
+ PyObject_AsReadBuffer(r, &rp, &rn)
+ if rn > n:
+ raise ValueError, 'remaining buffer too large'
+ if rn:
+ memcpy(p + n - rn, rp, rn)
+ keep[0] = rn
+
+#----- That's all, folks ----------------------------------------------------
rx_subst = sre.compile(r'\%(\w+)\%')
-def getsource(src):
- br = src.find('[')
- if br >= 0:
- if src[-1] != ']':
- raise SyntaxError, 'bad auto file'
- subst = src[br + 1:-1]
- src = src[:br]
- x = subst.split(':')
- infile = x[0]
- if needs_update_p(src, [infile]):
- print 'creating %s from %s...' % (src, infile)
- d = dict([i.split('/', 1) for i in x[1:]])
- out = file(src + '.new', 'w')
- for line in file(infile):
- out.write(rx_subst.sub((lambda m: d[m.group(1)]), line))
+def derive(target, src, subs):
+ if needs_update_p(target, [src]):
+ out = file(target + '.new', 'w')
+ for line in file(src):
+ out.write(rx_subst.sub((lambda m: subs[m.group(1)]), line))
out.close()
- rename(src + '.new', src)
- return src
+ rename(target + '.new', target)
+
+derive('base64.pyx', 'codec.pyx.in',
+ {'CLASS': 'Base64', 'PREFIX': 'base64'})
+derive('base32.pyx', 'codec.pyx.in',
+ {'CLASS': 'Base32', 'PREFIX': 'base32'})
+derive('hex.pyx', 'codec.pyx.in',
+ {'CLASS': 'Hex', 'PREFIX': 'hex'})
def mlibext(src):
col = src.find('!')
src = getsource(src)
mod, hunoz = src.split('.', 1)
srcs = [src]
- return Extension('mLib.' + mod, srcs,
- ##extra_compile_args = ['-O0'],
- include_dirs = uniquify(incdirs),
- library_dirs = uniquify(libdirs),
- libraries = uniquify(libs))
+
+mlib = Extension('mLib', ['mLib.pyx', 'atom-base.c', 'array.c'],
+
+ ##extra_compile_args = ['-O0'],
+ include_dirs = uniquify(incdirs),
+ library_dirs = uniquify(libdirs),
+ libraries = uniquify(libs))
setup(name = 'mLib-python',
version = '1.0.0',
author = 'Straylight/Edgeware',
author_email = 'mdw@distorted.org.uk',
license = 'GNU General Public License',
- packages = ['mLib'],
- ext_modules = [mlibext(x) for x in '''
- select.pyx crc32.pyx unihash.pyx report.pyx
- base64.pyx[codec.pyx.in:PREFIX/base64]
- base32.pyx[codec.pyx.in:PREFIX/base32]
- hex.pyx[codec.pyx.in:PREFIX/hex]
- array.c sym.pyx atom!atom-base.c,atom.pyx
- '''.split()],
+ ext_modules = [mlib],
cmdclass = {'build_ext': build_ext})
--- /dev/null
+# -*-pyrex-*-
+#
+# $Id$
+#
+# In-band signals
+#
+# (c) 2005 Straylight/Edgeware
+#
+
+#----- Licensing notice -----------------------------------------------------
+#
+# This file is part of the Python interface to mLib.
+#
+# mLib/Python is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# mLib/Python is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with mLib/Python; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+import signal
+
+cdef class SelSignal:
+ cdef sig s
+ cdef int _activep
+ cdef readonly int signal
+ cdef _signalled
+ def __new__(me, int sig, signalledproc = None, *hunoz, **hukairz):
+ if sig < 0 or sig >= signal.NSIG:
+ raise ValueError, 'signal number out of range'
+ me.signal = sig
+ me._signalledproc = _checkcallable(signalledproc, 'signalled proc')
+ me._activep = 0
+ def __dealloc__(me):
+ if me._activep:
+ sig_remove(&me.s)
+ property activep:
+ def __get__(me):
+ return _tobool(me._activep)
+ property signalledproc:
+ def __get__(me):
+ return me._signalled
+ def __set__(me, proc):
+ me._signalled = _checkcallable(proc, 'signalled proc')
+ def __del__(me):
+ me._signalled = None
+ def enable(me):
+ if me._activep:
+ raise ValueError, 'already enabled'
+ sig_add(&me.s, me.signal, _sigfunc, <void *>me)
+ me._enabled()
+ return me
+ def disable(me):
+ if not me._activep:
+ raise ValueError, 'already disabled'
+ sig_remove(&me.s)
+ me._disabled()
+ return me
+ cdef _enabled(me):
+ me._activep = 1
+ me.enabled()
+ cdef _disabled(me):
+ me._activep = 0
+ me.disabled()
+ def enabled(me):
+ pass
+ def disabled(me):
+ pass
+ def signalled(me):
+ return _maybecall(me._signalled, ())
+
+cdef void _sigfunc(int sig, void *arg):
+ cdef SelSignal s
+ s = <SelSignal>arg
+ s.signalled()
+
+sig_init(&_sel)
+
+#----- That's all, folks ----------------------------------------------------
# along with mLib/Python; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-cdef extern from 'mLib/sym.h':
- ctypedef struct sym_table:
- pass
- ctypedef struct sym_base:
- pass
- ctypedef struct sym_iter:
- pass
- void sym_create(sym_table *t)
- void sym_destroy(sym_table *t)
- void *sym_find(sym_table *t, char *n, long l, int sz, unsigned *f)
- void sym_remove(sym_table *t, void *b)
- char *SYM_NAME(void *b)
- int SYM_LEN(void *b)
- void sym_mkiter(sym_iter *i, sym_table *t)
- void *sym_next(sym_iter *i)
-
-cdef extern from 'grim.h':
- int PSIZEOF(void *p)
-
-cdef extern from 'Python.h':
- int PyObject_AsReadBuffer(obj, void **buf, int *len) except -1
- PyString_FromStringAndSize(char *p, int n)
- ctypedef struct PyObject:
- pass
- void Py_INCREF(PyObject *obj)
- void Py_DECREF(PyObject *obj)
-
-cdef struct entry:
+cdef struct _sym_entry:
sym_base _b
PyObject *v
-cdef entry *_find(sym_table *t, object k, unsigned *f) except ?NULL:
- cdef void *p
- cdef int n
- cdef entry *e
- PyObject_AsReadBuffer(key, &p, &n)
- if f:
- f[0] = 0
- e = <entry *>sym_find(t, <char *>p, n, PSIZEOF(e), f)
- if not f[0]:
- e.v = NULL
- else:
- e = <entry *>sym_find(t, <char *>p, n, 0, NULL)
- return e
-
-cdef _eget(entry *e):
- Py_INCREF(e.v)
- return <object>e.v
-
-cdef void _eset(entry *e, v):
- if e.v:
- Py_DECREF(e.v)
- e.v = <PyObject *>v
- Py_INCREF(e.v)
-
-cdef void _edel(sym_table *t, entry *e):
- if e.v:
- Py_DECREF(e.v)
- sym_remove(t, <void *>e)
-
-cdef _key(entry *e):
- return PyString_FromStringAndSize(SYM_NAME(<void *>e), SYM_LEN(<void *>e))
-
-cdef class Table:
+cdef class SymTable (Mapping):
cdef sym_table _t
- def __new__(me, *hunoz, **hukairz):
+ cdef int _init(me) except -1:
sym_create(&me._t)
- def __init__(me, stuff = None, **kw):
- me.update(stuff, kw)
- def __getitem__(me, key):
- cdef entry *e
- e = _find(&me._t, key, NULL)
- if not e:
- raise KeyError, key
- return _eget(e)
- def __setitem__(me, key, value):
- cdef unsigned f
- _eset(_find(&me._t, key, &f), value)
- def __delitem__(me, key):
- cdef entry *e
- cdef unsigned f
- e = _find(&me._t, key, &f)
- if not e:
- raise KeyError, key
- _edel(&me._t, e)
- def get(me, key, default = None):
- cdef entry *e
- e = _find(&me._t, key, NULL)
- if not e:
- return default
- return _eget(e)
- def setdefault(me, key, default = None):
- cdef entry *e
- cdef unsigned f
- e = _find(&me._t, key, &f)
+ return 0
+ cdef void *_find(me, object key, unsigned *f) except NULL:
+ cdef void *p
+ cdef int n
+ cdef _sym_entry *e
+ PyObject_AsReadBuffer(key, &p, &n)
if f:
- return _eget(e)
- else:
- _eset(e, default)
- return default
- def pop(me, key, default = None):
- cdef entry *e
- e = _find(&me._t, key, NULL)
- if not e:
- return default
- rc = _eget(e)
- _edel(&me._t, e)
- return rc
- def popitem(me):
- cdef entry *e
- cdef sym_iter i
- sym_mkiter(&i, &me._t)
- e = <entry *>sym_next(&i)
- if not e:
- raise ValueError, 'popitem(): table is empty'
- return _key(e), _eget(e)
- def keys(me):
- cdef sym_iter i
- cdef entry *e
- l = []
- sym_mkiter(&i, &me._t)
- while 1:
- e = <entry *>sym_next(&i)
- if not e:
- break
- l.append(_key(e))
- return l
- def values(me):
- cdef sym_iter i
- cdef entry *e
- l = []
- sym_mkiter(&i, &me._t)
- while 1:
- e = <entry *>sym_next(&i)
- if not e:
- break
- l.append(_eget(e))
- return l
- def items(me):
- cdef sym_iter i
- cdef entry *e
- l = []
- sym_mkiter(&i, &me._t)
- while 1:
- e = <entry *>sym_next(&i)
- if not e:
- break
- l.append((_key(e), _eget(e)))
- return l
- def clear(me):
- cdef sym_iter i
- cdef entry *e
- sym_mkiter(&i, &me._t)
- while 1:
- e = <entry *>sym_next(&i)
- if not e:
- break
- _edel(&me._t, e)
- return me
- def __dealloc__(me):
- cdef sym_iter i
- cdef entry *e
- sym_mkiter(&i, &me._t)
- while 1:
- e = <entry *>sym_next(&i)
- if not e:
- break
- _edel(&me._t, e)
- sym_destroy(&me._t)
- def iterkeys(me):
- return KeyIter(me)
- def __iter__(me):
- return KeyIter(me)
- def itervalues(me):
- return ValueIter(me)
- def iteritems(me):
- return ItemIter(me)
- def update(me, stuff = None, **kw):
- cdef unsigned f
- if stuff is None:
- pass
- elif hasattr(stuff, 'itemiter'):
- for k, v in stuff.itemiter:
- _eset(_find(&me._t, k, &f), v)
- elif hasattr(stuff, 'keys'):
- for k in stuff.keys():
- _eset(_find(&me._t, k, &f), stuff[k])
+ f[0] = 0
+ e = <_sym_entry *>sym_find(&me._t, <char *>p, n, PSIZEOF(e), f)
+ if not f[0]:
+ e.v = NULL
else:
- for k, v in stuff:
- _eset(_find(&me._t, k, &f), v)
- for k, v in kw.iteritems():
- _eset(_find(&me._t, k, &f), v)
- return me
-
-cdef class KeyIter:
- cdef Table _t
- cdef sym_iter _i
- def __new__(me, Table t):
- me._t = t
- sym_mkiter(&me._i, &t._t)
- def __iter__(me):
- return me
- def __next__(me):
- cdef entry *e
- e = <entry *>sym_next(&me._i)
- if not e:
- raise StopIteration
- return _key(e)
-
-cdef class ValueIter:
- cdef Table _t
- cdef sym_iter _i
- def __new__(me, Table t):
- me._t = t
- sym_mkiter(&me._i, &t._t)
- def __iter__(me):
- return me
- def __next__(me):
- cdef entry *e
- e = <entry *>sym_next(&me._i)
- if not e:
- raise StopIteration
- return _eget(e)
+ e = <_sym_entry *>sym_find(&me._t, <char *>p, n, 0, NULL)
+ return <void *>e
+ cdef object _key(me, void *e):
+ return PyString_FromStringAndSize(SYM_NAME(e), SYM_LEN(e))
+ cdef object _value(me, void *e):
+ cdef _sym_entry *ee
+ ee = <_sym_entry *>e
+ Py_INCREF(ee.v)
+ return <object>ee.v
+ cdef void _setval(me, void *e, object val):
+ cdef _sym_entry *ee
+ ee = <_sym_entry *>e
+ if ee.v:
+ Py_DECREF(ee.v)
+ ee.v = <PyObject *>v
+ Py_INCREF(ee.v)
+ cdef void _del(me, void *e):
+ cdef _sym_entry *ee
+ ee = <_sym_entry *>e
+ if ee.v:
+ Py_DECREF(ee.v)
+ sym_remove(&me._t, <void *>ee)
+ cdef _MapIterator _iter(me):
+ return _SymIter(me)
-cdef class ItemIter:
- cdef Table _t
- cdef sym_iter _i
- def __new__(me, Table t):
- me._t = t
- sym_mkiter(&me._i, &t._t)
- def __iter__(me):
- return me
- def __next__(me):
- cdef entry *e
- e = <entry *>sym_next(&me._i)
- if not e:
- raise StopIteration
- return _key(e), _eget(e)
+cdef class _SymIter (_MapIterator):
+ cdef SymTable t
+ cdef sym_iter i
+ def __new__(me, SymTable t):
+ me.t = t
+ sym_mkiter(&me.i, &me.t._t)
+ cdef void *_next(me):
+ return sym_next(&me.i)
#----- That's all, folks ----------------------------------------------------
# along with mLib/Python; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-cdef extern from 'mLib/unihash.h':
- ctypedef int uint32
- ctypedef struct unihash_info:
- pass
- void unihash_setkey(unihash_info *i, uint32 k)
- uint32 UNIHASH_INIT(unihash_info *i)
- uint32 unihash_hash(unihash_info *i, uint32 a, void *p, int sz)
- unihash_info unihash_global
-
-cdef extern from 'limits.h':
- enum:
- LONG_MAX
-
-cdef extern from 'Python.h':
- int PyObject_AsReadBuffer(obj, void **buf, int *len) except -1
- PyInt_FromLong(long i)
- PyLong_FromUnsignedLong(unsigned long i)
-
-cdef _u32(uint32 x):
- if x < LONG_MAX:
- return PyInt_FromLong(x)
- else:
- return PyLong_FromUnsignedLong(x)
-
def setglobalkey(uint32 k):
unihash_setkey(&unihash_global, k)
--- /dev/null
+# -*-pyrex-*-
+#
+# $Id$
+#
+# Miscellaneous support gubbins
+#
+# (c) 2005 Straylight/Edgeware
+#
+
+#----- Licensing notice -----------------------------------------------------
+#
+# This file is part of the Python interface to mLib.
+#
+# mLib/Python is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# mLib/Python is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with mLib/Python; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+cdef object _u32(uint32 x):
+ if x < LONG_MAX:
+ return PyInt_FromLong(x)
+ else:
+ return PyLong_FromUnsignedLong(x)
+
+cdef object _oserror():
+ raise OSError, (errno, strerror(errno))
+
+cdef object _tobool(int i):
+ if i:
+ return True
+ else:
+ return False
+
+cdef int _getfd(object fdobj):
+ try:
+ return fdobj
+ except TypeError:
+ return fdobj.fileno()
+
+cdef object _checkcallable(f, what):
+ if f is not None and not callable(f):
+ raise TypeError, '%s must be callable' % what
+ return f
+
+cdef object _maybecall(f, args):
+ if f is None:
+ return None
+ return f(*args)
+
+#----- That's all, folks ----------------------------------------------------