diff --git a/src/runtime/python/ffi.c b/src/runtime/python/ffi.c index 3d7ec5598..d49515ddb 100644 --- a/src/runtime/python/ffi.c +++ b/src/runtime/python/ffi.c @@ -58,7 +58,7 @@ PgfTypeHypo * PyList_AsHypos(PyObject *pylist, Py_ssize_t *n_hypos) { if (!PyList_Check(pylist)) { - PyErr_SetString(PyExc_TypeError, "PyList_AsHypos: must be a list"); + PyErr_SetString(PyExc_TypeError, "hypos must be a list"); return NULL; } Py_ssize_t n = PyList_Size(pylist); @@ -66,29 +66,29 @@ PyList_AsHypos(PyObject *pylist, Py_ssize_t *n_hypos) PgfTypeHypo *hypos = PyMem_Malloc(sizeof(PgfTypeHypo)*n); for (Py_ssize_t i = 0; i < n; i++) { - PyObject *hytup = PyList_GetItem(pylist, i); - if (!PyTuple_Check(hytup)) { - PyErr_SetString(PyExc_TypeError, "PyList_AsHypos: item must be a tuple"); + PyObject *tup = PyList_GetItem(pylist, i); + if (!PyTuple_Check(tup)) { + PyErr_SetString(PyExc_TypeError, "hypo must be a tuple"); return NULL; } - PyObject *t0 = PyTuple_GetItem(hytup, 0); + PyObject *t0 = PyTuple_GetItem(tup, 0); if (!PyLong_Check(t0)) { - PyErr_SetString(PyExc_TypeError, "PyList_AsHypos: first element must be an integer"); + PyErr_SetString(PyExc_TypeError, "first element of hypo must be an integer"); return NULL; } hypos[i].bind_type = PyLong_AsLong(t0); - PyObject *t1 = PyTuple_GetItem(hytup, 1); + PyObject *t1 = PyTuple_GetItem(tup, 1); if (!PyUnicode_Check(t1)) { - PyErr_SetString(PyExc_TypeError, "PyList_AsHypos: second element must be a string"); + PyErr_SetString(PyExc_TypeError, "second element of hypo must be a string"); return NULL; } hypos[i].cid = PyUnicode_AsPgfText(t1); - PyObject *t2 = PyTuple_GetItem(hytup, 2); + PyObject *t2 = PyTuple_GetItem(tup, 2); if (!PyObject_TypeCheck(t2, &pgf_TypeType)) { - PyErr_SetString(PyExc_TypeError, "PyList_AsHypos: third element must be a Type"); + PyErr_SetString(PyExc_TypeError, "third element of hypo must be a Type"); return NULL; } hypos[i].type = (PgfType) t2; @@ -247,7 +247,6 @@ dtyp(PgfUnmarshaller *this, int n_hypos, PgfTypeHypo *hypos, PgfText *cat, int n static void free_ref(PgfUnmarshaller *this, object x) { - // Py_XDECREF(x); } static PgfUnmarshallerVtbl unmarshallerVtbl = diff --git a/src/runtime/python/pypgf.c b/src/runtime/python/pypgf.c index eeb76f7d5..ff94b1292 100644 --- a/src/runtime/python/pypgf.c +++ b/src/runtime/python/pypgf.c @@ -353,6 +353,9 @@ static PyMethodDef PGF_methods[] = { "Returns the probability of a function" }, + {"checkoutBranch", (PyCFunction)PGF_checkoutBranch, METH_VARARGS, + "Switch to a branch" + }, {"newTransaction", (PyCFunction)PGF_newTransaction, METH_VARARGS, "Create new transaction" }, diff --git a/src/runtime/python/transactions.c b/src/runtime/python/transactions.c index 64f1bda01..7625856a1 100644 --- a/src/runtime/python/transactions.c +++ b/src/runtime/python/transactions.c @@ -7,6 +7,35 @@ #include "./ffi.h" #include "./transactions.h" +PyObject * +PGF_checkoutBranch(PGFObject *self, PyObject *args) +{ + const char *s = NULL; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "s#", &s, &size)) + return NULL; + + PgfText *name = (PgfText *)PyMem_RawMalloc(sizeof(PgfText)+size+1); + memcpy(name->text, s, size+1); + name->size = size; + + PgfExn err; + PgfRevision rev = pgf_checkout_revision(self->db, name, &err); + PyMem_RawFree(name); + if (handleError(err) != PGF_EXN_NONE) { + return NULL; + } + if (rev == 0) { + // is this possible? + PyErr_SetString(PyExc_KeyError, "unknown branch name"); + return NULL; + } + + self->revision = rev; + + Py_RETURN_TRUE; +} + TransactionObject * PGF_newTransaction(PGFObject *self, PyObject *args) { @@ -49,7 +78,7 @@ Transaction_commit(TransactionObject *self, PyObject *args) pgf_free_revision(self->pgf->db, self->pgf->revision); self->pgf->revision = self->revision; - Py_INCREF(self->pgf->db); + Py_INCREF(self->pgf); Py_RETURN_NONE; } diff --git a/src/runtime/python/transactions.h b/src/runtime/python/transactions.h index d72835425..186ff1eda 100644 --- a/src/runtime/python/transactions.h +++ b/src/runtime/python/transactions.h @@ -14,6 +14,9 @@ typedef struct { PyTypeObject pgf_TransactionType; +PyObject * +PGF_checkoutBranch(PGFObject *self, PyObject *args); + TransactionObject * PGF_newTransaction(PGFObject *self, PyObject *args);