21 #include "_squareVisitor.h" 24 int matchNTokens(
const GArray* textTokens,
size_t textStart,
size_t textLength,
25 const GArray* searchTokens,
size_t searchStart,
size_t searchLength,
26 unsigned int numberOfWantedMatches) {
29 textStart < textLength &&
30 searchStart < searchLength &&
32 tokens_index(textTokens, textStart),
33 tokens_index(searchTokens, searchStart
38 size_t canMatch =
MIN(textLength - textStart, searchLength - searchStart);
39 size_t shouldMatch =
MIN(numberOfWantedMatches, canMatch);
40 for (
size_t i = 1; i < shouldMatch; i++) {
42 tokens_index(textTokens, i + textStart),
43 tokens_index(searchTokens, i + searchStart)))
48 return (matched == shouldMatch);
53 int lookForDiff(
const GArray* textTokens,
const GArray* searchTokens,
54 size_t iText,
size_t iSearch,
55 unsigned int maxAllowedDiff,
unsigned int minAdjacentMatches,
57 size_t searchLength = searchTokens->len;
58 size_t textLength = textTokens->len;
60 size_t searchStopAt =
MIN(iSearch + maxAllowedDiff, searchLength);
61 size_t textStopAt =
MIN(iText + maxAllowedDiff, textLength);
65 for (
unsigned int i = 0; i < SQUARE_VISITOR_LENGTH; i++) {
66 textPos = iText + squareVisitorX[i];
67 searchPos = iSearch + squareVisitorY[i];
69 if ((textPos < textStopAt) && (searchPos < searchStopAt))
70 if (matchNTokens(textTokens, textPos, textLength,
71 searchTokens, searchPos, searchLength,
74 result->search.start = searchPos;
75 result->search.length = searchPos - iSearch;
76 result->text.start = textPos;
77 result->text.length = textPos - iText;
87 size_t* additionsCounter,
size_t* removedCounter,
88 size_t* iText,
size_t* iSearch) {
91 diffCopy.text.start = *iText;
92 diffCopy.search.start = *iSearch;
94 if (diffCopy.search.length == 0)
95 diffCopy.diffType = DIFF_TYPE_ADDITION;
96 else if (diffCopy.text.length == 0)
97 diffCopy.diffType = DIFF_TYPE_REMOVAL;
99 diffCopy.diffType = DIFF_TYPE_REPLACE;
101 *iText = diff->text.start;
102 *iSearch = diff->search.start;
104 g_array_append_val(matchedInfo, diffCopy);
106 *additionsCounter += diffCopy.text.length;
107 *removedCounter += diffCopy.search.length;
112 static void applyTailDiff(GArray* matchedInfo,
114 size_t* removedCounter,
size_t* additionsCounter,
115 size_t* iText,
size_t* iSearch) {
120 .length = searchLength - (*iSearch)
129 applyDiff(&tailDiff, matchedInfo, additionsCounter, removedCounter, iText, iSearch);
132 static void initSimpleMatch(
DiffMatchInfo* simpleMatch,
size_t iText,
size_t iSearch) {
133 simpleMatch->text.start = iText;
134 simpleMatch->text.length = 0;
135 simpleMatch->search.start = iSearch;
136 simpleMatch->search.length = 0;
151 DiffResult* findMatchAsDiffs(
const GArray* textTokens,
const GArray* searchTokens,
152 size_t textStartPosition,
size_t searchStartPosition,
153 unsigned int maxAllowedDiff,
unsigned int minAdjacentMatches) {
154 size_t textLength = textTokens->len;
155 size_t searchLength = searchTokens->len;
157 if ((searchLength<=searchStartPosition) || (textLength<=textStartPosition)) {
162 result->matchedInfo = g_array_new(FALSE, FALSE,
sizeof(
DiffMatchInfo));
163 GArray* matchedInfo = result->matchedInfo;
165 size_t iText = textStartPosition;
168 size_t removedCounter = 0;
169 size_t matchedCounter = 0;
170 size_t additionsCounter = 0;
172 if (searchStartPosition > 0) {
176 .length = searchStartPosition
184 applyDiff(&licenseHeadDiff, matchedInfo, &additionsCounter, &removedCounter, &iText, &iSearch);
185 iSearch = searchStartPosition;
189 while (iText < textLength) {
190 Token* textToken = tokens_index(textTokens, iText);
191 Token* searchToken = tokens_index(searchTokens, iSearch);
192 if (tokenEquals(textToken, searchToken))
197 if (iText < textLength) {
199 simpleMatch.diffType = DIFF_TYPE_MATCH;
200 initSimpleMatch(&simpleMatch, iText, iSearch);
202 while ((iText < textLength) && (iSearch < searchLength)) {
203 Token* textToken = tokens_index(textTokens, iText);
204 Token* searchToken = tokens_index(searchTokens, iSearch);
206 if (tokenEquals(textToken, searchToken)) {
207 simpleMatch.text.length++;
208 simpleMatch.search.length++;
214 g_array_append_val(matchedInfo, simpleMatch);
215 initSimpleMatch(&simpleMatch, iText, iSearch);
218 if (lookForDiff(textTokens, searchTokens,
220 maxAllowedDiff, minAdjacentMatches,
224 &additionsCounter, &removedCounter,
227 simpleMatch.text.start = iText;
228 simpleMatch.search.start = iSearch;
234 if (simpleMatch.text.length > 0) {
235 g_array_append_val(matchedInfo, simpleMatch);
239 if ((iSearch < searchLength) && (searchLength < maxAllowedDiff + iSearch)) {
240 applyTailDiff(matchedInfo, searchLength, &removedCounter, &additionsCounter, &iText, &iSearch);
243 if (matchedCounter + removedCounter != searchLength) {
244 g_array_free(matchedInfo, TRUE);
250 printf(
"diff: (=%zu +%zu -%zu)/%zu\n", matchedCounter, additionsCounter, removedCounter, searchLength);
251 for (
size_t i=0; i<matchedInfo->len; i++) {
253 printf(
"info[%zu]: t[%zu+%zu] %s s[%zu+%zu]}\n",
258 current.search.start,
259 current.search.length
264 result->removed = removedCounter;
265 result->added = additionsCounter;
266 result->matched = matchedCounter;
271 void diffResult_free(
DiffResult* diffResult) {
272 g_array_free(diffResult->matchedInfo, TRUE);
#define MIN(a, b)
Min of two.