Fossil SCM
Change the sense of the "same_dline()" routine in the diff generator so that it returns 0 if the lines are the same and non-zero if the lines are different, as this helps the diff logic to run faster.
Commit
2f7527e88c169da38b51d5696bac3b72f6eb9b0f727e211a6ad14e94d64d4a3b
Parent
1e881f59786bd89…
1 file changed
+24
-23
+24
-23
| --- src/diff.c | ||
| +++ src/diff.c | ||
| @@ -115,11 +115,11 @@ | ||
| 115 | 115 | int nEditAlloc; /* Space allocated for aEdit[] */ |
| 116 | 116 | DLine *aFrom; /* File on left side of the diff */ |
| 117 | 117 | int nFrom; /* Number of lines in aFrom[] */ |
| 118 | 118 | DLine *aTo; /* File on right side of the diff */ |
| 119 | 119 | int nTo; /* Number of lines in aTo[] */ |
| 120 | - int (*same_fn)(const DLine*,const DLine*); /* comparison function */ | |
| 120 | + int (*xDiffer)(const DLine*,const DLine*); /* comparison function */ | |
| 121 | 121 | }; |
| 122 | 122 | |
| 123 | 123 | /* |
| 124 | 124 | ** Count the number of lines in the input string. Include the last line |
| 125 | 125 | ** in the count even if it lacks the \n terminator. If an empty string |
| @@ -232,33 +232,34 @@ | ||
| 232 | 232 | *pnLine = nLine; |
| 233 | 233 | return a; |
| 234 | 234 | } |
| 235 | 235 | |
| 236 | 236 | /* |
| 237 | -** Return true if two DLine elements are identical. | |
| 237 | +** Return zero if two DLine elements are identical. | |
| 238 | 238 | */ |
| 239 | 239 | static int same_dline(const DLine *pA, const DLine *pB){ |
| 240 | - return pA->h==pB->h && memcmp(pA->z,pB->z, pA->h&LENGTH_MASK)==0; | |
| 240 | + if( pA->h!=pB->h ) return 1; | |
| 241 | + return memcmp(pA->z,pB->z, pA->h&LENGTH_MASK); | |
| 241 | 242 | } |
| 242 | 243 | |
| 243 | 244 | /* |
| 244 | -** Return true if two DLine elements are identical, ignoring | |
| 245 | +** Return zero if two DLine elements are identical, ignoring | |
| 245 | 246 | ** all whitespace. The indent field of pA/pB already points |
| 246 | 247 | ** to the first non-space character in the string. |
| 247 | 248 | */ |
| 248 | 249 | |
| 249 | 250 | static int same_dline_ignore_allws(const DLine *pA, const DLine *pB){ |
| 250 | 251 | int a = pA->indent, b = pB->indent; |
| 251 | 252 | if( pA->h==pB->h ){ |
| 252 | 253 | while( a<pA->n || b<pB->n ){ |
| 253 | - if( a<pA->n && b<pB->n && pA->z[a++] != pB->z[b++] ) return 0; | |
| 254 | + if( a<pA->n && b<pB->n && pA->z[a++] != pB->z[b++] ) return 1; | |
| 254 | 255 | while( a<pA->n && fossil_isspace(pA->z[a])) ++a; |
| 255 | 256 | while( b<pB->n && fossil_isspace(pB->z[b])) ++b; |
| 256 | 257 | } |
| 257 | - return pA->n-a == pB->n-b; | |
| 258 | + return pA->n-a != pB->n-b; | |
| 258 | 259 | } |
| 259 | - return 0; | |
| 260 | + return 1; | |
| 260 | 261 | } |
| 261 | 262 | |
| 262 | 263 | /* |
| 263 | 264 | ** Return true if the regular expression *pRe matches any of the |
| 264 | 265 | ** N dlines |
| @@ -1444,16 +1445,16 @@ | ||
| 1444 | 1445 | int iSXb = iS1; /* Best match so far */ |
| 1445 | 1446 | int iSYb = iS2; /* Best match so far */ |
| 1446 | 1447 | |
| 1447 | 1448 | for(i=iS1; i<iE1-mxLength; i++){ |
| 1448 | 1449 | for(j=iS2; j<iE2-mxLength; j++){ |
| 1449 | - if( !p->same_fn(&p->aFrom[i], &p->aTo[j]) ) continue; | |
| 1450 | - if( mxLength && !p->same_fn(&p->aFrom[i+mxLength], &p->aTo[j+mxLength]) ){ | |
| 1450 | + if( p->xDiffer(&p->aFrom[i], &p->aTo[j]) ) continue; | |
| 1451 | + if( mxLength && p->xDiffer(&p->aFrom[i+mxLength], &p->aTo[j+mxLength]) ){ | |
| 1451 | 1452 | continue; |
| 1452 | 1453 | } |
| 1453 | 1454 | k = 1; |
| 1454 | - while( i+k<iE1 && j+k<iE2 && p->same_fn(&p->aFrom[i+k],&p->aTo[j+k]) ){ | |
| 1455 | + while( i+k<iE1 && j+k<iE2 && p->xDiffer(&p->aFrom[i+k],&p->aTo[j+k])==0 ){ | |
| 1455 | 1456 | k++; |
| 1456 | 1457 | } |
| 1457 | 1458 | if( k>mxLength ){ |
| 1458 | 1459 | iSXb = i; |
| 1459 | 1460 | iSYb = j; |
| @@ -1515,11 +1516,11 @@ | ||
| 1515 | 1516 | mid = (iE1 + iS1)/2; |
| 1516 | 1517 | for(i=iS1; i<iE1; i++){ |
| 1517 | 1518 | int limit = 0; |
| 1518 | 1519 | j = p->aTo[p->aFrom[i].h % p->nTo].iHash; |
| 1519 | 1520 | while( j>0 |
| 1520 | - && (j-1<iS2 || j>=iE2 || !p->same_fn(&p->aFrom[i], &p->aTo[j-1])) | |
| 1521 | + && (j-1<iS2 || j>=iE2 || p->xDiffer(&p->aFrom[i], &p->aTo[j-1])) | |
| 1521 | 1522 | ){ |
| 1522 | 1523 | if( limit++ > 10 ){ |
| 1523 | 1524 | j = 0; |
| 1524 | 1525 | break; |
| 1525 | 1526 | } |
| @@ -1532,19 +1533,19 @@ | ||
| 1532 | 1533 | iSX = i; |
| 1533 | 1534 | iSY = j-1; |
| 1534 | 1535 | pA = &p->aFrom[iSX-1]; |
| 1535 | 1536 | pB = &p->aTo[iSY-1]; |
| 1536 | 1537 | n = minInt(iSX-iS1, iSY-iS2); |
| 1537 | - for(k=0; k<n && p->same_fn(pA,pB); k++, pA--, pB--){} | |
| 1538 | + for(k=0; k<n && p->xDiffer(pA,pB)==0; k++, pA--, pB--){} | |
| 1538 | 1539 | iSX -= k; |
| 1539 | 1540 | iSY -= k; |
| 1540 | 1541 | iEX = i+1; |
| 1541 | 1542 | iEY = j; |
| 1542 | 1543 | pA = &p->aFrom[iEX]; |
| 1543 | 1544 | pB = &p->aTo[iEY]; |
| 1544 | 1545 | n = minInt(iE1-iEX, iE2-iEY); |
| 1545 | - for(k=0; k<n && p->same_fn(pA,pB); k++, pA++, pB++){} | |
| 1546 | + for(k=0; k<n && p->xDiffer(pA,pB)==0; k++, pA++, pB++){} | |
| 1546 | 1547 | iEX += k; |
| 1547 | 1548 | iEY += k; |
| 1548 | 1549 | skew = (iSX-iS1) - (iSY-iS2); |
| 1549 | 1550 | if( skew<0 ) skew = -skew; |
| 1550 | 1551 | dist = (iSX+iEX)/2 - mid; |
| @@ -1681,16 +1682,16 @@ | ||
| 1681 | 1682 | int mnE, iS, iE1, iE2; |
| 1682 | 1683 | |
| 1683 | 1684 | /* Carve off the common header and footer */ |
| 1684 | 1685 | iE1 = p->nFrom; |
| 1685 | 1686 | iE2 = p->nTo; |
| 1686 | - while( iE1>0 && iE2>0 && p->same_fn(&p->aFrom[iE1-1], &p->aTo[iE2-1]) ){ | |
| 1687 | + while( iE1>0 && iE2>0 && p->xDiffer(&p->aFrom[iE1-1], &p->aTo[iE2-1])==0 ){ | |
| 1687 | 1688 | iE1--; |
| 1688 | 1689 | iE2--; |
| 1689 | 1690 | } |
| 1690 | 1691 | mnE = iE1<iE2 ? iE1 : iE2; |
| 1691 | - for(iS=0; iS<mnE && p->same_fn(&p->aFrom[iS],&p->aTo[iS]); iS++){} | |
| 1692 | + for(iS=0; iS<mnE && p->xDiffer(&p->aFrom[iS],&p->aTo[iS])==0; iS++){} | |
| 1692 | 1693 | |
| 1693 | 1694 | /* do the difference */ |
| 1694 | 1695 | if( iS>0 ){ |
| 1695 | 1696 | appendTriple(p, iS, 0, 0); |
| 1696 | 1697 | } |
| @@ -1755,11 +1756,11 @@ | ||
| 1755 | 1756 | |
| 1756 | 1757 | /* Shift insertions toward the beginning of the file */ |
| 1757 | 1758 | while( cpy>0 && del==0 && ins>0 ){ |
| 1758 | 1759 | DLine *pTop = &p->aFrom[lnFrom-1]; /* Line before start of insert */ |
| 1759 | 1760 | DLine *pBtm = &p->aTo[lnTo+ins-1]; /* Last line inserted */ |
| 1760 | - if( p->same_fn(pTop, pBtm)==0 ) break; | |
| 1761 | + if( p->xDiffer(pTop, pBtm) ) break; | |
| 1761 | 1762 | if( LENGTH(pTop+1)+LENGTH(pBtm)<=LENGTH(pTop)+LENGTH(pBtm-1) ) break; |
| 1762 | 1763 | lnFrom--; |
| 1763 | 1764 | lnTo--; |
| 1764 | 1765 | p->aEdit[r]--; |
| 1765 | 1766 | p->aEdit[r+3]++; |
| @@ -1768,11 +1769,11 @@ | ||
| 1768 | 1769 | |
| 1769 | 1770 | /* Shift insertions toward the end of the file */ |
| 1770 | 1771 | while( r+3<p->nEdit && p->aEdit[r+3]>0 && del==0 && ins>0 ){ |
| 1771 | 1772 | DLine *pTop = &p->aTo[lnTo]; /* First line inserted */ |
| 1772 | 1773 | DLine *pBtm = &p->aTo[lnTo+ins]; /* First line past end of insert */ |
| 1773 | - if( p->same_fn(pTop, pBtm)==0 ) break; | |
| 1774 | + if( p->xDiffer(pTop, pBtm) ) break; | |
| 1774 | 1775 | if( LENGTH(pTop)+LENGTH(pBtm-1)<=LENGTH(pTop+1)+LENGTH(pBtm) ) break; |
| 1775 | 1776 | lnFrom++; |
| 1776 | 1777 | lnTo++; |
| 1777 | 1778 | p->aEdit[r]++; |
| 1778 | 1779 | p->aEdit[r+3]--; |
| @@ -1781,11 +1782,11 @@ | ||
| 1781 | 1782 | |
| 1782 | 1783 | /* Shift deletions toward the beginning of the file */ |
| 1783 | 1784 | while( cpy>0 && del>0 && ins==0 ){ |
| 1784 | 1785 | DLine *pTop = &p->aFrom[lnFrom-1]; /* Line before start of delete */ |
| 1785 | 1786 | DLine *pBtm = &p->aFrom[lnFrom+del-1]; /* Last line deleted */ |
| 1786 | - if( p->same_fn(pTop, pBtm)==0 ) break; | |
| 1787 | + if( p->xDiffer(pTop, pBtm) ) break; | |
| 1787 | 1788 | if( LENGTH(pTop+1)+LENGTH(pBtm)<=LENGTH(pTop)+LENGTH(pBtm-1) ) break; |
| 1788 | 1789 | lnFrom--; |
| 1789 | 1790 | lnTo--; |
| 1790 | 1791 | p->aEdit[r]--; |
| 1791 | 1792 | p->aEdit[r+3]++; |
| @@ -1794,11 +1795,11 @@ | ||
| 1794 | 1795 | |
| 1795 | 1796 | /* Shift deletions toward the end of the file */ |
| 1796 | 1797 | while( r+3<p->nEdit && p->aEdit[r+3]>0 && del>0 && ins==0 ){ |
| 1797 | 1798 | DLine *pTop = &p->aFrom[lnFrom]; /* First line deleted */ |
| 1798 | 1799 | DLine *pBtm = &p->aFrom[lnFrom+del]; /* First line past end of delete */ |
| 1799 | - if( p->same_fn(pTop, pBtm)==0 ) break; | |
| 1800 | + if( p->xDiffer(pTop, pBtm) ) break; | |
| 1800 | 1801 | if( LENGTH(pTop)+LENGTH(pBtm-1)<=LENGTH(pTop)+LENGTH(pBtm) ) break; |
| 1801 | 1802 | lnFrom++; |
| 1802 | 1803 | lnTo++; |
| 1803 | 1804 | p->aEdit[r]++; |
| 1804 | 1805 | p->aEdit[r+3]--; |
| @@ -1875,13 +1876,13 @@ | ||
| 1875 | 1876 | blob_to_utf8_no_bom(pB_Blob, 0); |
| 1876 | 1877 | |
| 1877 | 1878 | /* Prepare the input files */ |
| 1878 | 1879 | memset(&c, 0, sizeof(c)); |
| 1879 | 1880 | if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){ |
| 1880 | - c.same_fn = same_dline_ignore_allws; | |
| 1881 | + c.xDiffer = same_dline_ignore_allws; | |
| 1881 | 1882 | }else{ |
| 1882 | - c.same_fn = same_dline; | |
| 1883 | + c.xDiffer = same_dline; | |
| 1883 | 1884 | } |
| 1884 | 1885 | c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob), |
| 1885 | 1886 | &c.nFrom, diffFlags); |
| 1886 | 1887 | c.aTo = break_into_lines(blob_str(pB_Blob), blob_size(pB_Blob), |
| 1887 | 1888 | &c.nTo, diffFlags); |
| @@ -2107,13 +2108,13 @@ | ||
| 2107 | 2108 | static int annotation_start(Annotator *p, Blob *pInput, u64 diffFlags){ |
| 2108 | 2109 | int i; |
| 2109 | 2110 | |
| 2110 | 2111 | memset(p, 0, sizeof(*p)); |
| 2111 | 2112 | if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){ |
| 2112 | - p->c.same_fn = same_dline_ignore_allws; | |
| 2113 | + p->c.xDiffer = same_dline_ignore_allws; | |
| 2113 | 2114 | }else{ |
| 2114 | - p->c.same_fn = same_dline; | |
| 2115 | + p->c.xDiffer = same_dline; | |
| 2115 | 2116 | } |
| 2116 | 2117 | p->c.aTo = break_into_lines(blob_str(pInput), blob_size(pInput),&p->c.nTo, |
| 2117 | 2118 | diffFlags); |
| 2118 | 2119 | if( p->c.aTo==0 ){ |
| 2119 | 2120 | return 1; |
| 2120 | 2121 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -115,11 +115,11 @@ | |
| 115 | int nEditAlloc; /* Space allocated for aEdit[] */ |
| 116 | DLine *aFrom; /* File on left side of the diff */ |
| 117 | int nFrom; /* Number of lines in aFrom[] */ |
| 118 | DLine *aTo; /* File on right side of the diff */ |
| 119 | int nTo; /* Number of lines in aTo[] */ |
| 120 | int (*same_fn)(const DLine*,const DLine*); /* comparison function */ |
| 121 | }; |
| 122 | |
| 123 | /* |
| 124 | ** Count the number of lines in the input string. Include the last line |
| 125 | ** in the count even if it lacks the \n terminator. If an empty string |
| @@ -232,33 +232,34 @@ | |
| 232 | *pnLine = nLine; |
| 233 | return a; |
| 234 | } |
| 235 | |
| 236 | /* |
| 237 | ** Return true if two DLine elements are identical. |
| 238 | */ |
| 239 | static int same_dline(const DLine *pA, const DLine *pB){ |
| 240 | return pA->h==pB->h && memcmp(pA->z,pB->z, pA->h&LENGTH_MASK)==0; |
| 241 | } |
| 242 | |
| 243 | /* |
| 244 | ** Return true if two DLine elements are identical, ignoring |
| 245 | ** all whitespace. The indent field of pA/pB already points |
| 246 | ** to the first non-space character in the string. |
| 247 | */ |
| 248 | |
| 249 | static int same_dline_ignore_allws(const DLine *pA, const DLine *pB){ |
| 250 | int a = pA->indent, b = pB->indent; |
| 251 | if( pA->h==pB->h ){ |
| 252 | while( a<pA->n || b<pB->n ){ |
| 253 | if( a<pA->n && b<pB->n && pA->z[a++] != pB->z[b++] ) return 0; |
| 254 | while( a<pA->n && fossil_isspace(pA->z[a])) ++a; |
| 255 | while( b<pB->n && fossil_isspace(pB->z[b])) ++b; |
| 256 | } |
| 257 | return pA->n-a == pB->n-b; |
| 258 | } |
| 259 | return 0; |
| 260 | } |
| 261 | |
| 262 | /* |
| 263 | ** Return true if the regular expression *pRe matches any of the |
| 264 | ** N dlines |
| @@ -1444,16 +1445,16 @@ | |
| 1444 | int iSXb = iS1; /* Best match so far */ |
| 1445 | int iSYb = iS2; /* Best match so far */ |
| 1446 | |
| 1447 | for(i=iS1; i<iE1-mxLength; i++){ |
| 1448 | for(j=iS2; j<iE2-mxLength; j++){ |
| 1449 | if( !p->same_fn(&p->aFrom[i], &p->aTo[j]) ) continue; |
| 1450 | if( mxLength && !p->same_fn(&p->aFrom[i+mxLength], &p->aTo[j+mxLength]) ){ |
| 1451 | continue; |
| 1452 | } |
| 1453 | k = 1; |
| 1454 | while( i+k<iE1 && j+k<iE2 && p->same_fn(&p->aFrom[i+k],&p->aTo[j+k]) ){ |
| 1455 | k++; |
| 1456 | } |
| 1457 | if( k>mxLength ){ |
| 1458 | iSXb = i; |
| 1459 | iSYb = j; |
| @@ -1515,11 +1516,11 @@ | |
| 1515 | mid = (iE1 + iS1)/2; |
| 1516 | for(i=iS1; i<iE1; i++){ |
| 1517 | int limit = 0; |
| 1518 | j = p->aTo[p->aFrom[i].h % p->nTo].iHash; |
| 1519 | while( j>0 |
| 1520 | && (j-1<iS2 || j>=iE2 || !p->same_fn(&p->aFrom[i], &p->aTo[j-1])) |
| 1521 | ){ |
| 1522 | if( limit++ > 10 ){ |
| 1523 | j = 0; |
| 1524 | break; |
| 1525 | } |
| @@ -1532,19 +1533,19 @@ | |
| 1532 | iSX = i; |
| 1533 | iSY = j-1; |
| 1534 | pA = &p->aFrom[iSX-1]; |
| 1535 | pB = &p->aTo[iSY-1]; |
| 1536 | n = minInt(iSX-iS1, iSY-iS2); |
| 1537 | for(k=0; k<n && p->same_fn(pA,pB); k++, pA--, pB--){} |
| 1538 | iSX -= k; |
| 1539 | iSY -= k; |
| 1540 | iEX = i+1; |
| 1541 | iEY = j; |
| 1542 | pA = &p->aFrom[iEX]; |
| 1543 | pB = &p->aTo[iEY]; |
| 1544 | n = minInt(iE1-iEX, iE2-iEY); |
| 1545 | for(k=0; k<n && p->same_fn(pA,pB); k++, pA++, pB++){} |
| 1546 | iEX += k; |
| 1547 | iEY += k; |
| 1548 | skew = (iSX-iS1) - (iSY-iS2); |
| 1549 | if( skew<0 ) skew = -skew; |
| 1550 | dist = (iSX+iEX)/2 - mid; |
| @@ -1681,16 +1682,16 @@ | |
| 1681 | int mnE, iS, iE1, iE2; |
| 1682 | |
| 1683 | /* Carve off the common header and footer */ |
| 1684 | iE1 = p->nFrom; |
| 1685 | iE2 = p->nTo; |
| 1686 | while( iE1>0 && iE2>0 && p->same_fn(&p->aFrom[iE1-1], &p->aTo[iE2-1]) ){ |
| 1687 | iE1--; |
| 1688 | iE2--; |
| 1689 | } |
| 1690 | mnE = iE1<iE2 ? iE1 : iE2; |
| 1691 | for(iS=0; iS<mnE && p->same_fn(&p->aFrom[iS],&p->aTo[iS]); iS++){} |
| 1692 | |
| 1693 | /* do the difference */ |
| 1694 | if( iS>0 ){ |
| 1695 | appendTriple(p, iS, 0, 0); |
| 1696 | } |
| @@ -1755,11 +1756,11 @@ | |
| 1755 | |
| 1756 | /* Shift insertions toward the beginning of the file */ |
| 1757 | while( cpy>0 && del==0 && ins>0 ){ |
| 1758 | DLine *pTop = &p->aFrom[lnFrom-1]; /* Line before start of insert */ |
| 1759 | DLine *pBtm = &p->aTo[lnTo+ins-1]; /* Last line inserted */ |
| 1760 | if( p->same_fn(pTop, pBtm)==0 ) break; |
| 1761 | if( LENGTH(pTop+1)+LENGTH(pBtm)<=LENGTH(pTop)+LENGTH(pBtm-1) ) break; |
| 1762 | lnFrom--; |
| 1763 | lnTo--; |
| 1764 | p->aEdit[r]--; |
| 1765 | p->aEdit[r+3]++; |
| @@ -1768,11 +1769,11 @@ | |
| 1768 | |
| 1769 | /* Shift insertions toward the end of the file */ |
| 1770 | while( r+3<p->nEdit && p->aEdit[r+3]>0 && del==0 && ins>0 ){ |
| 1771 | DLine *pTop = &p->aTo[lnTo]; /* First line inserted */ |
| 1772 | DLine *pBtm = &p->aTo[lnTo+ins]; /* First line past end of insert */ |
| 1773 | if( p->same_fn(pTop, pBtm)==0 ) break; |
| 1774 | if( LENGTH(pTop)+LENGTH(pBtm-1)<=LENGTH(pTop+1)+LENGTH(pBtm) ) break; |
| 1775 | lnFrom++; |
| 1776 | lnTo++; |
| 1777 | p->aEdit[r]++; |
| 1778 | p->aEdit[r+3]--; |
| @@ -1781,11 +1782,11 @@ | |
| 1781 | |
| 1782 | /* Shift deletions toward the beginning of the file */ |
| 1783 | while( cpy>0 && del>0 && ins==0 ){ |
| 1784 | DLine *pTop = &p->aFrom[lnFrom-1]; /* Line before start of delete */ |
| 1785 | DLine *pBtm = &p->aFrom[lnFrom+del-1]; /* Last line deleted */ |
| 1786 | if( p->same_fn(pTop, pBtm)==0 ) break; |
| 1787 | if( LENGTH(pTop+1)+LENGTH(pBtm)<=LENGTH(pTop)+LENGTH(pBtm-1) ) break; |
| 1788 | lnFrom--; |
| 1789 | lnTo--; |
| 1790 | p->aEdit[r]--; |
| 1791 | p->aEdit[r+3]++; |
| @@ -1794,11 +1795,11 @@ | |
| 1794 | |
| 1795 | /* Shift deletions toward the end of the file */ |
| 1796 | while( r+3<p->nEdit && p->aEdit[r+3]>0 && del>0 && ins==0 ){ |
| 1797 | DLine *pTop = &p->aFrom[lnFrom]; /* First line deleted */ |
| 1798 | DLine *pBtm = &p->aFrom[lnFrom+del]; /* First line past end of delete */ |
| 1799 | if( p->same_fn(pTop, pBtm)==0 ) break; |
| 1800 | if( LENGTH(pTop)+LENGTH(pBtm-1)<=LENGTH(pTop)+LENGTH(pBtm) ) break; |
| 1801 | lnFrom++; |
| 1802 | lnTo++; |
| 1803 | p->aEdit[r]++; |
| 1804 | p->aEdit[r+3]--; |
| @@ -1875,13 +1876,13 @@ | |
| 1875 | blob_to_utf8_no_bom(pB_Blob, 0); |
| 1876 | |
| 1877 | /* Prepare the input files */ |
| 1878 | memset(&c, 0, sizeof(c)); |
| 1879 | if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){ |
| 1880 | c.same_fn = same_dline_ignore_allws; |
| 1881 | }else{ |
| 1882 | c.same_fn = same_dline; |
| 1883 | } |
| 1884 | c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob), |
| 1885 | &c.nFrom, diffFlags); |
| 1886 | c.aTo = break_into_lines(blob_str(pB_Blob), blob_size(pB_Blob), |
| 1887 | &c.nTo, diffFlags); |
| @@ -2107,13 +2108,13 @@ | |
| 2107 | static int annotation_start(Annotator *p, Blob *pInput, u64 diffFlags){ |
| 2108 | int i; |
| 2109 | |
| 2110 | memset(p, 0, sizeof(*p)); |
| 2111 | if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){ |
| 2112 | p->c.same_fn = same_dline_ignore_allws; |
| 2113 | }else{ |
| 2114 | p->c.same_fn = same_dline; |
| 2115 | } |
| 2116 | p->c.aTo = break_into_lines(blob_str(pInput), blob_size(pInput),&p->c.nTo, |
| 2117 | diffFlags); |
| 2118 | if( p->c.aTo==0 ){ |
| 2119 | return 1; |
| 2120 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -115,11 +115,11 @@ | |
| 115 | int nEditAlloc; /* Space allocated for aEdit[] */ |
| 116 | DLine *aFrom; /* File on left side of the diff */ |
| 117 | int nFrom; /* Number of lines in aFrom[] */ |
| 118 | DLine *aTo; /* File on right side of the diff */ |
| 119 | int nTo; /* Number of lines in aTo[] */ |
| 120 | int (*xDiffer)(const DLine*,const DLine*); /* comparison function */ |
| 121 | }; |
| 122 | |
| 123 | /* |
| 124 | ** Count the number of lines in the input string. Include the last line |
| 125 | ** in the count even if it lacks the \n terminator. If an empty string |
| @@ -232,33 +232,34 @@ | |
| 232 | *pnLine = nLine; |
| 233 | return a; |
| 234 | } |
| 235 | |
| 236 | /* |
| 237 | ** Return zero if two DLine elements are identical. |
| 238 | */ |
| 239 | static int same_dline(const DLine *pA, const DLine *pB){ |
| 240 | if( pA->h!=pB->h ) return 1; |
| 241 | return memcmp(pA->z,pB->z, pA->h&LENGTH_MASK); |
| 242 | } |
| 243 | |
| 244 | /* |
| 245 | ** Return zero if two DLine elements are identical, ignoring |
| 246 | ** all whitespace. The indent field of pA/pB already points |
| 247 | ** to the first non-space character in the string. |
| 248 | */ |
| 249 | |
| 250 | static int same_dline_ignore_allws(const DLine *pA, const DLine *pB){ |
| 251 | int a = pA->indent, b = pB->indent; |
| 252 | if( pA->h==pB->h ){ |
| 253 | while( a<pA->n || b<pB->n ){ |
| 254 | if( a<pA->n && b<pB->n && pA->z[a++] != pB->z[b++] ) return 1; |
| 255 | while( a<pA->n && fossil_isspace(pA->z[a])) ++a; |
| 256 | while( b<pB->n && fossil_isspace(pB->z[b])) ++b; |
| 257 | } |
| 258 | return pA->n-a != pB->n-b; |
| 259 | } |
| 260 | return 1; |
| 261 | } |
| 262 | |
| 263 | /* |
| 264 | ** Return true if the regular expression *pRe matches any of the |
| 265 | ** N dlines |
| @@ -1444,16 +1445,16 @@ | |
| 1445 | int iSXb = iS1; /* Best match so far */ |
| 1446 | int iSYb = iS2; /* Best match so far */ |
| 1447 | |
| 1448 | for(i=iS1; i<iE1-mxLength; i++){ |
| 1449 | for(j=iS2; j<iE2-mxLength; j++){ |
| 1450 | if( p->xDiffer(&p->aFrom[i], &p->aTo[j]) ) continue; |
| 1451 | if( mxLength && p->xDiffer(&p->aFrom[i+mxLength], &p->aTo[j+mxLength]) ){ |
| 1452 | continue; |
| 1453 | } |
| 1454 | k = 1; |
| 1455 | while( i+k<iE1 && j+k<iE2 && p->xDiffer(&p->aFrom[i+k],&p->aTo[j+k])==0 ){ |
| 1456 | k++; |
| 1457 | } |
| 1458 | if( k>mxLength ){ |
| 1459 | iSXb = i; |
| 1460 | iSYb = j; |
| @@ -1515,11 +1516,11 @@ | |
| 1516 | mid = (iE1 + iS1)/2; |
| 1517 | for(i=iS1; i<iE1; i++){ |
| 1518 | int limit = 0; |
| 1519 | j = p->aTo[p->aFrom[i].h % p->nTo].iHash; |
| 1520 | while( j>0 |
| 1521 | && (j-1<iS2 || j>=iE2 || p->xDiffer(&p->aFrom[i], &p->aTo[j-1])) |
| 1522 | ){ |
| 1523 | if( limit++ > 10 ){ |
| 1524 | j = 0; |
| 1525 | break; |
| 1526 | } |
| @@ -1532,19 +1533,19 @@ | |
| 1533 | iSX = i; |
| 1534 | iSY = j-1; |
| 1535 | pA = &p->aFrom[iSX-1]; |
| 1536 | pB = &p->aTo[iSY-1]; |
| 1537 | n = minInt(iSX-iS1, iSY-iS2); |
| 1538 | for(k=0; k<n && p->xDiffer(pA,pB)==0; k++, pA--, pB--){} |
| 1539 | iSX -= k; |
| 1540 | iSY -= k; |
| 1541 | iEX = i+1; |
| 1542 | iEY = j; |
| 1543 | pA = &p->aFrom[iEX]; |
| 1544 | pB = &p->aTo[iEY]; |
| 1545 | n = minInt(iE1-iEX, iE2-iEY); |
| 1546 | for(k=0; k<n && p->xDiffer(pA,pB)==0; k++, pA++, pB++){} |
| 1547 | iEX += k; |
| 1548 | iEY += k; |
| 1549 | skew = (iSX-iS1) - (iSY-iS2); |
| 1550 | if( skew<0 ) skew = -skew; |
| 1551 | dist = (iSX+iEX)/2 - mid; |
| @@ -1681,16 +1682,16 @@ | |
| 1682 | int mnE, iS, iE1, iE2; |
| 1683 | |
| 1684 | /* Carve off the common header and footer */ |
| 1685 | iE1 = p->nFrom; |
| 1686 | iE2 = p->nTo; |
| 1687 | while( iE1>0 && iE2>0 && p->xDiffer(&p->aFrom[iE1-1], &p->aTo[iE2-1])==0 ){ |
| 1688 | iE1--; |
| 1689 | iE2--; |
| 1690 | } |
| 1691 | mnE = iE1<iE2 ? iE1 : iE2; |
| 1692 | for(iS=0; iS<mnE && p->xDiffer(&p->aFrom[iS],&p->aTo[iS])==0; iS++){} |
| 1693 | |
| 1694 | /* do the difference */ |
| 1695 | if( iS>0 ){ |
| 1696 | appendTriple(p, iS, 0, 0); |
| 1697 | } |
| @@ -1755,11 +1756,11 @@ | |
| 1756 | |
| 1757 | /* Shift insertions toward the beginning of the file */ |
| 1758 | while( cpy>0 && del==0 && ins>0 ){ |
| 1759 | DLine *pTop = &p->aFrom[lnFrom-1]; /* Line before start of insert */ |
| 1760 | DLine *pBtm = &p->aTo[lnTo+ins-1]; /* Last line inserted */ |
| 1761 | if( p->xDiffer(pTop, pBtm) ) break; |
| 1762 | if( LENGTH(pTop+1)+LENGTH(pBtm)<=LENGTH(pTop)+LENGTH(pBtm-1) ) break; |
| 1763 | lnFrom--; |
| 1764 | lnTo--; |
| 1765 | p->aEdit[r]--; |
| 1766 | p->aEdit[r+3]++; |
| @@ -1768,11 +1769,11 @@ | |
| 1769 | |
| 1770 | /* Shift insertions toward the end of the file */ |
| 1771 | while( r+3<p->nEdit && p->aEdit[r+3]>0 && del==0 && ins>0 ){ |
| 1772 | DLine *pTop = &p->aTo[lnTo]; /* First line inserted */ |
| 1773 | DLine *pBtm = &p->aTo[lnTo+ins]; /* First line past end of insert */ |
| 1774 | if( p->xDiffer(pTop, pBtm) ) break; |
| 1775 | if( LENGTH(pTop)+LENGTH(pBtm-1)<=LENGTH(pTop+1)+LENGTH(pBtm) ) break; |
| 1776 | lnFrom++; |
| 1777 | lnTo++; |
| 1778 | p->aEdit[r]++; |
| 1779 | p->aEdit[r+3]--; |
| @@ -1781,11 +1782,11 @@ | |
| 1782 | |
| 1783 | /* Shift deletions toward the beginning of the file */ |
| 1784 | while( cpy>0 && del>0 && ins==0 ){ |
| 1785 | DLine *pTop = &p->aFrom[lnFrom-1]; /* Line before start of delete */ |
| 1786 | DLine *pBtm = &p->aFrom[lnFrom+del-1]; /* Last line deleted */ |
| 1787 | if( p->xDiffer(pTop, pBtm) ) break; |
| 1788 | if( LENGTH(pTop+1)+LENGTH(pBtm)<=LENGTH(pTop)+LENGTH(pBtm-1) ) break; |
| 1789 | lnFrom--; |
| 1790 | lnTo--; |
| 1791 | p->aEdit[r]--; |
| 1792 | p->aEdit[r+3]++; |
| @@ -1794,11 +1795,11 @@ | |
| 1795 | |
| 1796 | /* Shift deletions toward the end of the file */ |
| 1797 | while( r+3<p->nEdit && p->aEdit[r+3]>0 && del>0 && ins==0 ){ |
| 1798 | DLine *pTop = &p->aFrom[lnFrom]; /* First line deleted */ |
| 1799 | DLine *pBtm = &p->aFrom[lnFrom+del]; /* First line past end of delete */ |
| 1800 | if( p->xDiffer(pTop, pBtm) ) break; |
| 1801 | if( LENGTH(pTop)+LENGTH(pBtm-1)<=LENGTH(pTop)+LENGTH(pBtm) ) break; |
| 1802 | lnFrom++; |
| 1803 | lnTo++; |
| 1804 | p->aEdit[r]++; |
| 1805 | p->aEdit[r+3]--; |
| @@ -1875,13 +1876,13 @@ | |
| 1876 | blob_to_utf8_no_bom(pB_Blob, 0); |
| 1877 | |
| 1878 | /* Prepare the input files */ |
| 1879 | memset(&c, 0, sizeof(c)); |
| 1880 | if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){ |
| 1881 | c.xDiffer = same_dline_ignore_allws; |
| 1882 | }else{ |
| 1883 | c.xDiffer = same_dline; |
| 1884 | } |
| 1885 | c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob), |
| 1886 | &c.nFrom, diffFlags); |
| 1887 | c.aTo = break_into_lines(blob_str(pB_Blob), blob_size(pB_Blob), |
| 1888 | &c.nTo, diffFlags); |
| @@ -2107,13 +2108,13 @@ | |
| 2108 | static int annotation_start(Annotator *p, Blob *pInput, u64 diffFlags){ |
| 2109 | int i; |
| 2110 | |
| 2111 | memset(p, 0, sizeof(*p)); |
| 2112 | if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){ |
| 2113 | p->c.xDiffer = same_dline_ignore_allws; |
| 2114 | }else{ |
| 2115 | p->c.xDiffer = same_dline; |
| 2116 | } |
| 2117 | p->c.aTo = break_into_lines(blob_str(pInput), blob_size(pInput),&p->c.nTo, |
| 2118 | diffFlags); |
| 2119 | if( p->c.aTo==0 ){ |
| 2120 | return 1; |
| 2121 |