##// END OF EJS Templates
diffhelpers.c: Added support for py3k....
Renato Cunha -
r11363:f5010303 default
parent child Browse files
Show More
@@ -1,161 +1,190
1 1 /*
2 2 * diffhelpers.c - helper routines for mpatch
3 3 *
4 4 * Copyright 2007 Chris Mason <chris.mason@oracle.com>
5 5 *
6 6 * This software may be used and distributed according to the terms
7 7 * of the GNU General Public License v2, incorporated herein by reference.
8 8 */
9 9
10 10 #include <Python.h>
11 11 #include <stdlib.h>
12 12 #include <string.h>
13 13
14 #include "util.h"
15
14 16 static char diffhelpers_doc[] = "Efficient diff parsing";
15 17 static PyObject *diffhelpers_Error;
16 18
17 19
18 20 /* fixup the last lines of a and b when the patch has no newline at eof */
19 21 static void _fix_newline(PyObject *hunk, PyObject *a, PyObject *b)
20 22 {
21 23 int hunksz = PyList_Size(hunk);
22 24 PyObject *s = PyList_GET_ITEM(hunk, hunksz-1);
23 char *l = PyString_AS_STRING(s);
25 char *l = PyBytes_AsString(s);
24 26 int alen = PyList_Size(a);
25 27 int blen = PyList_Size(b);
26 28 char c = l[0];
27 29 PyObject *hline;
28 int sz = PyString_GET_SIZE(s);
30 int sz = PyBytes_GET_SIZE(s);
29 31
30 32 if (sz > 1 && l[sz-2] == '\r')
31 33 /* tolerate CRLF in last line */
32 34 sz -= 1;
33 hline = PyString_FromStringAndSize(l, sz-1);
35
36 hline = PyBytes_FromStringAndSize(l, sz-1);
34 37
35 38 if (c == ' ' || c == '+') {
36 PyObject *rline = PyString_FromStringAndSize(l + 1, sz - 2);
39 PyObject *rline = PyBytes_FromStringAndSize(l + 1, sz - 2);
37 40 PyList_SetItem(b, blen-1, rline);
38 41 }
39 42 if (c == ' ' || c == '-') {
40 43 Py_INCREF(hline);
41 44 PyList_SetItem(a, alen-1, hline);
42 45 }
43 46 PyList_SetItem(hunk, hunksz-1, hline);
44 47 }
45 48
46 49 /* python callable form of _fix_newline */
47 50 static PyObject *
48 51 fix_newline(PyObject *self, PyObject *args)
49 52 {
50 53 PyObject *hunk, *a, *b;
51 54 if (!PyArg_ParseTuple(args, "OOO", &hunk, &a, &b))
52 55 return NULL;
53 56 _fix_newline(hunk, a, b);
54 57 return Py_BuildValue("l", 0);
55 58 }
56 59
57 60 /*
58 61 * read lines from fp into the hunk. The hunk is parsed into two arrays
59 62 * a and b. a gets the old state of the text, b gets the new state
60 63 * The control char from the hunk is saved when inserting into a, but not b
61 64 * (for performance while deleting files)
62 65 */
63 66 static PyObject *
64 67 addlines(PyObject *self, PyObject *args)
65 68 {
66 69
67 70 PyObject *fp, *hunk, *a, *b, *x;
68 71 int i;
69 72 int lena, lenb;
70 73 int num;
71 74 int todoa, todob;
72 75 char *s, c;
73 76 PyObject *l;
74 77 if (!PyArg_ParseTuple(args, "OOiiOO", &fp, &hunk, &lena, &lenb, &a, &b))
75 78 return NULL;
76 79
77 80 while (1) {
78 81 todoa = lena - PyList_Size(a);
79 82 todob = lenb - PyList_Size(b);
80 83 num = todoa > todob ? todoa : todob;
81 84 if (num == 0)
82 85 break;
83 86 for (i = 0; i < num; i++) {
84 87 x = PyFile_GetLine(fp, 0);
85 s = PyString_AS_STRING(x);
88 s = PyBytes_AsString(x);
86 89 c = *s;
87 90 if (strcmp(s, "\\ No newline at end of file\n") == 0) {
88 91 _fix_newline(hunk, a, b);
89 92 continue;
90 93 }
91 94 if (c == '\n') {
92 95 /* Some patches may be missing the control char
93 96 * on empty lines. Supply a leading space. */
94 97 Py_DECREF(x);
95 x = PyString_FromString(" \n");
98 x = PyBytes_FromString(" \n");
96 99 }
97 100 PyList_Append(hunk, x);
98 101 if (c == '+') {
99 l = PyString_FromString(s + 1);
102 l = PyBytes_FromString(s + 1);
100 103 PyList_Append(b, l);
101 104 Py_DECREF(l);
102 105 } else if (c == '-') {
103 106 PyList_Append(a, x);
104 107 } else {
105 l = PyString_FromString(s + 1);
108 l = PyBytes_FromString(s + 1);
106 109 PyList_Append(b, l);
107 110 Py_DECREF(l);
108 111 PyList_Append(a, x);
109 112 }
110 113 Py_DECREF(x);
111 114 }
112 115 }
113 116 return Py_BuildValue("l", 0);
114 117 }
115 118
116 119 /*
117 120 * compare the lines in a with the lines in b. a is assumed to have
118 121 * a control char at the start of each line, this char is ignored in the
119 122 * compare
120 123 */
121 124 static PyObject *
122 125 testhunk(PyObject *self, PyObject *args)
123 126 {
124 127
125 128 PyObject *a, *b;
126 129 long bstart;
127 130 int alen, blen;
128 131 int i;
129 132 char *sa, *sb;
130 133
131 134 if (!PyArg_ParseTuple(args, "OOl", &a, &b, &bstart))
132 135 return NULL;
133 136 alen = PyList_Size(a);
134 137 blen = PyList_Size(b);
135 138 if (alen > blen - bstart) {
136 139 return Py_BuildValue("l", -1);
137 140 }
138 141 for (i = 0; i < alen; i++) {
139 sa = PyString_AS_STRING(PyList_GET_ITEM(a, i));
140 sb = PyString_AS_STRING(PyList_GET_ITEM(b, i + bstart));
142 sa = PyBytes_AsString(PyList_GET_ITEM(a, i));
143 sb = PyBytes_AsString(PyList_GET_ITEM(b, i + bstart));
141 144 if (strcmp(sa + 1, sb) != 0)
142 145 return Py_BuildValue("l", -1);
143 146 }
144 147 return Py_BuildValue("l", 0);
145 148 }
146 149
147 150 static PyMethodDef methods[] = {
148 151 {"addlines", addlines, METH_VARARGS, "add lines to a hunk\n"},
149 152 {"fix_newline", fix_newline, METH_VARARGS, "fixup newline counters\n"},
150 153 {"testhunk", testhunk, METH_VARARGS, "test lines in a hunk\n"},
151 154 {NULL, NULL}
152 155 };
153 156
157 #ifdef IS_PY3K
158 static struct PyModuleDef diffhelpers_module = {
159 PyModuleDef_HEAD_INIT,
160 "diffhelpers",
161 diffhelpers_doc,
162 -1,
163 methods
164 };
165
166 PyMODINIT_FUNC PyInit_diffhelpers(void)
167 {
168 PyObject *m;
169
170 m = PyModule_Create(&diffhelpers_module);
171 if (m == NULL)
172 return NULL;
173
174 diffhelpers_Error = PyErr_NewException("diffhelpers.diffhelpersError",
175 NULL, NULL);
176 Py_INCREF(diffhelpers_Error);
177 PyModule_AddObject(m, "diffhelpersError", diffhelpers_Error);
178
179 return m;
180 }
181 #else
154 182 PyMODINIT_FUNC
155 183 initdiffhelpers(void)
156 184 {
157 185 Py_InitModule3("diffhelpers", methods, diffhelpers_doc);
158 186 diffhelpers_Error = PyErr_NewException("diffhelpers.diffhelpersError",
159 187 NULL, NULL);
160 188 }
189 #endif
161 190
General Comments 0
You need to be logged in to leave comments. Login now