Fossil SCM

Fix indenting behavior of --ignore-space-at-sol option

jan.nijtmans 2014-03-03 11:17 diff-eolws
Commit 2faa1a272bf2b5934dc9832e6edfe3548db06bdf
1 file changed +21 -7
+21 -7
--- src/diff.c
+++ src/diff.c
@@ -55,12 +55,12 @@
5555
"cannot compute difference between symlink and regular file\n"
5656
5757
#define DIFF_TOO_MANY_CHANGES \
5858
"more than 10,000 changes\n"
5959
60
-#define DIFF_EOLWS_ONLY \
61
- "only end-of-line whitespace changed\n"
60
+#define DIFF_WHITESPACE_ONLY \
61
+ "whitespace changes only\n"
6262
6363
/*
6464
** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes)
6565
*/
6666
#define LENGTH_MASK_SZ 13
@@ -77,10 +77,11 @@
7777
*/
7878
typedef struct DLine DLine;
7979
struct DLine {
8080
const char *z; /* The text of the line */
8181
unsigned int h; /* Hash of the line */
82
+ unsigned int indent; /* Indent of the line. Only !=0 with --ignore-space-at sol option */
8283
unsigned int iNext; /* 1+(Index of next line with same the same hash) */
8384
8485
/* an array of DLine elements serves two purposes. The fields
8586
** above are one per line of input text. But each entry is also
8687
** a bucket in a hash table, as follows: */
@@ -130,11 +131,11 @@
130131
**
131132
** Profiling show that in most cases this routine consumes the bulk of
132133
** the CPU time on a diff.
133134
*/
134135
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;
136137
unsigned int h, h2;
137138
DLine *a;
138139
139140
/* Count the number of lines. Allocate space to hold
140141
** the returned array.
@@ -165,17 +166,24 @@
165166
/* Fill in the array */
166167
for(i=0; i<nLine; i++){
167168
for(j=0; z[j] && z[j]!='\n'; j++){}
168169
k = j;
169170
s = 0;
171
+ indent = 0;
170172
if( diffFlags & DIFF_IGNORE_EOLWS ){
171173
while( k>0 && fossil_isspace(z[k-1]) ){ k--; }
172174
}
173175
if( diffFlags & DIFF_IGNORE_SOLWS ){
174176
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
+ }
175182
}
176183
a[i].z = z+s;
184
+ a[i].indent = s;
177185
for(h=0, x=s; x<k; x++){
178186
h = h ^ (h<<2) ^ z[x];
179187
}
180188
a[i].h = h = (h<<LENGTH_MASK_SZ) | (k-s);
181189
h2 = h % nLine;
@@ -231,15 +239,21 @@
231239
}else if( cPrefix=='+' ){
232240
blob_append(pOut, "<span class=\"diffadd\">", -1);
233241
}else if( cPrefix=='-' ){
234242
blob_append(pOut, "<span class=\"diffrm\">", -1);
235243
}
244
+ if( pLine->indent ){
245
+ blob_appendf(pOut, "%*s", pLine->indent, " ");
246
+ }
236247
htmlize_to_blob(pOut, pLine->z, (pLine->h & LENGTH_MASK));
237248
if( cPrefix!=' ' ){
238249
blob_append(pOut, "</span>", -1);
239250
}
240251
}else{
252
+ if( pLine->indent ){
253
+ blob_appendf(pOut, "%*s", pLine->indent, " ");
254
+ }
241255
blob_append(pOut, pLine->z, pLine->h & LENGTH_MASK);
242256
}
243257
blob_append(pOut, "\n", 1);
244258
}
245259
@@ -1763,19 +1777,19 @@
17631777
Blob *pB_Blob, /* TO file */
17641778
Blob *pOut, /* Write diff here if not NULL */
17651779
ReCompiled *pRe, /* Only output changes where this Regexp matches */
17661780
u64 diffFlags /* DIFF_* flags defined above */
17671781
){
1768
- int ignoreEolWs; /* Ignore whitespace at the end of lines */
1782
+ int ignoreWs; /* Ignore whitespace */
17691783
DContext c;
17701784
17711785
if( diffFlags & DIFF_INVERT ){
17721786
Blob *pTemp = pA_Blob;
17731787
pA_Blob = pB_Blob;
17741788
pB_Blob = pTemp;
17751789
}
1776
- ignoreEolWs = (diffFlags & DIFF_IGNORE_EOLWS)!=0;
1790
+ ignoreWs = (diffFlags & (DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS))!=0;
17771791
blob_to_utf8_no_bom(pA_Blob, 0);
17781792
blob_to_utf8_no_bom(pB_Blob, 0);
17791793
17801794
/* Prepare the input files */
17811795
memset(&c, 0, sizeof(c));
@@ -1792,15 +1806,15 @@
17921806
return 0;
17931807
}
17941808
17951809
/* Compute the difference */
17961810
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 ){
17981812
fossil_free(c.aFrom);
17991813
fossil_free(c.aTo);
18001814
fossil_free(c.aEdit);
1801
- if( pOut ) diff_errmsg(pOut, DIFF_EOLWS_ONLY, diffFlags);
1815
+ if( pOut ) diff_errmsg(pOut, DIFF_WHITESPACE_ONLY, diffFlags);
18021816
return 0;
18031817
}
18041818
if( (diffFlags & DIFF_NOTTOOBIG)!=0 ){
18051819
int i, m, n;
18061820
int *a = c.aEdit;
18071821
--- 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

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button