|
@@ -0,0 +1,181 @@
|
|
|
|
+#define PY_SSIZE_T_CLEAN
|
|
|
|
+
|
|
|
|
+#include <Python.h>
|
|
|
|
+#include <structmember.h>
|
|
|
|
+
|
|
|
|
+#include "term.h"
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+typedef struct {
|
|
|
|
+ PyObject_HEAD
|
|
|
|
+ LSUP_Term * ob_struct;
|
|
|
|
+} TermObject;
|
|
|
|
+
|
|
|
|
+static PyModuleDef termmodule = {
|
|
|
|
+ PyModuleDef_HEAD_INIT,
|
|
|
|
+ .m_name = "term",
|
|
|
|
+ .m_doc = "RDF term module.",
|
|
|
|
+ .m_size = -1,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+static int
|
|
|
|
+Term_init (TermObject *self, PyObject *args, PyObject *kwargs)
|
|
|
|
+{
|
|
|
|
+ LSUP_term_type term_type;
|
|
|
|
+ char *data = NULL, *datatype = NULL, *lang = NULL;
|
|
|
|
+
|
|
|
|
+ static char *kwlist[] = {"data", "datatype", "lang", NULL};
|
|
|
|
+
|
|
|
|
+ if (!PyArg_ParseTupleAndKeywords (
|
|
|
|
+ args, kwargs, "bs|ss", kwlist,
|
|
|
|
+ &term_type, &data, &datatype, &lang))
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ self->ob_struct = LSUP_term_new (term_type, data, datatype, lang);
|
|
|
|
+ if (!self->ob_struct) {
|
|
|
|
+ PyErr_SetString (PyExc_ValueError, "Could not create term.");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void
|
|
|
|
+Term_dealloc (TermObject *self)
|
|
|
|
+{
|
|
|
|
+ LSUP_term_free (self->ob_struct);
|
|
|
|
+ Py_TYPE (self)->tp_free ((PyObject *) self);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+static PyObject *
|
|
|
|
+Term_get_type (TermObject *self)
|
|
|
|
+{
|
|
|
|
+ PyObject *type = PyLong_FromSize_t ((size_t)self->ob_struct->type);
|
|
|
|
+ Py_INCREF (type);
|
|
|
|
+
|
|
|
|
+ return type;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+static PyObject *
|
|
|
|
+Term_get_data (TermObject *self)
|
|
|
|
+{
|
|
|
|
+ PyObject *data = PyUnicode_FromString (self->ob_struct->data);
|
|
|
|
+ Py_INCREF (data);
|
|
|
|
+
|
|
|
|
+ return data;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+static PyObject *
|
|
|
|
+Term_get_datatype (TermObject *self)
|
|
|
|
+{
|
|
|
|
+ if (!self->ob_struct->datatype) Py_RETURN_NONE;
|
|
|
|
+
|
|
|
|
+ PyObject *datatype = PyUnicode_FromString (self->ob_struct->datatype);
|
|
|
|
+ Py_INCREF (datatype);
|
|
|
|
+
|
|
|
|
+ return datatype;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static PyObject *
|
|
|
|
+Term_get_lang (TermObject *self)
|
|
|
|
+{
|
|
|
|
+ if (
|
|
|
|
+ !self->ob_struct->datatype || !self->ob_struct->lang ||
|
|
|
|
+ strlen (self->ob_struct->lang) == 0)
|
|
|
|
+ Py_RETURN_NONE;
|
|
|
|
+
|
|
|
|
+ PyObject *lang = PyUnicode_FromString (self->ob_struct->lang);
|
|
|
|
+ Py_INCREF (lang);
|
|
|
|
+
|
|
|
|
+ return lang;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+static PyGetSetDef Term_getsetters[] = {
|
|
|
|
+ {"type", (getter) Term_get_type, NULL, "Term type.", NULL},
|
|
|
|
+ {"data", (getter) Term_get_data, NULL, "Term data.", NULL},
|
|
|
|
+ {
|
|
|
|
+ "datatype", (getter) Term_get_datatype,
|
|
|
|
+ NULL, "Literal term data type.", NULL
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ "lang", (getter) Term_get_lang,
|
|
|
|
+ NULL, "Literal term language tag.", NULL
|
|
|
|
+ },
|
|
|
|
+ {NULL}
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+static PyTypeObject TermType = {
|
|
|
|
+ PyVarObject_HEAD_INIT(NULL, 0)
|
|
|
|
+ .tp_name = "term.Term",
|
|
|
|
+ .tp_doc = "RDF term",
|
|
|
|
+ .tp_basicsize = sizeof(TermObject),
|
|
|
|
+ .tp_itemsize = 0,
|
|
|
|
+ .tp_flags = Py_TPFLAGS_DEFAULT,
|
|
|
|
+ .tp_new = PyType_GenericNew,
|
|
|
|
+ .tp_init = (initproc) Term_init,
|
|
|
|
+ .tp_dealloc = (destructor) Term_dealloc,
|
|
|
|
+ .tp_getset = Term_getsetters,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+static PyObject *
|
|
|
|
+Term_richcmp (PyObject *obj1, PyObject *obj2, int op)
|
|
|
|
+{
|
|
|
|
+ PyObject *result = NULL;
|
|
|
|
+
|
|
|
|
+ if (
|
|
|
|
+ ! PyObject_TypeCheck (obj1, &TermType) ||
|
|
|
|
+ ! PyObject_TypeCheck (obj2, &TermType)
|
|
|
|
+ ) return NULL;
|
|
|
|
+
|
|
|
|
+ int c = 0;
|
|
|
|
+ LSUP_Term *t1 = ((TermObject *) obj1)->ob_struct;
|
|
|
|
+ LSUP_Term *t2 = ((TermObject *) obj2)->ob_struct;
|
|
|
|
+
|
|
|
|
+ switch (op) {
|
|
|
|
+ case Py_LT: result = Py_NotImplemented; break;
|
|
|
|
+ case Py_LE: result = Py_NotImplemented; break;
|
|
|
|
+ case Py_EQ: c = LSUP_term_equals (t1, t2); break;
|
|
|
|
+ case Py_NE: c = ! LSUP_term_equals (t1, t2); break;
|
|
|
|
+ case Py_GT: result = Py_NotImplemented; break;
|
|
|
|
+ case Py_GE: result = Py_NotImplemented; break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!result) result = c ? Py_True : Py_False;
|
|
|
|
+
|
|
|
|
+ Py_INCREF(result);
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+PyMODINIT_FUNC
|
|
|
|
+PyInit_term(void)
|
|
|
|
+{
|
|
|
|
+ if (PyType_Ready (&TermType) < 0) return NULL;
|
|
|
|
+
|
|
|
|
+ PyObject *m = PyModule_Create(&termmodule);
|
|
|
|
+ if (m == NULL) return NULL;
|
|
|
|
+
|
|
|
|
+#define ENTRY(a, b) \
|
|
|
|
+ if (PyModule_AddIntConstant (m, "TERM_" #a, b) < 0) return NULL;
|
|
|
|
+ TTYPE_TABLE
|
|
|
|
+#undef ENTRY
|
|
|
|
+
|
|
|
|
+ TermType.tp_richcompare = Term_richcmp;
|
|
|
|
+
|
|
|
|
+ Py_INCREF(&TermType);
|
|
|
|
+ if (PyModule_AddObject(m, "Term", (PyObject *) &TermType) < 0) {
|
|
|
|
+ Py_DECREF(&TermType);
|
|
|
|
+ Py_DECREF(m);
|
|
|
|
+ return NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return m;
|
|
|
|
+}
|