Fossil SCM

modify looks_like_binary() to looks_like_text() such that it is usable in cr_warning() as well

jan.nijtmans 2012-10-28 09:34 trunk
Commit 1bffce5230e5d9f5d5142fa479adcc5d3e05d933
2 files changed +1 -23 +32 -26
+1 -23
--- src/checkin.c
+++ src/checkin.c
@@ -885,38 +885,16 @@
885885
/*
886886
** Issue a warning and give the user an opportunity to abandon out
887887
** if a \r\n line ending is seen in a text file.
888888
*/
889889
static void cr_warning(const Blob *p, const char *zFilename){
890
- int nCrNl = 0; /* Number of \r\n line endings seen */
891
- const unsigned char *z; /* File text */
892
- int n; /* Size of the file in bytes */
893
- int lastNl = 0; /* Characters since last \n */
894
- int i; /* Loop counter */
895890
char *zMsg; /* Warning message */
896891
Blob fname; /* Relative pathname of the file */
897892
static int allOk = 0; /* Set to true to disable this routine */
898893
899894
if( allOk ) return;
900
- z = (unsigned char*)blob_buffer(p);
901
- n = blob_size(p);
902
- for(i=0; i<n-1; i++){
903
- unsigned char c = z[i];
904
- if( c==0 ) return; /* It's binary */
905
- if( c=='\n' ){
906
- if( i>0 && z[i-1]=='\r' ){
907
- nCrNl = 1;
908
- if( i>8191 ) break;
909
- }
910
- lastNl = 0;
911
- }else{
912
- lastNl++;
913
- /* Binary if any line longer than 8191, see looks_like_binary() */
914
- if( lastNl>8191 ) return;
915
- }
916
- }
917
- if( nCrNl ){
895
+ if( looks_like_text(p)<0 ){
918896
Blob ans;
919897
char cReply;
920898
921899
file_relative_name(zFilename, &fname, 0);
922900
blob_zero(&ans);
923901
--- src/checkin.c
+++ src/checkin.c
@@ -885,38 +885,16 @@
885 /*
886 ** Issue a warning and give the user an opportunity to abandon out
887 ** if a \r\n line ending is seen in a text file.
888 */
889 static void cr_warning(const Blob *p, const char *zFilename){
890 int nCrNl = 0; /* Number of \r\n line endings seen */
891 const unsigned char *z; /* File text */
892 int n; /* Size of the file in bytes */
893 int lastNl = 0; /* Characters since last \n */
894 int i; /* Loop counter */
895 char *zMsg; /* Warning message */
896 Blob fname; /* Relative pathname of the file */
897 static int allOk = 0; /* Set to true to disable this routine */
898
899 if( allOk ) return;
900 z = (unsigned char*)blob_buffer(p);
901 n = blob_size(p);
902 for(i=0; i<n-1; i++){
903 unsigned char c = z[i];
904 if( c==0 ) return; /* It's binary */
905 if( c=='\n' ){
906 if( i>0 && z[i-1]=='\r' ){
907 nCrNl = 1;
908 if( i>8191 ) break;
909 }
910 lastNl = 0;
911 }else{
912 lastNl++;
913 /* Binary if any line longer than 8191, see looks_like_binary() */
914 if( lastNl>8191 ) return;
915 }
916 }
917 if( nCrNl ){
918 Blob ans;
919 char cReply;
920
921 file_relative_name(zFilename, &fname, 0);
922 blob_zero(&ans);
923
--- src/checkin.c
+++ src/checkin.c
@@ -885,38 +885,16 @@
885 /*
886 ** Issue a warning and give the user an opportunity to abandon out
887 ** if a \r\n line ending is seen in a text file.
888 */
889 static void cr_warning(const Blob *p, const char *zFilename){
 
 
 
 
 
890 char *zMsg; /* Warning message */
891 Blob fname; /* Relative pathname of the file */
892 static int allOk = 0; /* Set to true to disable this routine */
893
894 if( allOk ) return;
895 if( looks_like_text(p)<0 ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
896 Blob ans;
897 char cReply;
898
899 file_relative_name(zFilename, &fname, 0);
900 blob_zero(&ans);
901
+32 -26
--- src/diff.c
+++ src/diff.c
@@ -48,10 +48,11 @@
4848
"cannot compute difference between binary files\n"
4949
5050
#define DIFF_CANNOT_COMPUTE_SYMLINK \
5151
"cannot compute difference between symlink and regular file\n"
5252
53
+#define looks_like_binary(blob) (!(looks_like_text(blob)&1))
5354
#endif /* INTERFACE */
5455
5556
/*
5657
** Maximum length of a line in a text file. (8192)
5758
*/
@@ -106,11 +107,11 @@
106107
int nTo; /* Number of lines in aTo[] */
107108
};
108109
109110
/*
110111
** Return an array of DLine objects containing a pointer to the
111
-** start of each line and a hash of that line. The lower
112
+** start of each line and a hash of that line. The lower
112113
** bits of the hash store the length of each line.
113114
**
114115
** Trailing whitespace is removed from each line. 2010-08-20: Not any
115116
** more. If trailing whitespace is ignored, the "patch" command gets
116117
** confused by the diff output. Ticket [a9f7b23c2e376af5b0e5b]
@@ -169,35 +170,40 @@
169170
*pnLine = nLine;
170171
return a;
171172
}
172173
173174
/*
174
-** Returns non-zero if the specified content appears to be binary or
175
-** contains a line that is too long.
175
+** Returns 1, if the file appears text, and does not contain CrLf
176
+** Returns 0 if the specified content appears to be binary or
177
+** contains a line that is too long
178
+** Returns -1, if the file appears text, but it contains CrLf
176179
*/
177
-int looks_like_binary(const Blob *pContent){
180
+int looks_like_text(const Blob *pContent){
178181
const char *z = blob_buffer(pContent);
179182
int n = blob_size(pContent);
180183
int i, j;
184
+ int result = 1;
181185
182
- /* Count the number of lines. Allocate space to hold
183
- ** the returned array.
186
+ /* Check individual lines.
184187
*/
185188
for(i=j=0; i<n; i++, j++){
186189
int c = z[i];
187190
if( c==0 ) return 1; /* \000 byte in a file -> binary */
188191
if( c=='\n' ){
192
+ if( i>0 && z[i-1]=='\r' ){
193
+ result = -1; /* Contains CrLf, continue */
194
+ }
189195
if( j>LENGTH_MASK ){
190
- return 1; /* Very long line -> binary */
196
+ return 0; /* Very long line -> binary */
191197
}
192198
j = 0;
193199
}
194200
}
195201
if( j>LENGTH_MASK ){
196
- return 1; /* Very long line -> binary */
202
+ return 0; /* Very long line -> binary */
197203
}
198
- return 0; /* No problems seen -> not binary */
204
+ return result; /* No problems seen -> not binary */
199205
}
200206
201207
/*
202208
** Return true if two DLine elements are identical.
203209
*/
@@ -241,11 +247,11 @@
241247
242248
/*
243249
** Add two line numbers to the beginning of an output line for a context
244250
** diff. One or of the other of the two numbers might be zero, which means
245251
** to leave that number field blank. The "html" parameter means to format
246
-** the output for HTML.
252
+** the output for HTML.
247253
*/
248254
static void appendDiffLineno(Blob *pOut, int lnA, int lnB, int html){
249255
if( html ) blob_append(pOut, "<span class=\"diffln\">", -1);
250256
if( lnA>0 ){
251257
blob_appendf(pOut, "%6d ", lnA);
@@ -271,11 +277,11 @@
271277
int nContext, /* Number of lines of context */
272278
int showLn, /* Show line numbers */
273279
int html /* Render as HTML */
274280
){
275281
DLine *A; /* Left side of the diff */
276
- DLine *B; /* Right side of the diff */
282
+ DLine *B; /* Right side of the diff */
277283
int a = 0; /* Index of next line in A[] */
278284
int b = 0; /* Index of next line in B[] */
279285
int *R; /* Array of COPY/DELETE/INSERT triples */
280286
int r; /* Index into R[] */
281287
int nr; /* Number of COPY/DELETE/INSERT triples to process */
@@ -527,11 +533,11 @@
527533
sbsWriteHtml(p, "</span>");
528534
p->zLine[p->n++] = ' ';
529535
}
530536
531537
/*
532
-** The two text segments zLeft and zRight are known to be different on
538
+** The two text segments zLeft and zRight are known to be different on
533539
** both ends, but they might have a common segment in the middle. If
534540
** they do not have a common segment, return 0. If they do have a large
535541
** common segment, return 1 and before doing so set:
536542
**
537543
** aLCS[0] = start of the common segment in zLeft
@@ -712,11 +718,11 @@
712718
p->iEnd = p->iEnd2;
713719
p->zStart = p->zStart2;
714720
p->iStart2 = 0;
715721
p->iEnd2 = 0;
716722
}
717
- if( p->iStart==p->iEnd ) p->iStart = p->iEnd = -1;
723
+ if( p->iStart==p->iEnd ) p->iStart = p->iEnd = -1;
718724
sbsWriteText(p, pRight, SBS_NEWLINE);
719725
return;
720726
}
721727
722728
/* If all else fails, show a single big change between left and right */
@@ -928,11 +934,11 @@
928934
int nContext, /* Number of lines of context around each change */
929935
int width, /* Width of each column of output */
930936
int escHtml /* True to generate HTML output */
931937
){
932938
DLine *A; /* Left side of the diff */
933
- DLine *B; /* Right side of the diff */
939
+ DLine *B; /* Right side of the diff */
934940
int a = 0; /* Index of next line in A[] */
935941
int b = 0; /* Index of next line in B[] */
936942
int *R; /* Array of COPY/DELETE/INSERT triples */
937943
int r; /* Index into R[] */
938944
int nr; /* Number of COPY/DELETE/INSERT triples to process */
@@ -1024,11 +1030,11 @@
10241030
unsigned char *alignment;
10251031
ma = R[r+i*3+1]; /* Lines on left but not on right */
10261032
mb = R[r+i*3+2]; /* Lines on right but not on left */
10271033
10281034
/* If the gap between the current diff and then next diff within the
1029
- ** same block is not too great, then render them as if they are a
1035
+ ** same block is not too great, then render them as if they are a
10301036
** single diff. */
10311037
while( i<nr-1 && smallGap(&R[r+i*3]) ){
10321038
i++;
10331039
m = R[r+i*3];
10341040
ma += R[r+i*3+1] + m;
@@ -1170,11 +1176,11 @@
11701176
** input range.
11711177
**
11721178
** Ideally, the common sequence should be the longest possible common
11731179
** sequence. However, an exact computation of LCS is O(N*N) which is
11741180
** way too slow for larger files. So this routine uses an O(N)
1175
-** heuristic approximation based on hashing that usually works about
1181
+** heuristic approximation based on hashing that usually works about
11761182
** as well. But if the O(N) algorithm doesn't get a good solution
11771183
** and N is not too large, we fall back to an exact solution by
11781184
** calling optimalLCS().
11791185
*/
11801186
static void longestCommonSequence(
@@ -1203,11 +1209,11 @@
12031209
iEYb = iEYp = iS2;
12041210
mid = (iE1 + iS1)/2;
12051211
for(i=iS1; i<iE1; i++){
12061212
int limit = 0;
12071213
j = p->aTo[p->aFrom[i].h % p->nTo].iHash;
1208
- while( j>0
1214
+ while( j>0
12091215
&& (j-1<iS2 || j>=iE2 || !same_dline(&p->aFrom[i], &p->aTo[j-1]))
12101216
){
12111217
if( limit++ > 10 ){
12121218
j = 0;
12131219
break;
@@ -1260,11 +1266,11 @@
12601266
*piSX = iSXb;
12611267
*piSY = iSYb;
12621268
*piEX = iEXb;
12631269
*piEY = iEYb;
12641270
}
1265
- /* printf("LCS(%d..%d/%d..%d) = %d..%d/%d..%d\n",
1271
+ /* printf("LCS(%d..%d/%d..%d) = %d..%d/%d..%d\n",
12661272
iS1, iE1, iS2, iE2, *piSX, *piEX, *piSY, *piEY); */
12671273
}
12681274
12691275
/*
12701276
** Expand the size of aEdit[] array to hold at least nEdit elements.
@@ -1295,11 +1301,11 @@
12951301
}
12961302
if( nCopy==0 && nDel==0 ){
12971303
p->aEdit[p->nEdit-1] += nIns;
12981304
return;
12991305
}
1300
- }
1306
+ }
13011307
if( p->nEdit+3>p->nEditAlloc ){
13021308
expandEdit(p, p->nEdit*2 + 15);
13031309
if( p->aEdit==0 ) return;
13041310
}
13051311
p->aEdit[p->nEdit++] = nCopy;
@@ -1523,11 +1529,11 @@
15231529
15241530
/*
15251531
** Generate a report of the differences between files pA and pB.
15261532
** If pOut is not NULL then a unified diff is appended there. It
15271533
** is assumed that pOut has already been initialized. If pOut is
1528
-** NULL, then a pointer to an array of integers is returned.
1534
+** NULL, then a pointer to an array of integers is returned.
15291535
** The integers come in triples. For each triple,
15301536
** the elements are the number of lines copied, the number of
15311537
** lines deleted, and the number of lines inserted. The vector
15321538
** is terminated by a triple of all zeros.
15331539
**
@@ -1540,11 +1546,11 @@
15401546
Blob *pB_Blob, /* TO file */
15411547
Blob *pOut, /* Write diff here if not NULL */
15421548
u64 diffFlags /* DIFF_* flags defined above */
15431549
){
15441550
int ignoreEolWs; /* Ignore whitespace at the end of lines */
1545
- int nContext; /* Amount of context to display */
1551
+ int nContext; /* Amount of context to display */
15461552
DContext c;
15471553
15481554
if( diffFlags & DIFF_INVERT ){
15491555
Blob *pTemp = pA_Blob;
15501556
pA_Blob = pB_Blob;
@@ -1596,11 +1602,11 @@
15961602
}
15971603
}
15981604
15991605
/*
16001606
** Process diff-related command-line options and return an appropriate
1601
-** "diffFlags" integer.
1607
+** "diffFlags" integer.
16021608
**
16031609
** --brief Show filenames only DIFF_BRIEF
16041610
** --context|-c N N lines of context. DIFF_CONTEXT_MASK
16051611
** --html Format for HTML DIFF_HTML
16061612
** --invert Invert the diff DIFF_INVERT
@@ -1767,11 +1773,11 @@
17671773
p->c.aEdit = 0;
17681774
p->c.nEdit = 0;
17691775
p->c.nEditAlloc = 0;
17701776
17711777
/* Clear out the from file */
1772
- free(p->c.aFrom);
1778
+ free(p->c.aFrom);
17731779
17741780
/* Return no errors */
17751781
return 0;
17761782
}
17771783
@@ -1838,11 +1844,11 @@
18381844
db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)");
18391845
if( iLimit<=0 ) iLimit = 1000000000;
18401846
compute_direct_ancestors(mid, iLimit);
18411847
annotation_start(p, &toAnnotate);
18421848
1843
- db_prepare(&q,
1849
+ db_prepare(&q,
18441850
"SELECT mlink.fid,"
18451851
" (SELECT uuid FROM blob WHERE rid=mlink.%s),"
18461852
" date(event.mtime), "
18471853
" coalesce(event.euser,event.user) "
18481854
" FROM ancestor, mlink, event"
@@ -1860,11 +1866,11 @@
18601866
const char *zUuid = db_column_text(&q, 1);
18611867
const char *zDate = db_column_text(&q, 2);
18621868
const char *zUser = db_column_text(&q, 3);
18631869
if( webLabel ){
18641870
zLabel = mprintf(
1865
- "<a href='%R/info/%s' target='infowindow'>%.10s</a> %s %13.13s",
1871
+ "<a href='%R/info/%s' target='infowindow'>%.10s</a> %s %13.13s",
18661872
zUuid, zUuid, zDate, zUser
18671873
);
18681874
}else{
18691875
zLabel = mprintf("%.10s %s %13.13s", zUuid, zDate, zUser);
18701876
}
@@ -1995,9 +2001,9 @@
19952001
printf("version %3d: %s\n", i+1, ann.azVers[i]);
19962002
}
19972003
printf("---------------------------------------------------\n");
19982004
}
19992005
for(i=0; i<ann.nOrig; i++){
2000
- fossil_print("%s: %.*s\n",
2006
+ fossil_print("%s: %.*s\n",
20012007
ann.aOrig[i].zSrc, ann.aOrig[i].n, ann.aOrig[i].z);
20022008
}
20032009
}
20042010
--- src/diff.c
+++ src/diff.c
@@ -48,10 +48,11 @@
48 "cannot compute difference between binary files\n"
49
50 #define DIFF_CANNOT_COMPUTE_SYMLINK \
51 "cannot compute difference between symlink and regular file\n"
52
 
53 #endif /* INTERFACE */
54
55 /*
56 ** Maximum length of a line in a text file. (8192)
57 */
@@ -106,11 +107,11 @@
106 int nTo; /* Number of lines in aTo[] */
107 };
108
109 /*
110 ** Return an array of DLine objects containing a pointer to the
111 ** start of each line and a hash of that line. The lower
112 ** bits of the hash store the length of each line.
113 **
114 ** Trailing whitespace is removed from each line. 2010-08-20: Not any
115 ** more. If trailing whitespace is ignored, the "patch" command gets
116 ** confused by the diff output. Ticket [a9f7b23c2e376af5b0e5b]
@@ -169,35 +170,40 @@
169 *pnLine = nLine;
170 return a;
171 }
172
173 /*
174 ** Returns non-zero if the specified content appears to be binary or
175 ** contains a line that is too long.
 
 
176 */
177 int looks_like_binary(const Blob *pContent){
178 const char *z = blob_buffer(pContent);
179 int n = blob_size(pContent);
180 int i, j;
 
181
182 /* Count the number of lines. Allocate space to hold
183 ** the returned array.
184 */
185 for(i=j=0; i<n; i++, j++){
186 int c = z[i];
187 if( c==0 ) return 1; /* \000 byte in a file -> binary */
188 if( c=='\n' ){
 
 
 
189 if( j>LENGTH_MASK ){
190 return 1; /* Very long line -> binary */
191 }
192 j = 0;
193 }
194 }
195 if( j>LENGTH_MASK ){
196 return 1; /* Very long line -> binary */
197 }
198 return 0; /* No problems seen -> not binary */
199 }
200
201 /*
202 ** Return true if two DLine elements are identical.
203 */
@@ -241,11 +247,11 @@
241
242 /*
243 ** Add two line numbers to the beginning of an output line for a context
244 ** diff. One or of the other of the two numbers might be zero, which means
245 ** to leave that number field blank. The "html" parameter means to format
246 ** the output for HTML.
247 */
248 static void appendDiffLineno(Blob *pOut, int lnA, int lnB, int html){
249 if( html ) blob_append(pOut, "<span class=\"diffln\">", -1);
250 if( lnA>0 ){
251 blob_appendf(pOut, "%6d ", lnA);
@@ -271,11 +277,11 @@
271 int nContext, /* Number of lines of context */
272 int showLn, /* Show line numbers */
273 int html /* Render as HTML */
274 ){
275 DLine *A; /* Left side of the diff */
276 DLine *B; /* Right side of the diff */
277 int a = 0; /* Index of next line in A[] */
278 int b = 0; /* Index of next line in B[] */
279 int *R; /* Array of COPY/DELETE/INSERT triples */
280 int r; /* Index into R[] */
281 int nr; /* Number of COPY/DELETE/INSERT triples to process */
@@ -527,11 +533,11 @@
527 sbsWriteHtml(p, "</span>");
528 p->zLine[p->n++] = ' ';
529 }
530
531 /*
532 ** The two text segments zLeft and zRight are known to be different on
533 ** both ends, but they might have a common segment in the middle. If
534 ** they do not have a common segment, return 0. If they do have a large
535 ** common segment, return 1 and before doing so set:
536 **
537 ** aLCS[0] = start of the common segment in zLeft
@@ -712,11 +718,11 @@
712 p->iEnd = p->iEnd2;
713 p->zStart = p->zStart2;
714 p->iStart2 = 0;
715 p->iEnd2 = 0;
716 }
717 if( p->iStart==p->iEnd ) p->iStart = p->iEnd = -1;
718 sbsWriteText(p, pRight, SBS_NEWLINE);
719 return;
720 }
721
722 /* If all else fails, show a single big change between left and right */
@@ -928,11 +934,11 @@
928 int nContext, /* Number of lines of context around each change */
929 int width, /* Width of each column of output */
930 int escHtml /* True to generate HTML output */
931 ){
932 DLine *A; /* Left side of the diff */
933 DLine *B; /* Right side of the diff */
934 int a = 0; /* Index of next line in A[] */
935 int b = 0; /* Index of next line in B[] */
936 int *R; /* Array of COPY/DELETE/INSERT triples */
937 int r; /* Index into R[] */
938 int nr; /* Number of COPY/DELETE/INSERT triples to process */
@@ -1024,11 +1030,11 @@
1024 unsigned char *alignment;
1025 ma = R[r+i*3+1]; /* Lines on left but not on right */
1026 mb = R[r+i*3+2]; /* Lines on right but not on left */
1027
1028 /* If the gap between the current diff and then next diff within the
1029 ** same block is not too great, then render them as if they are a
1030 ** single diff. */
1031 while( i<nr-1 && smallGap(&R[r+i*3]) ){
1032 i++;
1033 m = R[r+i*3];
1034 ma += R[r+i*3+1] + m;
@@ -1170,11 +1176,11 @@
1170 ** input range.
1171 **
1172 ** Ideally, the common sequence should be the longest possible common
1173 ** sequence. However, an exact computation of LCS is O(N*N) which is
1174 ** way too slow for larger files. So this routine uses an O(N)
1175 ** heuristic approximation based on hashing that usually works about
1176 ** as well. But if the O(N) algorithm doesn't get a good solution
1177 ** and N is not too large, we fall back to an exact solution by
1178 ** calling optimalLCS().
1179 */
1180 static void longestCommonSequence(
@@ -1203,11 +1209,11 @@
1203 iEYb = iEYp = iS2;
1204 mid = (iE1 + iS1)/2;
1205 for(i=iS1; i<iE1; i++){
1206 int limit = 0;
1207 j = p->aTo[p->aFrom[i].h % p->nTo].iHash;
1208 while( j>0
1209 && (j-1<iS2 || j>=iE2 || !same_dline(&p->aFrom[i], &p->aTo[j-1]))
1210 ){
1211 if( limit++ > 10 ){
1212 j = 0;
1213 break;
@@ -1260,11 +1266,11 @@
1260 *piSX = iSXb;
1261 *piSY = iSYb;
1262 *piEX = iEXb;
1263 *piEY = iEYb;
1264 }
1265 /* printf("LCS(%d..%d/%d..%d) = %d..%d/%d..%d\n",
1266 iS1, iE1, iS2, iE2, *piSX, *piEX, *piSY, *piEY); */
1267 }
1268
1269 /*
1270 ** Expand the size of aEdit[] array to hold at least nEdit elements.
@@ -1295,11 +1301,11 @@
1295 }
1296 if( nCopy==0 && nDel==0 ){
1297 p->aEdit[p->nEdit-1] += nIns;
1298 return;
1299 }
1300 }
1301 if( p->nEdit+3>p->nEditAlloc ){
1302 expandEdit(p, p->nEdit*2 + 15);
1303 if( p->aEdit==0 ) return;
1304 }
1305 p->aEdit[p->nEdit++] = nCopy;
@@ -1523,11 +1529,11 @@
1523
1524 /*
1525 ** Generate a report of the differences between files pA and pB.
1526 ** If pOut is not NULL then a unified diff is appended there. It
1527 ** is assumed that pOut has already been initialized. If pOut is
1528 ** NULL, then a pointer to an array of integers is returned.
1529 ** The integers come in triples. For each triple,
1530 ** the elements are the number of lines copied, the number of
1531 ** lines deleted, and the number of lines inserted. The vector
1532 ** is terminated by a triple of all zeros.
1533 **
@@ -1540,11 +1546,11 @@
1540 Blob *pB_Blob, /* TO file */
1541 Blob *pOut, /* Write diff here if not NULL */
1542 u64 diffFlags /* DIFF_* flags defined above */
1543 ){
1544 int ignoreEolWs; /* Ignore whitespace at the end of lines */
1545 int nContext; /* Amount of context to display */
1546 DContext c;
1547
1548 if( diffFlags & DIFF_INVERT ){
1549 Blob *pTemp = pA_Blob;
1550 pA_Blob = pB_Blob;
@@ -1596,11 +1602,11 @@
1596 }
1597 }
1598
1599 /*
1600 ** Process diff-related command-line options and return an appropriate
1601 ** "diffFlags" integer.
1602 **
1603 ** --brief Show filenames only DIFF_BRIEF
1604 ** --context|-c N N lines of context. DIFF_CONTEXT_MASK
1605 ** --html Format for HTML DIFF_HTML
1606 ** --invert Invert the diff DIFF_INVERT
@@ -1767,11 +1773,11 @@
1767 p->c.aEdit = 0;
1768 p->c.nEdit = 0;
1769 p->c.nEditAlloc = 0;
1770
1771 /* Clear out the from file */
1772 free(p->c.aFrom);
1773
1774 /* Return no errors */
1775 return 0;
1776 }
1777
@@ -1838,11 +1844,11 @@
1838 db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)");
1839 if( iLimit<=0 ) iLimit = 1000000000;
1840 compute_direct_ancestors(mid, iLimit);
1841 annotation_start(p, &toAnnotate);
1842
1843 db_prepare(&q,
1844 "SELECT mlink.fid,"
1845 " (SELECT uuid FROM blob WHERE rid=mlink.%s),"
1846 " date(event.mtime), "
1847 " coalesce(event.euser,event.user) "
1848 " FROM ancestor, mlink, event"
@@ -1860,11 +1866,11 @@
1860 const char *zUuid = db_column_text(&q, 1);
1861 const char *zDate = db_column_text(&q, 2);
1862 const char *zUser = db_column_text(&q, 3);
1863 if( webLabel ){
1864 zLabel = mprintf(
1865 "<a href='%R/info/%s' target='infowindow'>%.10s</a> %s %13.13s",
1866 zUuid, zUuid, zDate, zUser
1867 );
1868 }else{
1869 zLabel = mprintf("%.10s %s %13.13s", zUuid, zDate, zUser);
1870 }
@@ -1995,9 +2001,9 @@
1995 printf("version %3d: %s\n", i+1, ann.azVers[i]);
1996 }
1997 printf("---------------------------------------------------\n");
1998 }
1999 for(i=0; i<ann.nOrig; i++){
2000 fossil_print("%s: %.*s\n",
2001 ann.aOrig[i].zSrc, ann.aOrig[i].n, ann.aOrig[i].z);
2002 }
2003 }
2004
--- src/diff.c
+++ src/diff.c
@@ -48,10 +48,11 @@
48 "cannot compute difference between binary files\n"
49
50 #define DIFF_CANNOT_COMPUTE_SYMLINK \
51 "cannot compute difference between symlink and regular file\n"
52
53 #define looks_like_binary(blob) (!(looks_like_text(blob)&1))
54 #endif /* INTERFACE */
55
56 /*
57 ** Maximum length of a line in a text file. (8192)
58 */
@@ -106,11 +107,11 @@
107 int nTo; /* Number of lines in aTo[] */
108 };
109
110 /*
111 ** Return an array of DLine objects containing a pointer to the
112 ** start of each line and a hash of that line. The lower
113 ** bits of the hash store the length of each line.
114 **
115 ** Trailing whitespace is removed from each line. 2010-08-20: Not any
116 ** more. If trailing whitespace is ignored, the "patch" command gets
117 ** confused by the diff output. Ticket [a9f7b23c2e376af5b0e5b]
@@ -169,35 +170,40 @@
170 *pnLine = nLine;
171 return a;
172 }
173
174 /*
175 ** Returns 1, if the file appears text, and does not contain CrLf
176 ** Returns 0 if the specified content appears to be binary or
177 ** contains a line that is too long
178 ** Returns -1, if the file appears text, but it contains CrLf
179 */
180 int looks_like_text(const Blob *pContent){
181 const char *z = blob_buffer(pContent);
182 int n = blob_size(pContent);
183 int i, j;
184 int result = 1;
185
186 /* Check individual lines.
 
187 */
188 for(i=j=0; i<n; i++, j++){
189 int c = z[i];
190 if( c==0 ) return 1; /* \000 byte in a file -> binary */
191 if( c=='\n' ){
192 if( i>0 && z[i-1]=='\r' ){
193 result = -1; /* Contains CrLf, continue */
194 }
195 if( j>LENGTH_MASK ){
196 return 0; /* Very long line -> binary */
197 }
198 j = 0;
199 }
200 }
201 if( j>LENGTH_MASK ){
202 return 0; /* Very long line -> binary */
203 }
204 return result; /* No problems seen -> not binary */
205 }
206
207 /*
208 ** Return true if two DLine elements are identical.
209 */
@@ -241,11 +247,11 @@
247
248 /*
249 ** Add two line numbers to the beginning of an output line for a context
250 ** diff. One or of the other of the two numbers might be zero, which means
251 ** to leave that number field blank. The "html" parameter means to format
252 ** the output for HTML.
253 */
254 static void appendDiffLineno(Blob *pOut, int lnA, int lnB, int html){
255 if( html ) blob_append(pOut, "<span class=\"diffln\">", -1);
256 if( lnA>0 ){
257 blob_appendf(pOut, "%6d ", lnA);
@@ -271,11 +277,11 @@
277 int nContext, /* Number of lines of context */
278 int showLn, /* Show line numbers */
279 int html /* Render as HTML */
280 ){
281 DLine *A; /* Left side of the diff */
282 DLine *B; /* Right side of the diff */
283 int a = 0; /* Index of next line in A[] */
284 int b = 0; /* Index of next line in B[] */
285 int *R; /* Array of COPY/DELETE/INSERT triples */
286 int r; /* Index into R[] */
287 int nr; /* Number of COPY/DELETE/INSERT triples to process */
@@ -527,11 +533,11 @@
533 sbsWriteHtml(p, "</span>");
534 p->zLine[p->n++] = ' ';
535 }
536
537 /*
538 ** The two text segments zLeft and zRight are known to be different on
539 ** both ends, but they might have a common segment in the middle. If
540 ** they do not have a common segment, return 0. If they do have a large
541 ** common segment, return 1 and before doing so set:
542 **
543 ** aLCS[0] = start of the common segment in zLeft
@@ -712,11 +718,11 @@
718 p->iEnd = p->iEnd2;
719 p->zStart = p->zStart2;
720 p->iStart2 = 0;
721 p->iEnd2 = 0;
722 }
723 if( p->iStart==p->iEnd ) p->iStart = p->iEnd = -1;
724 sbsWriteText(p, pRight, SBS_NEWLINE);
725 return;
726 }
727
728 /* If all else fails, show a single big change between left and right */
@@ -928,11 +934,11 @@
934 int nContext, /* Number of lines of context around each change */
935 int width, /* Width of each column of output */
936 int escHtml /* True to generate HTML output */
937 ){
938 DLine *A; /* Left side of the diff */
939 DLine *B; /* Right side of the diff */
940 int a = 0; /* Index of next line in A[] */
941 int b = 0; /* Index of next line in B[] */
942 int *R; /* Array of COPY/DELETE/INSERT triples */
943 int r; /* Index into R[] */
944 int nr; /* Number of COPY/DELETE/INSERT triples to process */
@@ -1024,11 +1030,11 @@
1030 unsigned char *alignment;
1031 ma = R[r+i*3+1]; /* Lines on left but not on right */
1032 mb = R[r+i*3+2]; /* Lines on right but not on left */
1033
1034 /* If the gap between the current diff and then next diff within the
1035 ** same block is not too great, then render them as if they are a
1036 ** single diff. */
1037 while( i<nr-1 && smallGap(&R[r+i*3]) ){
1038 i++;
1039 m = R[r+i*3];
1040 ma += R[r+i*3+1] + m;
@@ -1170,11 +1176,11 @@
1176 ** input range.
1177 **
1178 ** Ideally, the common sequence should be the longest possible common
1179 ** sequence. However, an exact computation of LCS is O(N*N) which is
1180 ** way too slow for larger files. So this routine uses an O(N)
1181 ** heuristic approximation based on hashing that usually works about
1182 ** as well. But if the O(N) algorithm doesn't get a good solution
1183 ** and N is not too large, we fall back to an exact solution by
1184 ** calling optimalLCS().
1185 */
1186 static void longestCommonSequence(
@@ -1203,11 +1209,11 @@
1209 iEYb = iEYp = iS2;
1210 mid = (iE1 + iS1)/2;
1211 for(i=iS1; i<iE1; i++){
1212 int limit = 0;
1213 j = p->aTo[p->aFrom[i].h % p->nTo].iHash;
1214 while( j>0
1215 && (j-1<iS2 || j>=iE2 || !same_dline(&p->aFrom[i], &p->aTo[j-1]))
1216 ){
1217 if( limit++ > 10 ){
1218 j = 0;
1219 break;
@@ -1260,11 +1266,11 @@
1266 *piSX = iSXb;
1267 *piSY = iSYb;
1268 *piEX = iEXb;
1269 *piEY = iEYb;
1270 }
1271 /* printf("LCS(%d..%d/%d..%d) = %d..%d/%d..%d\n",
1272 iS1, iE1, iS2, iE2, *piSX, *piEX, *piSY, *piEY); */
1273 }
1274
1275 /*
1276 ** Expand the size of aEdit[] array to hold at least nEdit elements.
@@ -1295,11 +1301,11 @@
1301 }
1302 if( nCopy==0 && nDel==0 ){
1303 p->aEdit[p->nEdit-1] += nIns;
1304 return;
1305 }
1306 }
1307 if( p->nEdit+3>p->nEditAlloc ){
1308 expandEdit(p, p->nEdit*2 + 15);
1309 if( p->aEdit==0 ) return;
1310 }
1311 p->aEdit[p->nEdit++] = nCopy;
@@ -1523,11 +1529,11 @@
1529
1530 /*
1531 ** Generate a report of the differences between files pA and pB.
1532 ** If pOut is not NULL then a unified diff is appended there. It
1533 ** is assumed that pOut has already been initialized. If pOut is
1534 ** NULL, then a pointer to an array of integers is returned.
1535 ** The integers come in triples. For each triple,
1536 ** the elements are the number of lines copied, the number of
1537 ** lines deleted, and the number of lines inserted. The vector
1538 ** is terminated by a triple of all zeros.
1539 **
@@ -1540,11 +1546,11 @@
1546 Blob *pB_Blob, /* TO file */
1547 Blob *pOut, /* Write diff here if not NULL */
1548 u64 diffFlags /* DIFF_* flags defined above */
1549 ){
1550 int ignoreEolWs; /* Ignore whitespace at the end of lines */
1551 int nContext; /* Amount of context to display */
1552 DContext c;
1553
1554 if( diffFlags & DIFF_INVERT ){
1555 Blob *pTemp = pA_Blob;
1556 pA_Blob = pB_Blob;
@@ -1596,11 +1602,11 @@
1602 }
1603 }
1604
1605 /*
1606 ** Process diff-related command-line options and return an appropriate
1607 ** "diffFlags" integer.
1608 **
1609 ** --brief Show filenames only DIFF_BRIEF
1610 ** --context|-c N N lines of context. DIFF_CONTEXT_MASK
1611 ** --html Format for HTML DIFF_HTML
1612 ** --invert Invert the diff DIFF_INVERT
@@ -1767,11 +1773,11 @@
1773 p->c.aEdit = 0;
1774 p->c.nEdit = 0;
1775 p->c.nEditAlloc = 0;
1776
1777 /* Clear out the from file */
1778 free(p->c.aFrom);
1779
1780 /* Return no errors */
1781 return 0;
1782 }
1783
@@ -1838,11 +1844,11 @@
1844 db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)");
1845 if( iLimit<=0 ) iLimit = 1000000000;
1846 compute_direct_ancestors(mid, iLimit);
1847 annotation_start(p, &toAnnotate);
1848
1849 db_prepare(&q,
1850 "SELECT mlink.fid,"
1851 " (SELECT uuid FROM blob WHERE rid=mlink.%s),"
1852 " date(event.mtime), "
1853 " coalesce(event.euser,event.user) "
1854 " FROM ancestor, mlink, event"
@@ -1860,11 +1866,11 @@
1866 const char *zUuid = db_column_text(&q, 1);
1867 const char *zDate = db_column_text(&q, 2);
1868 const char *zUser = db_column_text(&q, 3);
1869 if( webLabel ){
1870 zLabel = mprintf(
1871 "<a href='%R/info/%s' target='infowindow'>%.10s</a> %s %13.13s",
1872 zUuid, zUuid, zDate, zUser
1873 );
1874 }else{
1875 zLabel = mprintf("%.10s %s %13.13s", zUuid, zDate, zUser);
1876 }
@@ -1995,9 +2001,9 @@
2001 printf("version %3d: %s\n", i+1, ann.azVers[i]);
2002 }
2003 printf("---------------------------------------------------\n");
2004 }
2005 for(i=0; i<ann.nOrig; i++){
2006 fossil_print("%s: %.*s\n",
2007 ann.aOrig[i].zSrc, ann.aOrig[i].n, ann.aOrig[i].z);
2008 }
2009 }
2010

Keyboard Shortcuts

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