mercurial/cext/bdiff.c
changeset 36146 29dd37a418aa
parent 36055 b4fdc6177b29
child 36620 186c6df3a373
equal deleted inserted replaced
36145:4f3e989536c3 36146:29dd37a418aa
   178 nomem:
   178 nomem:
   179 	PyMem_Free(w);
   179 	PyMem_Free(w);
   180 	return result ? result : PyErr_NoMemory();
   180 	return result ? result : PyErr_NoMemory();
   181 }
   181 }
   182 
   182 
       
   183 static bool sliceintolist(PyObject *list, Py_ssize_t destidx,
       
   184                           const char *source, Py_ssize_t len)
       
   185 {
       
   186 	PyObject *sliced = PyBytes_FromStringAndSize(source, len);
       
   187 	if (sliced == NULL)
       
   188 		return false;
       
   189 	PyList_SET_ITEM(list, destidx, sliced);
       
   190 	return true;
       
   191 }
       
   192 
       
   193 static PyObject *splitnewlines(PyObject *self, PyObject *args)
       
   194 {
       
   195 	const char *text;
       
   196 	Py_ssize_t nelts = 0, size, i, start = 0;
       
   197 	PyObject *result = NULL;
       
   198 
       
   199 	if (!PyArg_ParseTuple(args, "s#", &text, &size)) {
       
   200 		goto abort;
       
   201 	}
       
   202 	if (!size) {
       
   203 		return PyList_New(0);
       
   204 	}
       
   205 	/* This loops to size-1 because if the last byte is a newline,
       
   206 	 * we don't want to perform a split there. */
       
   207 	for (i = 0; i < size - 1; ++i) {
       
   208 		if (text[i] == '\n') {
       
   209 			++nelts;
       
   210 		}
       
   211 	}
       
   212 	if ((result = PyList_New(nelts + 1)) == NULL)
       
   213 		goto abort;
       
   214 	nelts = 0;
       
   215 	for (i = 0; i < size - 1; ++i) {
       
   216 		if (text[i] == '\n') {
       
   217 			if (!sliceintolist(result, nelts++, text + start,
       
   218 			                   i - start + 1))
       
   219 				goto abort;
       
   220 			start = i + 1;
       
   221 		}
       
   222 	}
       
   223 	if (!sliceintolist(result, nelts++, text + start, size - start))
       
   224 		goto abort;
       
   225 	return result;
       
   226 abort:
       
   227 	Py_XDECREF(result);
       
   228 	return NULL;
       
   229 }
       
   230 
   183 static char mdiff_doc[] = "Efficient binary diff.";
   231 static char mdiff_doc[] = "Efficient binary diff.";
   184 
   232 
   185 static PyMethodDef methods[] = {
   233 static PyMethodDef methods[] = {
   186     {"bdiff", bdiff, METH_VARARGS, "calculate a binary diff\n"},
   234     {"bdiff", bdiff, METH_VARARGS, "calculate a binary diff\n"},
   187     {"blocks", blocks, METH_VARARGS, "find a list of matching lines\n"},
   235     {"blocks", blocks, METH_VARARGS, "find a list of matching lines\n"},
   188     {"fixws", fixws, METH_VARARGS, "normalize diff whitespaces\n"},
   236     {"fixws", fixws, METH_VARARGS, "normalize diff whitespaces\n"},
       
   237     {"splitnewlines", splitnewlines, METH_VARARGS,
       
   238      "like str.splitlines, but only split on newlines\n"},
   189     {NULL, NULL},
   239     {NULL, NULL},
   190 };
   240 };
   191 
   241 
   192 static const int version = 1;
   242 static const int version = 2;
   193 
   243 
   194 #ifdef IS_PY3K
   244 #ifdef IS_PY3K
   195 static struct PyModuleDef bdiff_module = {
   245 static struct PyModuleDef bdiff_module = {
   196     PyModuleDef_HEAD_INIT, "bdiff", mdiff_doc, -1, methods,
   246     PyModuleDef_HEAD_INIT, "bdiff", mdiff_doc, -1, methods,
   197 };
   247 };