##// END OF EJS Templates
mdiff: replace wscleanup() regexps with C loops...
Patrick Mezard -
r15530:eeac5e17 default
parent child Browse files
Show More
@@ -425,11 +425,55 b' nomem:'
425 425 return result ? result : PyErr_NoMemory();
426 426 }
427 427
428 /*
429 * If allws != 0, remove all whitespace (' ', \t and \r). Otherwise,
430 * reduce whitespace sequences to a single space and trim remaining whitespace
431 * from end of lines.
432 */
433 static PyObject *fixws(PyObject *self, PyObject *args)
434 {
435 PyObject *s, *result = NULL;
436 char allws, c;
437 const char *r;
438 int i, rlen, wlen = 0;
439 char *w;
440
441 if (!PyArg_ParseTuple(args, "Sb:fixws", &s, &allws))
442 return NULL;
443 r = PyBytes_AsString(s);
444 rlen = PyBytes_Size(s);
445
446 w = (char *)malloc(rlen);
447 if (!w)
448 goto nomem;
449
450 for (i = 0; i != rlen; i++) {
451 c = r[i];
452 if (c == ' ' || c == '\t' || c == '\r') {
453 if (!allws && (wlen == 0 || w[wlen - 1] != ' '))
454 w[wlen++] = ' ';
455 } else if (c == '\n' && !allws
456 && wlen > 0 && w[wlen - 1] == ' ') {
457 w[wlen - 1] = '\n';
458 } else {
459 w[wlen++] = c;
460 }
461 }
462
463 result = PyBytes_FromStringAndSize(w, wlen);
464
465 nomem:
466 free(w);
467 return result ? result : PyErr_NoMemory();
468 }
469
470
428 471 static char mdiff_doc[] = "Efficient binary diff.";
429 472
430 473 static PyMethodDef methods[] = {
431 474 {"bdiff", bdiff, METH_VARARGS, "calculate a binary diff\n"},
432 475 {"blocks", blocks, METH_VARARGS, "find a list of matching lines\n"},
476 {"fixws", fixws, METH_VARARGS, "normalize diff whitespaces\n"},
433 477 {NULL, NULL}
434 478 };
435 479
@@ -67,10 +67,9 b' defaultopts = diffopts()'
67 67
68 68 def wsclean(opts, text, blank=True):
69 69 if opts.ignorews:
70 text = re.sub('[ \t\r]+', '', text)
70 text = bdiff.fixws(text, 1)
71 71 elif opts.ignorewsamount:
72 text = re.sub('[ \t\r]+', ' ', text)
73 text = text.replace(' \n', '\n')
72 text = bdiff.fixws(text, 0)
74 73 if blank and opts.ignoreblanklines:
75 74 text = re.sub('\n+', '\n', text).strip('\n')
76 75 return text
@@ -5,7 +5,7 b''
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 import struct, difflib
8 import struct, difflib, re
9 9
10 10 def splitnewlines(text):
11 11 '''like str.splitlines, but only split on newlines.'''
@@ -78,3 +78,10 b' def blocks(a, b):'
78 78 d = _normalizeblocks(an, bn, d)
79 79 return [(i, i + n, j, j + n) for (i, j, n) in d]
80 80
81 def fixws(text, allws):
82 if allws:
83 text = re.sub('[ \t\r]+', '', text)
84 else:
85 text = re.sub('[ \t\r]+', ' ', text)
86 text = text.replace(' \n', '\n')
87 return text
@@ -50,3 +50,17 b' showdiff("x\\n\\nx\\n\\nx\\n\\nx\\n\\nz\\n", "x\\n'
50 50 showdiff("x\n\nx\n\nx\n\nx\n\nz\n", "x\n\nx\n\ny\n\nx\n\ny\n\nx\n\nz\n")
51 51
52 52 print "done"
53
54 def testfixws(a, b, allws):
55 c = bdiff.fixws(a, allws)
56 if c != b:
57 print "*** fixws", repr(a), repr(b), allws
58 print "got:"
59 print repr(c)
60
61 testfixws(" \ta\r b\t\n", "ab\n", 1)
62 testfixws(" \ta\r b\t\n", " a b\n", 0)
63 testfixws("", "", 1)
64 testfixws("", "", 0)
65
66 print "done"
@@ -21,3 +21,4 b" 6 6 'y\\n\\n'"
21 21 6 6 'y\n\n'
22 22 9 9 'y\n\n'
23 23 done
24 done
General Comments 0
You need to be logged in to leave comments. Login now