Fossil SCM
Fix indenting behavior of --ignore-space-at-sol option
Commit
2faa1a272bf2b5934dc9832e6edfe3548db06bdf
Parent
6392c032ce64db5…
1 file changed
+21
-7
+21
-7
| --- src/diff.c | ||
| +++ src/diff.c | ||
| @@ -55,12 +55,12 @@ | ||
| 55 | 55 | "cannot compute difference between symlink and regular file\n" |
| 56 | 56 | |
| 57 | 57 | #define DIFF_TOO_MANY_CHANGES \ |
| 58 | 58 | "more than 10,000 changes\n" |
| 59 | 59 | |
| 60 | -#define DIFF_EOLWS_ONLY \ | |
| 61 | - "only end-of-line whitespace changed\n" | |
| 60 | +#define DIFF_WHITESPACE_ONLY \ | |
| 61 | + "whitespace changes only\n" | |
| 62 | 62 | |
| 63 | 63 | /* |
| 64 | 64 | ** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes) |
| 65 | 65 | */ |
| 66 | 66 | #define LENGTH_MASK_SZ 13 |
| @@ -77,10 +77,11 @@ | ||
| 77 | 77 | */ |
| 78 | 78 | typedef struct DLine DLine; |
| 79 | 79 | struct DLine { |
| 80 | 80 | const char *z; /* The text of the line */ |
| 81 | 81 | unsigned int h; /* Hash of the line */ |
| 82 | + unsigned int indent; /* Indent of the line. Only !=0 with --ignore-space-at sol option */ | |
| 82 | 83 | unsigned int iNext; /* 1+(Index of next line with same the same hash) */ |
| 83 | 84 | |
| 84 | 85 | /* an array of DLine elements serves two purposes. The fields |
| 85 | 86 | ** above are one per line of input text. But each entry is also |
| 86 | 87 | ** a bucket in a hash table, as follows: */ |
| @@ -130,11 +131,11 @@ | ||
| 130 | 131 | ** |
| 131 | 132 | ** Profiling show that in most cases this routine consumes the bulk of |
| 132 | 133 | ** the CPU time on a diff. |
| 133 | 134 | */ |
| 134 | 135 | static DLine *break_into_lines(const char *z, int n, int *pnLine, u64 diffFlags){ |
| 135 | - int nLine, i, j, k, s, x; | |
| 136 | + int nLine, i, j, k, s, indent, x; | |
| 136 | 137 | unsigned int h, h2; |
| 137 | 138 | DLine *a; |
| 138 | 139 | |
| 139 | 140 | /* Count the number of lines. Allocate space to hold |
| 140 | 141 | ** the returned array. |
| @@ -165,17 +166,24 @@ | ||
| 165 | 166 | /* Fill in the array */ |
| 166 | 167 | for(i=0; i<nLine; i++){ |
| 167 | 168 | for(j=0; z[j] && z[j]!='\n'; j++){} |
| 168 | 169 | k = j; |
| 169 | 170 | s = 0; |
| 171 | + indent = 0; | |
| 170 | 172 | if( diffFlags & DIFF_IGNORE_EOLWS ){ |
| 171 | 173 | while( k>0 && fossil_isspace(z[k-1]) ){ k--; } |
| 172 | 174 | } |
| 173 | 175 | if( diffFlags & DIFF_IGNORE_SOLWS ){ |
| 174 | 176 | while( s<k && fossil_isspace(z[s]) ){ s++; } |
| 177 | + if( z[s]=='\t' ){ | |
| 178 | + indent = ((indent+9)/8)*8; | |
| 179 | + }else if( z[s]==' ' ){ | |
| 180 | + indent++; | |
| 181 | + } | |
| 175 | 182 | } |
| 176 | 183 | a[i].z = z+s; |
| 184 | + a[i].indent = s; | |
| 177 | 185 | for(h=0, x=s; x<k; x++){ |
| 178 | 186 | h = h ^ (h<<2) ^ z[x]; |
| 179 | 187 | } |
| 180 | 188 | a[i].h = h = (h<<LENGTH_MASK_SZ) | (k-s); |
| 181 | 189 | h2 = h % nLine; |
| @@ -231,15 +239,21 @@ | ||
| 231 | 239 | }else if( cPrefix=='+' ){ |
| 232 | 240 | blob_append(pOut, "<span class=\"diffadd\">", -1); |
| 233 | 241 | }else if( cPrefix=='-' ){ |
| 234 | 242 | blob_append(pOut, "<span class=\"diffrm\">", -1); |
| 235 | 243 | } |
| 244 | + if( pLine->indent ){ | |
| 245 | + blob_appendf(pOut, "%*s", pLine->indent, " "); | |
| 246 | + } | |
| 236 | 247 | htmlize_to_blob(pOut, pLine->z, (pLine->h & LENGTH_MASK)); |
| 237 | 248 | if( cPrefix!=' ' ){ |
| 238 | 249 | blob_append(pOut, "</span>", -1); |
| 239 | 250 | } |
| 240 | 251 | }else{ |
| 252 | + if( pLine->indent ){ | |
| 253 | + blob_appendf(pOut, "%*s", pLine->indent, " "); | |
| 254 | + } | |
| 241 | 255 | blob_append(pOut, pLine->z, pLine->h & LENGTH_MASK); |
| 242 | 256 | } |
| 243 | 257 | blob_append(pOut, "\n", 1); |
| 244 | 258 | } |
| 245 | 259 | |
| @@ -1763,19 +1777,19 @@ | ||
| 1763 | 1777 | Blob *pB_Blob, /* TO file */ |
| 1764 | 1778 | Blob *pOut, /* Write diff here if not NULL */ |
| 1765 | 1779 | ReCompiled *pRe, /* Only output changes where this Regexp matches */ |
| 1766 | 1780 | u64 diffFlags /* DIFF_* flags defined above */ |
| 1767 | 1781 | ){ |
| 1768 | - int ignoreEolWs; /* Ignore whitespace at the end of lines */ | |
| 1782 | + int ignoreWs; /* Ignore whitespace */ | |
| 1769 | 1783 | DContext c; |
| 1770 | 1784 | |
| 1771 | 1785 | if( diffFlags & DIFF_INVERT ){ |
| 1772 | 1786 | Blob *pTemp = pA_Blob; |
| 1773 | 1787 | pA_Blob = pB_Blob; |
| 1774 | 1788 | pB_Blob = pTemp; |
| 1775 | 1789 | } |
| 1776 | - ignoreEolWs = (diffFlags & DIFF_IGNORE_EOLWS)!=0; | |
| 1790 | + ignoreWs = (diffFlags & (DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS))!=0; | |
| 1777 | 1791 | blob_to_utf8_no_bom(pA_Blob, 0); |
| 1778 | 1792 | blob_to_utf8_no_bom(pB_Blob, 0); |
| 1779 | 1793 | |
| 1780 | 1794 | /* Prepare the input files */ |
| 1781 | 1795 | memset(&c, 0, sizeof(c)); |
| @@ -1792,15 +1806,15 @@ | ||
| 1792 | 1806 | return 0; |
| 1793 | 1807 | } |
| 1794 | 1808 | |
| 1795 | 1809 | /* Compute the difference */ |
| 1796 | 1810 | diff_all(&c); |
| 1797 | - if( ignoreEolWs && c.nEdit==6 && c.aEdit[1]==0 && c.aEdit[2]==0 ){ | |
| 1811 | + if( ignoreWs && c.nEdit==6 && c.aEdit[1]==0 && c.aEdit[2]==0 ){ | |
| 1798 | 1812 | fossil_free(c.aFrom); |
| 1799 | 1813 | fossil_free(c.aTo); |
| 1800 | 1814 | fossil_free(c.aEdit); |
| 1801 | - if( pOut ) diff_errmsg(pOut, DIFF_EOLWS_ONLY, diffFlags); | |
| 1815 | + if( pOut ) diff_errmsg(pOut, DIFF_WHITESPACE_ONLY, diffFlags); | |
| 1802 | 1816 | return 0; |
| 1803 | 1817 | } |
| 1804 | 1818 | if( (diffFlags & DIFF_NOTTOOBIG)!=0 ){ |
| 1805 | 1819 | int i, m, n; |
| 1806 | 1820 | int *a = c.aEdit; |
| 1807 | 1821 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -55,12 +55,12 @@ | |
| 55 | "cannot compute difference between symlink and regular file\n" |
| 56 | |
| 57 | #define DIFF_TOO_MANY_CHANGES \ |
| 58 | "more than 10,000 changes\n" |
| 59 | |
| 60 | #define DIFF_EOLWS_ONLY \ |
| 61 | "only end-of-line whitespace changed\n" |
| 62 | |
| 63 | /* |
| 64 | ** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes) |
| 65 | */ |
| 66 | #define LENGTH_MASK_SZ 13 |
| @@ -77,10 +77,11 @@ | |
| 77 | */ |
| 78 | typedef struct DLine DLine; |
| 79 | struct DLine { |
| 80 | const char *z; /* The text of the line */ |
| 81 | unsigned int h; /* Hash of the line */ |
| 82 | unsigned int iNext; /* 1+(Index of next line with same the same hash) */ |
| 83 | |
| 84 | /* an array of DLine elements serves two purposes. The fields |
| 85 | ** above are one per line of input text. But each entry is also |
| 86 | ** a bucket in a hash table, as follows: */ |
| @@ -130,11 +131,11 @@ | |
| 130 | ** |
| 131 | ** Profiling show that in most cases this routine consumes the bulk of |
| 132 | ** the CPU time on a diff. |
| 133 | */ |
| 134 | static DLine *break_into_lines(const char *z, int n, int *pnLine, u64 diffFlags){ |
| 135 | int nLine, i, j, k, s, x; |
| 136 | unsigned int h, h2; |
| 137 | DLine *a; |
| 138 | |
| 139 | /* Count the number of lines. Allocate space to hold |
| 140 | ** the returned array. |
| @@ -165,17 +166,24 @@ | |
| 165 | /* Fill in the array */ |
| 166 | for(i=0; i<nLine; i++){ |
| 167 | for(j=0; z[j] && z[j]!='\n'; j++){} |
| 168 | k = j; |
| 169 | s = 0; |
| 170 | if( diffFlags & DIFF_IGNORE_EOLWS ){ |
| 171 | while( k>0 && fossil_isspace(z[k-1]) ){ k--; } |
| 172 | } |
| 173 | if( diffFlags & DIFF_IGNORE_SOLWS ){ |
| 174 | while( s<k && fossil_isspace(z[s]) ){ s++; } |
| 175 | } |
| 176 | a[i].z = z+s; |
| 177 | for(h=0, x=s; x<k; x++){ |
| 178 | h = h ^ (h<<2) ^ z[x]; |
| 179 | } |
| 180 | a[i].h = h = (h<<LENGTH_MASK_SZ) | (k-s); |
| 181 | h2 = h % nLine; |
| @@ -231,15 +239,21 @@ | |
| 231 | }else if( cPrefix=='+' ){ |
| 232 | blob_append(pOut, "<span class=\"diffadd\">", -1); |
| 233 | }else if( cPrefix=='-' ){ |
| 234 | blob_append(pOut, "<span class=\"diffrm\">", -1); |
| 235 | } |
| 236 | htmlize_to_blob(pOut, pLine->z, (pLine->h & LENGTH_MASK)); |
| 237 | if( cPrefix!=' ' ){ |
| 238 | blob_append(pOut, "</span>", -1); |
| 239 | } |
| 240 | }else{ |
| 241 | blob_append(pOut, pLine->z, pLine->h & LENGTH_MASK); |
| 242 | } |
| 243 | blob_append(pOut, "\n", 1); |
| 244 | } |
| 245 | |
| @@ -1763,19 +1777,19 @@ | |
| 1763 | Blob *pB_Blob, /* TO file */ |
| 1764 | Blob *pOut, /* Write diff here if not NULL */ |
| 1765 | ReCompiled *pRe, /* Only output changes where this Regexp matches */ |
| 1766 | u64 diffFlags /* DIFF_* flags defined above */ |
| 1767 | ){ |
| 1768 | int ignoreEolWs; /* Ignore whitespace at the end of lines */ |
| 1769 | DContext c; |
| 1770 | |
| 1771 | if( diffFlags & DIFF_INVERT ){ |
| 1772 | Blob *pTemp = pA_Blob; |
| 1773 | pA_Blob = pB_Blob; |
| 1774 | pB_Blob = pTemp; |
| 1775 | } |
| 1776 | ignoreEolWs = (diffFlags & DIFF_IGNORE_EOLWS)!=0; |
| 1777 | blob_to_utf8_no_bom(pA_Blob, 0); |
| 1778 | blob_to_utf8_no_bom(pB_Blob, 0); |
| 1779 | |
| 1780 | /* Prepare the input files */ |
| 1781 | memset(&c, 0, sizeof(c)); |
| @@ -1792,15 +1806,15 @@ | |
| 1792 | return 0; |
| 1793 | } |
| 1794 | |
| 1795 | /* Compute the difference */ |
| 1796 | diff_all(&c); |
| 1797 | if( ignoreEolWs && c.nEdit==6 && c.aEdit[1]==0 && c.aEdit[2]==0 ){ |
| 1798 | fossil_free(c.aFrom); |
| 1799 | fossil_free(c.aTo); |
| 1800 | fossil_free(c.aEdit); |
| 1801 | if( pOut ) diff_errmsg(pOut, DIFF_EOLWS_ONLY, diffFlags); |
| 1802 | return 0; |
| 1803 | } |
| 1804 | if( (diffFlags & DIFF_NOTTOOBIG)!=0 ){ |
| 1805 | int i, m, n; |
| 1806 | int *a = c.aEdit; |
| 1807 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -55,12 +55,12 @@ | |
| 55 | "cannot compute difference between symlink and regular file\n" |
| 56 | |
| 57 | #define DIFF_TOO_MANY_CHANGES \ |
| 58 | "more than 10,000 changes\n" |
| 59 | |
| 60 | #define DIFF_WHITESPACE_ONLY \ |
| 61 | "whitespace changes only\n" |
| 62 | |
| 63 | /* |
| 64 | ** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes) |
| 65 | */ |
| 66 | #define LENGTH_MASK_SZ 13 |
| @@ -77,10 +77,11 @@ | |
| 77 | */ |
| 78 | typedef struct DLine DLine; |
| 79 | struct DLine { |
| 80 | const char *z; /* The text of the line */ |
| 81 | unsigned int h; /* Hash of the line */ |
| 82 | unsigned int indent; /* Indent of the line. Only !=0 with --ignore-space-at sol option */ |
| 83 | unsigned int iNext; /* 1+(Index of next line with same the same hash) */ |
| 84 | |
| 85 | /* an array of DLine elements serves two purposes. The fields |
| 86 | ** above are one per line of input text. But each entry is also |
| 87 | ** a bucket in a hash table, as follows: */ |
| @@ -130,11 +131,11 @@ | |
| 131 | ** |
| 132 | ** Profiling show that in most cases this routine consumes the bulk of |
| 133 | ** the CPU time on a diff. |
| 134 | */ |
| 135 | static DLine *break_into_lines(const char *z, int n, int *pnLine, u64 diffFlags){ |
| 136 | int nLine, i, j, k, s, indent, x; |
| 137 | unsigned int h, h2; |
| 138 | DLine *a; |
| 139 | |
| 140 | /* Count the number of lines. Allocate space to hold |
| 141 | ** the returned array. |
| @@ -165,17 +166,24 @@ | |
| 166 | /* Fill in the array */ |
| 167 | for(i=0; i<nLine; i++){ |
| 168 | for(j=0; z[j] && z[j]!='\n'; j++){} |
| 169 | k = j; |
| 170 | s = 0; |
| 171 | indent = 0; |
| 172 | if( diffFlags & DIFF_IGNORE_EOLWS ){ |
| 173 | while( k>0 && fossil_isspace(z[k-1]) ){ k--; } |
| 174 | } |
| 175 | if( diffFlags & DIFF_IGNORE_SOLWS ){ |
| 176 | while( s<k && fossil_isspace(z[s]) ){ s++; } |
| 177 | if( z[s]=='\t' ){ |
| 178 | indent = ((indent+9)/8)*8; |
| 179 | }else if( z[s]==' ' ){ |
| 180 | indent++; |
| 181 | } |
| 182 | } |
| 183 | a[i].z = z+s; |
| 184 | a[i].indent = s; |
| 185 | for(h=0, x=s; x<k; x++){ |
| 186 | h = h ^ (h<<2) ^ z[x]; |
| 187 | } |
| 188 | a[i].h = h = (h<<LENGTH_MASK_SZ) | (k-s); |
| 189 | h2 = h % nLine; |
| @@ -231,15 +239,21 @@ | |
| 239 | }else if( cPrefix=='+' ){ |
| 240 | blob_append(pOut, "<span class=\"diffadd\">", -1); |
| 241 | }else if( cPrefix=='-' ){ |
| 242 | blob_append(pOut, "<span class=\"diffrm\">", -1); |
| 243 | } |
| 244 | if( pLine->indent ){ |
| 245 | blob_appendf(pOut, "%*s", pLine->indent, " "); |
| 246 | } |
| 247 | htmlize_to_blob(pOut, pLine->z, (pLine->h & LENGTH_MASK)); |
| 248 | if( cPrefix!=' ' ){ |
| 249 | blob_append(pOut, "</span>", -1); |
| 250 | } |
| 251 | }else{ |
| 252 | if( pLine->indent ){ |
| 253 | blob_appendf(pOut, "%*s", pLine->indent, " "); |
| 254 | } |
| 255 | blob_append(pOut, pLine->z, pLine->h & LENGTH_MASK); |
| 256 | } |
| 257 | blob_append(pOut, "\n", 1); |
| 258 | } |
| 259 | |
| @@ -1763,19 +1777,19 @@ | |
| 1777 | Blob *pB_Blob, /* TO file */ |
| 1778 | Blob *pOut, /* Write diff here if not NULL */ |
| 1779 | ReCompiled *pRe, /* Only output changes where this Regexp matches */ |
| 1780 | u64 diffFlags /* DIFF_* flags defined above */ |
| 1781 | ){ |
| 1782 | int ignoreWs; /* Ignore whitespace */ |
| 1783 | DContext c; |
| 1784 | |
| 1785 | if( diffFlags & DIFF_INVERT ){ |
| 1786 | Blob *pTemp = pA_Blob; |
| 1787 | pA_Blob = pB_Blob; |
| 1788 | pB_Blob = pTemp; |
| 1789 | } |
| 1790 | ignoreWs = (diffFlags & (DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS))!=0; |
| 1791 | blob_to_utf8_no_bom(pA_Blob, 0); |
| 1792 | blob_to_utf8_no_bom(pB_Blob, 0); |
| 1793 | |
| 1794 | /* Prepare the input files */ |
| 1795 | memset(&c, 0, sizeof(c)); |
| @@ -1792,15 +1806,15 @@ | |
| 1806 | return 0; |
| 1807 | } |
| 1808 | |
| 1809 | /* Compute the difference */ |
| 1810 | diff_all(&c); |
| 1811 | if( ignoreWs && c.nEdit==6 && c.aEdit[1]==0 && c.aEdit[2]==0 ){ |
| 1812 | fossil_free(c.aFrom); |
| 1813 | fossil_free(c.aTo); |
| 1814 | fossil_free(c.aEdit); |
| 1815 | if( pOut ) diff_errmsg(pOut, DIFF_WHITESPACE_ONLY, diffFlags); |
| 1816 | return 0; |
| 1817 | } |
| 1818 | if( (diffFlags & DIFF_NOTTOOBIG)!=0 ){ |
| 1819 | int i, m, n; |
| 1820 | int *a = c.aEdit; |
| 1821 |