|
|
- #include "Python.h"
- #include "structmember.h"
-
- PyDoc_STRVAR(istr__doc__, "istr class implementation");
-
- /* We link this module statically for convenience. If compiled as a shared
- library instead, some compilers don't allow addresses of Python objects
- defined in other libraries to be used in static initializers here. The
- DEFERRED_ADDRESS macro is used to tag the slots where such addresses
- appear; the module init function must fill in the tagged slots at runtime.
- The argument is for documentation -- the macro ignores it.
- */
- #define DEFERRED_ADDRESS(ADDR) 0
-
-
- typedef struct {
- PyUnicodeObject str;
- PyObject * canonical;
- } istrobject;
-
- typedef struct {
- PyObject *title;
- PyObject *emptystr;
- PyObject *emptydict;
- } ModData;
-
- static struct PyModuleDef _istrmodule;
- static PyTypeObject istr_type;
-
- static ModData *
- modstate(PyObject *mod)
- {
- return (ModData*)PyModule_GetState(mod);
- }
-
- static ModData *
- global_state(void)
- {
- return modstate(PyState_FindModule(&_istrmodule));
- }
-
-
-
- static PyObject *
- istr_title(istrobject *self, PyObject *args)
- {
- if (!PyArg_ParseTuple(args, ":title"))
- return NULL;
- Py_INCREF(self);
- return (PyObject*)self;
- }
-
- static PyObject *
- istr_str(istrobject *self)
- {
- Py_INCREF(self->canonical);
- return self->canonical;
- }
-
- static PyMethodDef istr_methods[] = {
- {"title", (PyCFunction)istr_title, METH_VARARGS,
- PyDoc_STR("title()")},
- {NULL, NULL},
- };
-
-
- void istr_dealloc(istrobject *self)
- {
- Py_XDECREF(self->canonical);
- PyUnicode_Type.tp_dealloc((PyObject*)self);
- }
-
- static PyObject *
- istr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
- {
- PyObject *x = NULL;
- static char *kwlist[] = {"object", "encoding", "errors", 0};
- char *encoding = NULL;
- char *errors = NULL;
- PyObject *s = NULL;
- PyObject *tmp = NULL;
- PyObject * new_args = NULL;
- PyObject * ret = NULL;
-
- ModData * state = global_state();
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:str",
- kwlist, &x, &encoding, &errors))
- return NULL;
- if (x == NULL) {
- s = state->emptystr;
- Py_INCREF(s);
- }
- else if (PyObject_IsInstance(x, (PyObject*)&istr_type)) {
- Py_INCREF(x);
- return x;
- }
- else {
- if (encoding == NULL && errors == NULL) {
- tmp = PyObject_Str(x);
- } else {
- tmp = PyUnicode_FromEncodedObject(x, encoding, errors);
- }
- if (!tmp) {
- goto finish;
- }
- s = PyObject_CallMethodObjArgs(tmp, state->title, NULL);
- }
- if (!s)
- goto finish;
-
- new_args = PyTuple_Pack(1, s);
- if (!new_args) {
- goto finish;
- }
- ret = PyUnicode_Type.tp_new(type, new_args, state->emptydict);
- if (!ret) {
- goto finish;
- }
- ((istrobject*)ret)->canonical = s;
- s = NULL; /* the reference is stollen by .canonical */
- finish:
- Py_XDECREF(tmp);
- Py_XDECREF(s);
- Py_XDECREF(new_args);
- return ret;
- }
-
- static PyTypeObject istr_type = {
- PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
- "multidict._istr.istr",
- sizeof(istrobject),
- 0,
- (destructor)istr_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_reserved */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- (reprfunc)istr_str, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_UNICODE_SUBCLASS,
- /* tp_flags */
- 0, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- istr_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- DEFERRED_ADDRESS(&PyUnicode_Type), /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- (newfunc)istr_new, /* tp_new */
- };
-
-
- static int mod_clear(PyObject *m)
- {
- Py_CLEAR(modstate(m)->title);
- Py_CLEAR(modstate(m)->emptystr);
- Py_CLEAR(modstate(m)->emptydict);
- return 0;
- }
-
-
- static struct PyModuleDef _istrmodule = {
- PyModuleDef_HEAD_INIT,
- "multidict._istr",
- istr__doc__,
- sizeof(ModData),
- NULL, /* m_methods */
- NULL, /* m_reload */
- NULL, /* m_traverse */
- mod_clear, /* m_clear */
- NULL /* m_free */
- };
-
-
- PyObject* PyInit__istr(void)
- {
- PyObject * tmp;
- PyObject *mod;
-
- mod = PyState_FindModule(&_istrmodule);
- if (mod) {
- Py_INCREF(mod);
- return mod;
- }
-
- istr_type.tp_base = &PyUnicode_Type;
- if (PyType_Ready(&istr_type) < 0) {
- return NULL;
- }
-
- mod = PyModule_Create(&_istrmodule);
- if (!mod) {
- return NULL;
- }
- tmp = PyUnicode_FromString("title");
- if (!tmp) {
- goto err;
- }
- modstate(mod)->title = tmp;
- tmp = PyUnicode_New(0, 0);
- if (!tmp) {
- goto err;
- }
- modstate(mod)->emptystr = tmp;
- tmp = PyUnicode_FromString("title");
- if(!tmp) {
- goto err;
- }
- modstate(mod)->title = tmp;
-
- Py_INCREF(&istr_type);
- if (PyModule_AddObject(mod, "istr", (PyObject *)&istr_type) < 0)
- goto err;
-
- return mod;
- err:
- Py_DECREF(mod);
- return NULL;
- }
|