X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/mLib-python/blobdiff_plain/20bce5e92b01cd928f26b61be78215117039c561..26d9d0fb1d0ab596657f968425318456e45ea660:/sym.pyx diff --git a/sym.pyx b/sym.pyx index 4df3d9e..880d636 100644 --- a/sym.pyx +++ b/sym.pyx @@ -25,243 +25,58 @@ # 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 = sym_find(t, p, n, PSIZEOF(e), f) - if not f[0]: - e.v = NULL - else: - e = sym_find(t, p, n, 0, NULL) - return e - -cdef _eget(entry *e): - Py_INCREF(e.v) - return e.v - -cdef void _eset(entry *e, v): - if e.v: - Py_DECREF(e.v) - e.v = v - Py_INCREF(e.v) - -cdef void _edel(sym_table *t, entry *e): - if e.v: - Py_DECREF(e.v) - sym_remove(t, e) - -cdef _key(entry *e): - return PyString_FromStringAndSize(SYM_NAME(e), SYM_LEN(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 = 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 = 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 = 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 = 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 = 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 = 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, 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 = 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 = sym_next(&me._i) - if not e: - raise StopIteration - return _eget(e) + e = <_sym_entry *>sym_find(&me._t, p, n, 0, NULL) + return 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 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 = 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, 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 = 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 ----------------------------------------------------