X-Git-Url: https://git.distorted.org.uk/~mdw/pyke/blobdiff_plain/747ddb1b97d37fd57efae3c99c2bd188a14df308..4509276e7147042c753ec7180d1dd8e1f5923906:/pyke.h diff --git a/pyke.h b/pyke.h index 138a9fb..e6d465e 100644 --- a/pyke.h +++ b/pyke.h @@ -62,6 +62,18 @@ PRIVATE_SYMBOLS; +/*----- Python version compatibility hacks --------------------------------*/ + +/* The handy `Py_TYPE' and `Py_SIZE' macros turned up in 2.6. Define them if + * they're not already here. + */ +#ifndef Py_TYPE +# define Py_TYPE(obj) (((PyObject *)(obj))->ob_type) +#endif +#ifndef Py_SIZE +# define Py_SIZE(obj) (((PyVarObject *)(obj))->ob_size) +#endif + /*----- Utilities for returning values and exceptions ---------------------*/ /* Returning values. */ @@ -153,8 +165,7 @@ extern PyObject *getulong(unsigned long); /* any kind of unsigned integer */ /*----- Miscellaneous utilities -------------------------------------------*/ -#define FREEOBJ(obj) \ - (((PyObject *)(obj))->ob_type->tp_free((PyObject *)(obj))) +#define FREEOBJ(obj) (Py_TYPE(obj)->tp_free((PyObject *)(obj))) /* Actually free OBJ, e.g., in a deallocation function. */ extern PyObject *abstract_pynew(PyTypeObject *, PyObject *, PyObject *); @@ -321,6 +332,8 @@ extern PyObject *mkexc(PyObject */*mod*/, PyObject */*base*/, struct nameval { const char *name; unsigned f; unsigned long value; }; #define CF_SIGNED 1u extern void setconstants(PyObject *, const struct nameval *); +#define CONST(x) { #x, (x) >= 0 ? 0 : CF_SIGNED, x } +#define CONSTFLAG(f, x) { #x, f, x } #define INSEXC(name, var, base, meth) \ INSERT(name, var = mkexc(mod, base, name, meth)) @@ -369,6 +382,55 @@ extern PyMethodDef *donemethods(void); /*----- Generic mapping support -------------------------------------------*/ +/* Operations table. ME is the mapping object throughout. */ +typedef struct gmap_ops { + size_t isz; /* iterator size */ + + void *(*lookup)(PyObject *me, PyObject *key, unsigned *f); + /* Lookup the KEY. If it is found, return an entry pointer for it; if F + * is not null, set *F nonzero. Otherwise, if F is null, return a null + * pointer (without setting a pending exception); if F is not null, then + * set *F zero and return a fresh entry pointer. Return null on a Python + * exception (the caller will notice the difference.) + */ + + void (*iter_init)(PyObject *me, void *i); + /* Initialize an iterator at I. */ + + void *(*iter_next)(PyObject *me, void *i); + /* Return an entry pointer for a different item, or null if all have been + * visited. + */ + + PyObject *(*entry_key)(PyObject *me, void *e); + /* Return the key object for a mapping entry. */ + + PyObject *(*entry_value)(PyObject *me, void *e); + /* Return the value object for a mapping entry. */ + + int (*set_entry)(PyObject *me, void *e, PyObject *val); + /* Modify the entry by storing VAL in its place. Return 0 on success, + * or -1 on a Python error. + */ + + int (*del_entry)(PyObject *me, void *e); + /* Delete the entry. (It may be necessary to delete a freshly allocated + * entry, e.g., if `set_entry' failed.) Return 0 on success, or -1 on a + * Python error. + */ +} gmap_ops; + +/* The intrusion at the head of a mapping object. */ +#define GMAP_PYOBJ_HEAD \ + PyObject_HEAD \ + const gmap_ops *gmops; + +typedef struct gmap_pyobj { + GMAP_PYOBJ_HEAD +} gmap_pyobj; +#define GMAP_OPS(obj) (((gmap_pyobj *)(obj))->gmops) + /* Discover the operations from a mapping object. */ + /* Mapping methods. */ #define GMAP_METMNAME(func) gmapmeth_##func #define GMAP_METH(func, doc) STD_METHOD(GMAP_METMNAME, func, 0, doc) @@ -397,7 +459,7 @@ extern PyMethodDef *donemethods(void); KWMETH(setdefault, "D.setdefault(K, [default = None]) -> VALUE") \ KWMETH(pop, "D.pop(KEY, [default = ]) -> VALUE") \ NAMETH(popitem, "D.popitem() -> (KEY, VALUE)") \ - METH (update, "D.update(MAP)") + KWMETH(update, "D.update(MAP)") GMAP_DOMETHODS(GMAP_METHDECL, GMAP_KWMETHDECL, GMAP_NAMETHDECL) #define GMAP_ROMETHODS GMAP_DOROMETHODS(GMAP_METH, GMAP_KWMETH, GMAP_NAMETH) @@ -405,7 +467,12 @@ GMAP_DOMETHODS(GMAP_METHDECL, GMAP_KWMETHDECL, GMAP_NAMETHDECL) /* Mapping protocol implementation. */ extern Py_ssize_t gmap_pysize(PyObject *); /* for `mp_length' */ +extern PyObject *gmap_pyiter(PyObject *); /* for `tp_iter' */ +extern PyObject *gmap_pylookup(PyObject *, PyObject *); /* for `mp_subscript' */ +extern int gmap_pystore(PyObject *, PyObject *, PyObject *); /* for `mp_ass_subscript' */ +extern int gmap_pyhaskey(PyObject *, PyObject *); /* for `sq_contains' */ extern const PySequenceMethods gmap_pysequence; /* for `tp_as_sequence' */ +extern const PyMethodDef gmapro_pymethods[]; /* read-only methods */ extern const PyMethodDef gmap_pymethods[]; /* all the standard methods */ /*----- That's all, folks -------------------------------------------------*/