Fossil SCM

Another adjustment to handle some corner cases.

mistachkin 2016-10-03 23:10 binDiffFix
Commit 8017c358ba77159dcdb836c0fa305e94cf701c20
3 files changed +24 +26 -10 +1 -1
+24
--- src/blob.c
+++ src/blob.c
@@ -87,10 +87,34 @@
8787
#else
8888
#define assert_blob_is_reset(x)
8989
#endif
9090
9191
92
+/*
93
+** The built-in strchr() function cannot deal with NUL characters.
94
+** So here is a substitute. If the character being sought after
95
+** is not NUL, this function will call the built-in strchr(). In
96
+** that case, the "n" argument is ignored. If the value of "n"
97
+** is less than zero, the length of the "str" value will be used;
98
+** however, that is unlikely to produce a useful result.
99
+*/
100
+char *fossil_strchr(
101
+ const char *str, /* Null-terminated string being searched. */
102
+ int n, /* Length of the string being searched. */
103
+ int c /* Character being sought. */
104
+){
105
+ if( c=='\0' ){
106
+ int i = 0;
107
+ if( n<0 ) n = strlen(str); /* pedantic */
108
+ for(; i<n; i++){
109
+ if( str[i]==c ) return str+i;
110
+ }
111
+ return 0;
112
+ }else{
113
+ return strchr(str, c);
114
+ }
115
+}
92116
93117
/*
94118
** We find that the built-in isspace() function does not work for
95119
** some international character sets. So here is a substitute.
96120
*/
97121
--- src/blob.c
+++ src/blob.c
@@ -87,10 +87,34 @@
87 #else
88 #define assert_blob_is_reset(x)
89 #endif
90
91
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
93 /*
94 ** We find that the built-in isspace() function does not work for
95 ** some international character sets. So here is a substitute.
96 */
97
--- src/blob.c
+++ src/blob.c
@@ -87,10 +87,34 @@
87 #else
88 #define assert_blob_is_reset(x)
89 #endif
90
91
92 /*
93 ** The built-in strchr() function cannot deal with NUL characters.
94 ** So here is a substitute. If the character being sought after
95 ** is not NUL, this function will call the built-in strchr(). In
96 ** that case, the "n" argument is ignored. If the value of "n"
97 ** is less than zero, the length of the "str" value will be used;
98 ** however, that is unlikely to produce a useful result.
99 */
100 char *fossil_strchr(
101 const char *str, /* Null-terminated string being searched. */
102 int n, /* Length of the string being searched. */
103 int c /* Character being sought. */
104 ){
105 if( c=='\0' ){
106 int i = 0;
107 if( n<0 ) n = strlen(str); /* pedantic */
108 for(; i<n; i++){
109 if( str[i]==c ) return str+i;
110 }
111 return 0;
112 }else{
113 return strchr(str, c);
114 }
115 }
116
117 /*
118 ** We find that the built-in isspace() function does not work for
119 ** some international character sets. So here is a substitute.
120 */
121
+26 -10
--- src/diff.c
+++ src/diff.c
@@ -115,10 +115,26 @@
115115
int nFrom; /* Number of lines in aFrom[] */
116116
DLine *aTo; /* File on right side of the diff */
117117
int nTo; /* Number of lines in aTo[] */
118118
int (*same_fn)(const DLine*,const DLine*); /* comparison function */
119119
};
120
+
121
+/*
122
+** Count the number of lines in the input string. Include the last line
123
+** in the count even if it lacks the \n terminator. If an empty string
124
+** is specified, the number of lines is zero.
125
+*/
126
+static int count_lines(
127
+ const char *z,
128
+ int n
129
+){
130
+ int nLine;
131
+ const char *zNL, *z2;
132
+ for(nLine=0, z2=z; (zNL = fossil_strchr(z2,-1,'\n'))!=0; z2=zNL+1, nLine++){}
133
+ if( z2[0]!=0 ) nLine++;
134
+ return nLine;
135
+}
120136
121137
/*
122138
** Return an array of DLine objects containing a pointer to the
123139
** start of each line and a hash of that line. The lower
124140
** bits of the hash store the length of each line.
@@ -140,27 +156,27 @@
140156
u64 diffFlags
141157
){
142158
int nLine, i, k, nn, s, x;
143159
unsigned int h, h2;
144160
DLine *a;
145
- const char *zNL, *z2;
146
-
147
- /* Count the number of lines in the input file. Include the last line
148
- ** in the count even if it lacks the \n terminator
149
- */
150
- for(nLine=0, z2=z; (zNL = strchr(z2,'\n'))!=0; z2=zNL+1, nLine++){}
151
- if( z2[0]!=0 ) nLine++;
152
-
161
+ const char *zNL;
162
+
163
+ nLine = count_lines(z, n);
164
+ assert( nLine>0 || z[0]==0 );
153165
a = fossil_malloc( sizeof(a[0])*nLine );
154166
memset(a, 0, sizeof(a[0])*nLine);
155167
if( nLine==0 ){
168
+ if( fossil_strchr(z,n,'\0')!=0 ){
169
+ fossil_free(a);
170
+ return 0;
171
+ }
156172
*pnLine = 0;
157173
return a;
158174
}
159175
i = 0;
160176
do{
161
- zNL = strchr(z,'\n');
177
+ zNL = fossil_strchr(z,n,'\n');
162178
if( zNL==0 ) zNL = z+n;
163179
nn = (int)(zNL - z);
164180
if( nn>LENGTH_MASK ){
165181
fossil_free(a);
166182
return 0;
@@ -204,11 +220,11 @@
204220
a[i].indent = s;
205221
a[i].h = h = (h<<LENGTH_MASK_SZ) | (k-s);
206222
h2 = h % nLine;
207223
a[i].iNext = a[h2].iHash;
208224
a[h2].iHash = i+1;
209
- z += nn+1;
225
+ z += nn+1; n -= nn+1;
210226
i++;
211227
}while( zNL[0] && zNL[1] );
212228
assert( i==nLine );
213229
214230
/* Return results */
215231
--- src/diff.c
+++ src/diff.c
@@ -115,10 +115,26 @@
115 int nFrom; /* Number of lines in aFrom[] */
116 DLine *aTo; /* File on right side of the diff */
117 int nTo; /* Number of lines in aTo[] */
118 int (*same_fn)(const DLine*,const DLine*); /* comparison function */
119 };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
121 /*
122 ** Return an array of DLine objects containing a pointer to the
123 ** start of each line and a hash of that line. The lower
124 ** bits of the hash store the length of each line.
@@ -140,27 +156,27 @@
140 u64 diffFlags
141 ){
142 int nLine, i, k, nn, s, x;
143 unsigned int h, h2;
144 DLine *a;
145 const char *zNL, *z2;
146
147 /* Count the number of lines in the input file. Include the last line
148 ** in the count even if it lacks the \n terminator
149 */
150 for(nLine=0, z2=z; (zNL = strchr(z2,'\n'))!=0; z2=zNL+1, nLine++){}
151 if( z2[0]!=0 ) nLine++;
152
153 a = fossil_malloc( sizeof(a[0])*nLine );
154 memset(a, 0, sizeof(a[0])*nLine);
155 if( nLine==0 ){
 
 
 
 
156 *pnLine = 0;
157 return a;
158 }
159 i = 0;
160 do{
161 zNL = strchr(z,'\n');
162 if( zNL==0 ) zNL = z+n;
163 nn = (int)(zNL - z);
164 if( nn>LENGTH_MASK ){
165 fossil_free(a);
166 return 0;
@@ -204,11 +220,11 @@
204 a[i].indent = s;
205 a[i].h = h = (h<<LENGTH_MASK_SZ) | (k-s);
206 h2 = h % nLine;
207 a[i].iNext = a[h2].iHash;
208 a[h2].iHash = i+1;
209 z += nn+1;
210 i++;
211 }while( zNL[0] && zNL[1] );
212 assert( i==nLine );
213
214 /* Return results */
215
--- src/diff.c
+++ src/diff.c
@@ -115,10 +115,26 @@
115 int nFrom; /* Number of lines in aFrom[] */
116 DLine *aTo; /* File on right side of the diff */
117 int nTo; /* Number of lines in aTo[] */
118 int (*same_fn)(const DLine*,const DLine*); /* comparison function */
119 };
120
121 /*
122 ** Count the number of lines in the input string. Include the last line
123 ** in the count even if it lacks the \n terminator. If an empty string
124 ** is specified, the number of lines is zero.
125 */
126 static int count_lines(
127 const char *z,
128 int n
129 ){
130 int nLine;
131 const char *zNL, *z2;
132 for(nLine=0, z2=z; (zNL = fossil_strchr(z2,-1,'\n'))!=0; z2=zNL+1, nLine++){}
133 if( z2[0]!=0 ) nLine++;
134 return nLine;
135 }
136
137 /*
138 ** Return an array of DLine objects containing a pointer to the
139 ** start of each line and a hash of that line. The lower
140 ** bits of the hash store the length of each line.
@@ -140,27 +156,27 @@
156 u64 diffFlags
157 ){
158 int nLine, i, k, nn, s, x;
159 unsigned int h, h2;
160 DLine *a;
161 const char *zNL;
162
163 nLine = count_lines(z, n);
164 assert( nLine>0 || z[0]==0 );
 
 
 
 
165 a = fossil_malloc( sizeof(a[0])*nLine );
166 memset(a, 0, sizeof(a[0])*nLine);
167 if( nLine==0 ){
168 if( fossil_strchr(z,n,'\0')!=0 ){
169 fossil_free(a);
170 return 0;
171 }
172 *pnLine = 0;
173 return a;
174 }
175 i = 0;
176 do{
177 zNL = fossil_strchr(z,n,'\n');
178 if( zNL==0 ) zNL = z+n;
179 nn = (int)(zNL - z);
180 if( nn>LENGTH_MASK ){
181 fossil_free(a);
182 return 0;
@@ -204,11 +220,11 @@
220 a[i].indent = s;
221 a[i].h = h = (h<<LENGTH_MASK_SZ) | (k-s);
222 h2 = h % nLine;
223 a[i].iNext = a[h2].iHash;
224 a[h2].iHash = i+1;
225 z += nn+1; n -= nn+1;
226 i++;
227 }while( zNL[0] && zNL[1] );
228 assert( i==nLine );
229
230 /* Return results */
231
+1 -1
--- test/diff.test
+++ test/diff.test
@@ -24,11 +24,11 @@
2424
2525
###################################
2626
# Tests of binary file detection. #
2727
###################################
2828
29
-file mkdir [file join .fossil-settings]
29
+file mkdir .fossil-settings
3030
write_file [file join .fossil-settings binary-glob] "*"
3131
3232
write_file file0.dat ""; # no content.
3333
write_file file1.dat "test file 1 (one line no term)."
3434
write_file file2.dat "test file 2 (NUL character).\0"
3535
--- test/diff.test
+++ test/diff.test
@@ -24,11 +24,11 @@
24
25 ###################################
26 # Tests of binary file detection. #
27 ###################################
28
29 file mkdir [file join .fossil-settings]
30 write_file [file join .fossil-settings binary-glob] "*"
31
32 write_file file0.dat ""; # no content.
33 write_file file1.dat "test file 1 (one line no term)."
34 write_file file2.dat "test file 2 (NUL character).\0"
35
--- test/diff.test
+++ test/diff.test
@@ -24,11 +24,11 @@
24
25 ###################################
26 # Tests of binary file detection. #
27 ###################################
28
29 file mkdir .fossil-settings
30 write_file [file join .fossil-settings binary-glob] "*"
31
32 write_file file0.dat ""; # no content.
33 write_file file1.dat "test file 1 (one line no term)."
34 write_file file2.dat "test file 2 (NUL character).\0"
35

Keyboard Shortcuts

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