diff mercurial/mpatch_module.c @ 29694:55dd12204b8e

mpatch: remove dependency on Python.h in mpatch.c Now all the CPython-related stuff are referenced only from mpatch_module.c with mpatch.c being freely usable from a future cffi module
author Maciej Fijalkowski <fijall@gmail.com>
date Fri, 22 Jul 2016 17:28:05 +0200
parents b9b9f9a92481
children 21ac534d7d30
line wrap: on
line diff
--- a/mercurial/mpatch_module.c	Mon Jul 18 19:02:30 2016 +0200
+++ b/mercurial/mpatch_module.c	Fri Jul 22 17:28:05 2016 +0200
@@ -33,12 +33,33 @@
 static char mpatch_doc[] = "Efficient binary patching.";
 static PyObject *mpatch_Error;
 
+struct mpatch_flist *cpygetitem(void *bins, ssize_t pos)
+{
+	const char *buffer;
+	struct mpatch_flist *res;
+	ssize_t blen;
+	int r;
+
+	PyObject *tmp = PyList_GetItem((PyObject*)bins, pos);
+	if (!tmp)
+		return NULL;
+	if (PyObject_AsCharBuffer(tmp, &buffer, (Py_ssize_t*)&blen))
+		return NULL;
+	if ((r = mpatch_decode(buffer, blen, &res)) < 0) {
+		if (!PyErr_Occurred())
+			PyErr_SetString(mpatch_Error, mpatch_errors[-r]);
+ 		return NULL;
+	}
+	return res;
+}
+
 static PyObject *
 patches(PyObject *self, PyObject *args)
 {
 	PyObject *text, *bins, *result;
 	struct mpatch_flist *patch;
 	const char *in;
+	int r;
 	char *out;
 	Py_ssize_t len, outlen, inlen;
 
@@ -55,12 +76,16 @@
 	if (PyObject_AsCharBuffer(text, &in, &inlen))
 		return NULL;
 
-	patch = mpatch_fold(bins, 0, len);
-	if (!patch)
+	patch = mpatch_fold(bins, cpygetitem, 0, len);
+	if (!patch) { /* error already set or memory error */
+		if (!PyErr_Occurred())
+			PyErr_NoMemory();
 		return NULL;
+	}
 
 	outlen = mpatch_calcsize(inlen, patch);
 	if (outlen < 0) {
+		r = (int)outlen;
 		result = NULL;
 		goto cleanup;
 	}
@@ -70,12 +95,14 @@
 		goto cleanup;
 	}
 	out = PyBytes_AsString(result);
-	if (!mpatch_apply(out, in, inlen, patch)) {
+	if ((r = mpatch_apply(out, in, inlen, patch)) < 0) {
 		Py_DECREF(result);
 		result = NULL;
 	}
 cleanup:
 	mpatch_lfree(patch);
+	if (!result && !PyErr_Occurred())
+		PyErr_SetString(mpatch_Error, mpatch_errors[-r]);
 	return result;
 }