X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/mLib-python/blobdiff_plain/20bce5e92b01cd928f26b61be78215117039c561..376ad06df03e59ebf0796b2f475417150e82252d:/atom.pyx diff --git a/atom.pyx b/atom.pyx index 8fac74c..9892ba5 100644 --- a/atom.pyx +++ b/atom.pyx @@ -15,60 +15,19 @@ # 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 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 __cinit__(me): atom_mkiter(&me._i, ATOM_GLOBAL) def __next__(me): cdef atom *a @@ -82,215 +41,4 @@ cdef class AtomIter: 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 = assoc_find(t, a, PSIZEOF(e), f) - if not f[0]: - e.v = NULL - else: - e = assoc_find(t, a, 0, NULL) - return e - -cdef _key(entry *e): - return atom_pywrap(ASSOC_ATOM(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(assoc_table *t, entry *e): - if e.v: - Py_DECREF(e.v) - assoc_remove(t, 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = assoc_next(&me._i) - if not e: - raise StopIteration - return _key(e), _eget(e) - -Atom = atom_pystartup() - #----- That's all, folks ----------------------------------------------------