comparison 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
comparison
equal deleted inserted replaced
29693:b9b9f9a92481 29694:55dd12204b8e
31 #include "mpatch.h" 31 #include "mpatch.h"
32 32
33 static char mpatch_doc[] = "Efficient binary patching."; 33 static char mpatch_doc[] = "Efficient binary patching.";
34 static PyObject *mpatch_Error; 34 static PyObject *mpatch_Error;
35 35
36 struct mpatch_flist *cpygetitem(void *bins, ssize_t pos)
37 {
38 const char *buffer;
39 struct mpatch_flist *res;
40 ssize_t blen;
41 int r;
42
43 PyObject *tmp = PyList_GetItem((PyObject*)bins, pos);
44 if (!tmp)
45 return NULL;
46 if (PyObject_AsCharBuffer(tmp, &buffer, (Py_ssize_t*)&blen))
47 return NULL;
48 if ((r = mpatch_decode(buffer, blen, &res)) < 0) {
49 if (!PyErr_Occurred())
50 PyErr_SetString(mpatch_Error, mpatch_errors[-r]);
51 return NULL;
52 }
53 return res;
54 }
55
36 static PyObject * 56 static PyObject *
37 patches(PyObject *self, PyObject *args) 57 patches(PyObject *self, PyObject *args)
38 { 58 {
39 PyObject *text, *bins, *result; 59 PyObject *text, *bins, *result;
40 struct mpatch_flist *patch; 60 struct mpatch_flist *patch;
41 const char *in; 61 const char *in;
62 int r;
42 char *out; 63 char *out;
43 Py_ssize_t len, outlen, inlen; 64 Py_ssize_t len, outlen, inlen;
44 65
45 if (!PyArg_ParseTuple(args, "OO:mpatch", &text, &bins)) 66 if (!PyArg_ParseTuple(args, "OO:mpatch", &text, &bins))
46 return NULL; 67 return NULL;
53 } 74 }
54 75
55 if (PyObject_AsCharBuffer(text, &in, &inlen)) 76 if (PyObject_AsCharBuffer(text, &in, &inlen))
56 return NULL; 77 return NULL;
57 78
58 patch = mpatch_fold(bins, 0, len); 79 patch = mpatch_fold(bins, cpygetitem, 0, len);
59 if (!patch) 80 if (!patch) { /* error already set or memory error */
81 if (!PyErr_Occurred())
82 PyErr_NoMemory();
60 return NULL; 83 return NULL;
84 }
61 85
62 outlen = mpatch_calcsize(inlen, patch); 86 outlen = mpatch_calcsize(inlen, patch);
63 if (outlen < 0) { 87 if (outlen < 0) {
88 r = (int)outlen;
64 result = NULL; 89 result = NULL;
65 goto cleanup; 90 goto cleanup;
66 } 91 }
67 result = PyBytes_FromStringAndSize(NULL, outlen); 92 result = PyBytes_FromStringAndSize(NULL, outlen);
68 if (!result) { 93 if (!result) {
69 result = NULL; 94 result = NULL;
70 goto cleanup; 95 goto cleanup;
71 } 96 }
72 out = PyBytes_AsString(result); 97 out = PyBytes_AsString(result);
73 if (!mpatch_apply(out, in, inlen, patch)) { 98 if ((r = mpatch_apply(out, in, inlen, patch)) < 0) {
74 Py_DECREF(result); 99 Py_DECREF(result);
75 result = NULL; 100 result = NULL;
76 } 101 }
77 cleanup: 102 cleanup:
78 mpatch_lfree(patch); 103 mpatch_lfree(patch);
104 if (!result && !PyErr_Occurred())
105 PyErr_SetString(mpatch_Error, mpatch_errors[-r]);
79 return result; 106 return result;
80 } 107 }
81 108
82 /* calculate size of a patched file directly */ 109 /* calculate size of a patched file directly */
83 static PyObject * 110 static PyObject *