mercurial/cext/bdiff.c
changeset 36655 68026dd7c4f9
parent 36654 b864f4536ca8
child 36675 430fdb717549
equal deleted inserted replaced
36654:b864f4536ca8 36655:68026dd7c4f9
    58 	return rl ? rl : PyErr_NoMemory();
    58 	return rl ? rl : PyErr_NoMemory();
    59 }
    59 }
    60 
    60 
    61 static PyObject *bdiff(PyObject *self, PyObject *args)
    61 static PyObject *bdiff(PyObject *self, PyObject *args)
    62 {
    62 {
    63 	char *sa, *sb, *rb, *ia, *ib;
    63 	Py_buffer ba, bb;
       
    64 	char *rb, *ia, *ib;
    64 	PyObject *result = NULL;
    65 	PyObject *result = NULL;
    65 	struct bdiff_line *al = NULL, *bl = NULL;
    66 	struct bdiff_line *al = NULL, *bl = NULL;
    66 	struct bdiff_hunk l, *h;
    67 	struct bdiff_hunk l, *h;
    67 	int an, bn, count;
    68 	int an, bn, count;
    68 	Py_ssize_t len = 0, la, lb, li = 0, lcommon = 0, lmax;
    69 	Py_ssize_t len = 0, la, lb, li = 0, lcommon = 0, lmax;
    69 	PyThreadState *_save = NULL;
    70 	PyThreadState *_save = NULL;
    70 
    71 
    71 	l.next = NULL;
    72 	l.next = NULL;
    72 
    73 
    73 	if (!PyArg_ParseTuple(args, PY23("s#s#:bdiff", "y#y#:bdiff"), &sa, &la,
    74 	if (!PyArg_ParseTuple(args, PY23("s*s*:bdiff", "y*y*:bdiff"), &ba, &bb))
    74 	                      &sb, &lb))
       
    75 		return NULL;
    75 		return NULL;
       
    76 
       
    77 	if (!PyBuffer_IsContiguous(&ba, 'C') || ba.ndim > 1) {
       
    78 		PyErr_SetString(PyExc_ValueError, "bdiff input not contiguous");
       
    79 		goto cleanup;
       
    80 	}
       
    81 
       
    82 	if (!PyBuffer_IsContiguous(&bb, 'C') || bb.ndim > 1) {
       
    83 		PyErr_SetString(PyExc_ValueError, "bdiff input not contiguous");
       
    84 		goto cleanup;
       
    85 	}
       
    86 
       
    87 	la = ba.len;
       
    88 	lb = bb.len;
    76 
    89 
    77 	if (la > UINT_MAX || lb > UINT_MAX) {
    90 	if (la > UINT_MAX || lb > UINT_MAX) {
    78 		PyErr_SetString(PyExc_ValueError, "bdiff inputs too large");
    91 		PyErr_SetString(PyExc_ValueError, "bdiff inputs too large");
    79 		return NULL;
    92 		goto cleanup;
    80 	}
    93 	}
    81 
    94 
    82 	_save = PyEval_SaveThread();
    95 	_save = PyEval_SaveThread();
    83 
    96 
    84 	lmax = la > lb ? lb : la;
    97 	lmax = la > lb ? lb : la;
    85 	for (ia = sa, ib = sb; li < lmax && *ia == *ib; ++li, ++ia, ++ib)
    98 	for (ia = ba.buf, ib = bb.buf; li < lmax && *ia == *ib;
       
    99 	     ++li, ++ia, ++ib) {
    86 		if (*ia == '\n')
   100 		if (*ia == '\n')
    87 			lcommon = li + 1;
   101 			lcommon = li + 1;
       
   102 	}
    88 	/* we can almost add: if (li == lmax) lcommon = li; */
   103 	/* we can almost add: if (li == lmax) lcommon = li; */
    89 
   104 
    90 	an = bdiff_splitlines(sa + lcommon, la - lcommon, &al);
   105 	an = bdiff_splitlines(ba.buf + lcommon, la - lcommon, &al);
    91 	bn = bdiff_splitlines(sb + lcommon, lb - lcommon, &bl);
   106 	bn = bdiff_splitlines(bb.buf + lcommon, lb - lcommon, &bl);
    92 	if (!al || !bl) {
   107 	if (!al || !bl) {
    93 		PyErr_NoMemory();
   108 		PyErr_NoMemory();
    94 		goto cleanup;
   109 		goto cleanup;
    95 	}
   110 	}
    96 
   111 
   135 	}
   150 	}
   136 
   151 
   137 cleanup:
   152 cleanup:
   138 	if (_save)
   153 	if (_save)
   139 		PyEval_RestoreThread(_save);
   154 		PyEval_RestoreThread(_save);
       
   155 	PyBuffer_Release(&ba);
       
   156 	PyBuffer_Release(&bb);
   140 	if (al) {
   157 	if (al) {
   141 		free(al);
   158 		free(al);
   142 	}
   159 	}
   143 	if (bl) {
   160 	if (bl) {
   144 		free(bl);
   161 		free(bl);