aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2006-05-29 12:12:45 +0000
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2006-05-29 12:12:45 +0000
commitbbc225e13d0b4388a095c98c86caff6dd675962b (patch)
tree5e1eb47b2c43663d199bb185af6ee85424df39db
parentd2c306e862abf49dd4b1ff1d1bd1a789317b7905 (diff)
downloadbusybox-w32-bbc225e13d0b4388a095c98c86caff6dd675962b.tar.gz
busybox-w32-bbc225e13d0b4388a095c98c86caff6dd675962b.tar.bz2
busybox-w32-bbc225e13d0b4388a095c98c86caff6dd675962b.zip
- just whitespace
-rw-r--r--coreutils/diff.c1472
1 files changed, 741 insertions, 731 deletions
diff --git a/coreutils/diff.c b/coreutils/diff.c
index a1a74d51e..57b32eb78 100644
--- a/coreutils/diff.c
+++ b/coreutils/diff.c
@@ -36,9 +36,9 @@
36/* 36/*
37 * Output flags 37 * Output flags
38 */ 38 */
39#define D_HEADER 1 /* Print a header/footer between files */ 39#define D_HEADER 1 /* Print a header/footer between files */
40#define D_EMPTY1 2 /* Treat first file as empty (/dev/null) */ 40#define D_EMPTY1 2 /* Treat first file as empty (/dev/null) */
41#define D_EMPTY2 4 /* Treat second file as empty (/dev/null) */ 41#define D_EMPTY2 4 /* Treat second file as empty (/dev/null) */
42 42
43/* 43/*
44 * Status values for print_status() and diffreg() return values 44 * Status values for print_status() and diffreg() return values
@@ -68,6 +68,7 @@
68 68
69/* Command line options */ 69/* Command line options */
70static unsigned long cmd_flags; 70static unsigned long cmd_flags;
71
71#define FLAG_a (1<<0) 72#define FLAG_a (1<<0)
72#define FLAG_b (1<<1) 73#define FLAG_b (1<<1)
73#define FLAG_d (1<<2) 74#define FLAG_d (1<<2)
@@ -90,14 +91,14 @@ char **dl;
90int dl_count = 0; 91int dl_count = 0;
91 92
92struct cand { 93struct cand {
93 int x; 94 int x;
94 int y; 95 int y;
95 int pred; 96 int pred;
96}; 97};
97 98
98struct line { 99struct line {
99 int serial; 100 int serial;
100 int value; 101 int value;
101} *file[2]; 102} *file[2];
102 103
103/* 104/*
@@ -106,145 +107,145 @@ struct line {
106 * understand the highly mnemonic field names) 107 * understand the highly mnemonic field names)
107 */ 108 */
108struct context_vec { 109struct context_vec {
109 int a; /* start line in old file */ 110 int a; /* start line in old file */
110 int b; /* end line in old file */ 111 int b; /* end line in old file */
111 int c; /* start line in new file */ 112 int c; /* start line in new file */
112 int d; /* end line in new file */ 113 int d; /* end line in new file */
113}; 114};
114 115
115static int *J; /* will be overlaid on class */ 116static int *J; /* will be overlaid on class */
116static int *class; /* will be overlaid on file[0] */ 117static int *class; /* will be overlaid on file[0] */
117static int *klist; /* will be overlaid on file[0] after class */ 118static int *klist; /* will be overlaid on file[0] after class */
118static int *member; /* will be overlaid on file[1] */ 119static int *member; /* will be overlaid on file[1] */
119static int clen; 120static int clen;
120static int len[2]; 121static int len[2];
121static int pref, suff; /* length of prefix and suffix */ 122static int pref, suff; /* length of prefix and suffix */
122static int slen[2]; 123static int slen[2];
123static int anychange; 124static int anychange;
124static long *ixnew; /* will be overlaid on file[1] */ 125static long *ixnew; /* will be overlaid on file[1] */
125static long *ixold; /* will be overlaid on klist */ 126static long *ixold; /* will be overlaid on klist */
126static struct cand *clist; /* merely a free storage pot for candidates */ 127static struct cand *clist; /* merely a free storage pot for candidates */
127static int clistlen; /* the length of clist */ 128static int clistlen; /* the length of clist */
128static struct line *sfile[2]; /* shortened by pruning common prefix/suffix */ 129static struct line *sfile[2]; /* shortened by pruning common prefix/suffix */
129static struct context_vec *context_vec_start; 130static struct context_vec *context_vec_start;
130static struct context_vec *context_vec_end; 131static struct context_vec *context_vec_end;
131static struct context_vec *context_vec_ptr; 132static struct context_vec *context_vec_ptr;
132 133
133static void print_only(const char *path, size_t dirlen, const char *entry) 134static void print_only(const char *path, size_t dirlen, const char *entry)
134{ 135{
135 if (dirlen > 1) 136 if (dirlen > 1)
136 dirlen--; 137 dirlen--;
137 printf("Only in %.*s: %s\n", (int)dirlen, path, entry); 138 printf("Only in %.*s: %s\n", (int) dirlen, path, entry);
138} 139}
139 140
140static void print_status(int val, char *path1, char *path2, char *entry) 141static void print_status(int val, char *path1, char *path2, char *entry)
141{ 142{
142 const char * const _entry = entry ? entry : ""; 143 const char *const _entry = entry ? entry : "";
143 char *_path1 = entry ? concat_path_file(path1, _entry) : path1; 144 char *_path1 = entry ? concat_path_file(path1, _entry) : path1;
144 char *_path2 = entry ? concat_path_file(path2, _entry) : path2; 145 char *_path2 = entry ? concat_path_file(path2, _entry) : path2;
145 switch (val) { 146
146 case D_ONLY: 147 switch (val) {
147 print_only(path1, strlen(path1), entry); 148 case D_ONLY:
148 break; 149 print_only(path1, strlen(path1), entry);
149 case D_COMMON: 150 break;
150 printf("Common subdirectories: %s and %s\n", _path1, _path2); 151 case D_COMMON:
151 break; 152 printf("Common subdirectories: %s and %s\n", _path1, _path2);
152 case D_BINARY: 153 break;
153 printf("Binary files %s and %s differ\n", _path1, _path2); 154 case D_BINARY:
154 break; 155 printf("Binary files %s and %s differ\n", _path1, _path2);
155 case D_DIFFER: 156 break;
156 if (cmd_flags & FLAG_q) 157 case D_DIFFER:
157 printf("Files %s and %s differ\n", _path1, _path2); 158 if (cmd_flags & FLAG_q)
158 break; 159 printf("Files %s and %s differ\n", _path1, _path2);
159 case D_SAME: 160 break;
160 if (cmd_flags & FLAG_s) 161 case D_SAME:
161 printf("Files %s and %s are identical\n", _path1, _path2); 162 if (cmd_flags & FLAG_s)
162 break; 163 printf("Files %s and %s are identical\n", _path1, _path2);
163 case D_MISMATCH1: 164 break;
164 printf("File %s is a directory while file %s is a regular file\n", 165 case D_MISMATCH1:
165 _path1, _path2); 166 printf("File %s is a directory while file %s is a regular file\n",
166 break; 167 _path1, _path2);
167 case D_MISMATCH2: 168 break;
168 printf("File %s is a regular file while file %s is a directory\n", 169 case D_MISMATCH2:
169 _path1, _path2); 170 printf("File %s is a regular file while file %s is a directory\n",
170 break; 171 _path1, _path2);
171 case D_SKIPPED1: 172 break;
172 printf("File %s is not a regular file or directory and was skipped\n", 173 case D_SKIPPED1:
173 _path1); 174 printf("File %s is not a regular file or directory and was skipped\n",
174 break; 175 _path1);
175 case D_SKIPPED2: 176 break;
176 printf("File %s is not a regular file or directory and was skipped\n", 177 case D_SKIPPED2:
177 _path2); 178 printf("File %s is not a regular file or directory and was skipped\n",
178 break; 179 _path2);
179 } 180 break;
180 if (entry) { 181 }
181 free(_path1); 182 if (entry) {
182 free(_path2); 183 free(_path1);
183 } 184 free(_path2);
185 }
184} 186}
185 187
186/* 188/*
187 * Hash function taken from Robert Sedgewick, Algorithms in C, 3d ed., p 578. 189 * Hash function taken from Robert Sedgewick, Algorithms in C, 3d ed., p 578.
188 */ 190 */
189static int readhash(FILE *f) 191static int readhash(FILE * f)
190{ 192{
191 int i, t, space; 193 int i, t, space;
192 int sum; 194 int sum;
193 195
194 sum = 1; 196 sum = 1;
195 space = 0; 197 space = 0;
196 if (!(cmd_flags & FLAG_b) && !(cmd_flags & FLAG_w)) { 198 if (!(cmd_flags & FLAG_b) && !(cmd_flags & FLAG_w)) {
197 if (FLAG_i) 199 if (FLAG_i)
198 for (i = 0; (t = getc(f)) != '\n'; i++) { 200 for (i = 0; (t = getc(f)) != '\n'; i++) {
199 if (t == EOF) { 201 if (t == EOF) {
200 if (i == 0) 202 if (i == 0)
201 return (0); 203 return (0);
202 break; 204 break;
203 } 205 }
204 sum = sum * 127 + t; 206 sum = sum * 127 + t;
205 } 207 } else
206 else 208 for (i = 0; (t = getc(f)) != '\n'; i++) {
207 for (i = 0; (t = getc(f)) != '\n'; i++) { 209 if (t == EOF) {
208 if (t == EOF) { 210 if (i == 0)
209 if (i == 0) 211 return (0);
210 return (0); 212 break;
211 break; 213 }
212 } 214 sum = sum * 127 + t;
213 sum = sum * 127 + t; 215 }
214 } 216 } else {
215 } else { 217 for (i = 0;;) {
216 for (i = 0;;) { 218 switch (t = getc(f)) {
217 switch (t = getc(f)) { 219 case '\t':
218 case '\t': 220 case '\r':
219 case '\r': 221 case '\v':
220 case '\v': 222 case '\f':
221 case '\f': 223 case ' ':
222 case ' ': 224 space++;
223 space++; 225 continue;
224 continue; 226 default:
225 default: 227 if (space && !(cmd_flags & FLAG_w)) {
226 if (space && !(cmd_flags & FLAG_w)) { 228 i++;
227 i++; 229 space = 0;
228 space = 0; 230 }
229 } 231 sum = sum * 127 + t;
230 sum = sum * 127 + t; 232 i++;
231 i++; 233 continue;
232 continue; 234 case EOF:
233 case EOF: 235 if (i == 0)
234 if (i == 0) 236 return (0);
235 return (0); 237 /* FALLTHROUGH */
236 /* FALLTHROUGH */ 238 case '\n':
237 case '\n': 239 break;
238 break; 240 }
239 } 241 break;
240 break; 242 }
241 } 243 }
242 } 244 /*
243 /* 245 * There is a remote possibility that we end up with a zero sum.
244 * There is a remote possibility that we end up with a zero sum. 246 * Zero is used as an EOF marker, so return 1 instead.
245 * Zero is used as an EOF marker, so return 1 instead. 247 */
246 */ 248 return (sum == 0 ? 1 : sum);
247 return (sum == 0 ? 1 : sum);
248} 249}
249 250
250 251
@@ -253,103 +254,103 @@ static int readhash(FILE *f)
253 * Check to see if the given files differ. 254 * Check to see if the given files differ.
254 * Returns 0 if they are the same, 1 if different, and -1 on error. 255 * Returns 0 if they are the same, 1 if different, and -1 on error.
255 */ 256 */
256static int files_differ(FILE *f1, FILE *f2, int flags) 257static int files_differ(FILE * f1, FILE * f2, int flags)
257{ 258{
258 char buf1[BUFSIZ], buf2[BUFSIZ]; 259 char buf1[BUFSIZ], buf2[BUFSIZ];
259 size_t i, j; 260 size_t i, j;
260 261
261 if ((flags & (D_EMPTY1|D_EMPTY2)) || stb1.st_size != stb2.st_size || 262 if ((flags & (D_EMPTY1 | D_EMPTY2)) || stb1.st_size != stb2.st_size ||
262 (stb1.st_mode & S_IFMT) != (stb2.st_mode & S_IFMT)) 263 (stb1.st_mode & S_IFMT) != (stb2.st_mode & S_IFMT))
263 return (1); 264 return (1);
264 while(1) { 265 while (1) {
265 i = fread(buf1, 1, sizeof(buf1), f1); 266 i = fread(buf1, 1, sizeof(buf1), f1);
266 j = fread(buf2, 1, sizeof(buf2), f2); 267 j = fread(buf2, 1, sizeof(buf2), f2);
267 if (i != j) 268 if (i != j)
268 return (1); 269 return (1);
269 if (i == 0 && j == 0) { 270 if (i == 0 && j == 0) {
270 if (ferror(f1) || ferror(f2)) 271 if (ferror(f1) || ferror(f2))
271 return (1); 272 return (1);
272 return (0); 273 return (0);
273 } 274 }
274 if (memcmp(buf1, buf2, i) != 0) 275 if (memcmp(buf1, buf2, i) != 0)
275 return (1); 276 return (1);
276 } 277 }
277} 278}
278 279
279static void prepare(int i, FILE *fd, off_t filesize) 280static void prepare(int i, FILE * fd, off_t filesize)
280{ 281{
281 struct line *p; 282 struct line *p;
282 int h; 283 int h;
283 size_t j, sz; 284 size_t j, sz;
284 285
285 rewind(fd); 286 rewind(fd);
286 287
287 sz = (filesize <= FSIZE_MAX ? filesize : FSIZE_MAX) / 25; 288 sz = (filesize <= FSIZE_MAX ? filesize : FSIZE_MAX) / 25;
288 if (sz < 100) 289 if (sz < 100)
289 sz = 100; 290 sz = 100;
290 291
291 p = xmalloc((sz + 3) * sizeof(struct line)); 292 p = xmalloc((sz + 3) * sizeof(struct line));
292 for (j = 0; (h = readhash(fd));) { 293 for (j = 0; (h = readhash(fd));) {
293 if (j == sz) { 294 if (j == sz) {
294 sz = sz * 3 / 2; 295 sz = sz * 3 / 2;
295 p = xrealloc(p, (sz + 3) * sizeof(struct line)); 296 p = xrealloc(p, (sz + 3) * sizeof(struct line));
296 } 297 }
297 p[++j].value = h; 298 p[++j].value = h;
298 } 299 }
299 len[i] = j; 300 len[i] = j;
300 file[i] = p; 301 file[i] = p;
301} 302}
302 303
303static void prune(void) 304static void prune(void)
304{ 305{
305 int i, j; 306 int i, j;
306 307
307 for (pref = 0; pref < len[0] && pref < len[1] && 308 for (pref = 0; pref < len[0] && pref < len[1] &&
308 file[0][pref + 1].value == file[1][pref + 1].value; 309 file[0][pref + 1].value == file[1][pref + 1].value; pref++);
309 pref++) 310 for (suff = 0; suff < len[0] - pref && suff < len[1] - pref &&
310 ; 311 file[0][len[0] - suff].value == file[1][len[1] - suff].value;
311 for (suff = 0; suff < len[0] - pref && suff < len[1] - pref && 312 suff++);
312 file[0][len[0] - suff].value == file[1][len[1] - suff].value; 313 for (j = 0; j < 2; j++) {
313 suff++) 314 sfile[j] = file[j] + pref;
314 ; 315 slen[j] = len[j] - pref - suff;
315 for (j = 0; j < 2; j++) { 316 for (i = 0; i <= slen[j]; i++)
316 sfile[j] = file[j] + pref; 317 sfile[j][i].serial = i;
317 slen[j] = len[j] - pref - suff; 318 }
318 for (i = 0; i <= slen[j]; i++)
319 sfile[j][i].serial = i;
320 }
321} 319}
322 320
323static void equiv(struct line *a, int n, struct line *b, int m, int *c) 321static void equiv(struct line *a, int n, struct line *b, int m, int *c)
324{ 322{
325 int i, j; 323 int i, j;
326 324
327 i = j = 1; 325 i = j = 1;
328 while (i <= n && j <= m) { 326 while (i <= n && j <= m) {
329 if (a[i].value < b[j].value) 327 if (a[i].value < b[j].value)
330 a[i++].value = 0; 328 a[i++].value = 0;
331 else if (a[i].value == b[j].value) 329 else if (a[i].value == b[j].value)
332 a[i++].value = j; 330 a[i++].value = j;
333 else 331 else
334 j++; 332 j++;
335 } 333 }
336 while (i <= n) 334 while (i <= n)
337 a[i++].value = 0; 335 a[i++].value = 0;
338 b[m + 1].value = 0; 336 b[m + 1].value = 0;
339 j = 0; 337 j = 0;
340 while (++j <= m) { 338 while (++j <= m) {
341 c[j] = -b[j].serial; 339 c[j] = -b[j].serial;
342 while (b[j + 1].value == b[j].value) { 340 while (b[j + 1].value == b[j].value) {
343 j++; 341 j++;
344 c[j] = b[j].serial; 342 c[j] = b[j].serial;
345 } 343 }
346 } 344 }
347 c[j] = -1; 345 c[j] = -1;
348} 346}
349 347
350static int isqrt(int n) { 348static int isqrt(int n)
349{
351 int y, x = 1; 350 int y, x = 1;
352 if (n == 0) return(0); 351
352 if (n == 0)
353 return (0);
353 354
354 do { 355 do {
355 y = x; 356 y = x;
@@ -363,120 +364,121 @@ static int isqrt(int n) {
363 364
364static int newcand(int x, int y, int pred) 365static int newcand(int x, int y, int pred)
365{ 366{
366 struct cand *q; 367 struct cand *q;
367 368
368 if (clen == clistlen) { 369 if (clen == clistlen) {
369 clistlen = clistlen * 11 / 10; 370 clistlen = clistlen * 11 / 10;
370 clist = xrealloc(clist, clistlen * sizeof(struct cand)); 371 clist = xrealloc(clist, clistlen * sizeof(struct cand));
371 } 372 }
372 q = clist + clen; 373 q = clist + clen;
373 q->x = x; 374 q->x = x;
374 q->y = y; 375 q->y = y;
375 q->pred = pred; 376 q->pred = pred;
376 return (clen++); 377 return (clen++);
377} 378}
378 379
379 380
380static int search(int *c, int k, int y) 381static int search(int *c, int k, int y)
381{ 382{
382 int i, j, l, t; 383 int i, j, l, t;
383 384
384 if (clist[c[k]].y < y) /* quick look for typical case */ 385 if (clist[c[k]].y < y) /* quick look for typical case */
385 return (k + 1); 386 return (k + 1);
386 i = 0; 387 i = 0;
387 j = k + 1; 388 j = k + 1;
388 while (1) { 389 while (1) {
389 l = i + j; 390 l = i + j;
390 if ((l >>= 1) <= i) 391 if ((l >>= 1) <= i)
391 break; 392 break;
392 t = clist[c[l]].y; 393 t = clist[c[l]].y;
393 if (t > y) 394 if (t > y)
394 j = l; 395 j = l;
395 else if (t < y) 396 else if (t < y)
396 i = l; 397 i = l;
397 else 398 else
398 return (l); 399 return (l);
399 } 400 }
400 return (l + 1); 401 return (l + 1);
401} 402}
402 403
403 404
404static int stone(int *a, int n, int *b, int *c) 405static int stone(int *a, int n, int *b, int *c)
405{ 406{
406 int i, k, y, j, l; 407 int i, k, y, j, l;
407 int oldc, tc, oldl; 408 int oldc, tc, oldl;
408 unsigned int numtries; 409 unsigned int numtries;
410
409#if ENABLE_FEATURE_DIFF_MINIMAL 411#if ENABLE_FEATURE_DIFF_MINIMAL
410 const unsigned int bound = (cmd_flags & FLAG_d) ? UINT_MAX : MAX(256, isqrt(n)); 412 const unsigned int bound =
413 (cmd_flags & FLAG_d) ? UINT_MAX : MAX(256, isqrt(n));
411#else 414#else
412 const unsigned int bound = MAX(256, isqrt(n)); 415 const unsigned int bound = MAX(256, isqrt(n));
413#endif 416#endif
414 k = 0; 417 k = 0;
415 c[0] = newcand(0, 0, 0); 418 c[0] = newcand(0, 0, 0);
416 for (i = 1; i <= n; i++) { 419 for (i = 1; i <= n; i++) {
417 j = a[i]; 420 j = a[i];
418 if (j == 0) 421 if (j == 0)
419 continue; 422 continue;
420 y = -b[j]; 423 y = -b[j];
421 oldl = 0; 424 oldl = 0;
422 oldc = c[0]; 425 oldc = c[0];
423 numtries = 0; 426 numtries = 0;
424 do { 427 do {
425 if (y <= clist[oldc].y) 428 if (y <= clist[oldc].y)
426 continue; 429 continue;
427 l = search(c, k, y); 430 l = search(c, k, y);
428 if (l != oldl + 1) 431 if (l != oldl + 1)
429 oldc = c[l - 1]; 432 oldc = c[l - 1];
430 if (l <= k) { 433 if (l <= k) {
431 if (clist[c[l]].y <= y) 434 if (clist[c[l]].y <= y)
432 continue; 435 continue;
433 tc = c[l]; 436 tc = c[l];
434 c[l] = newcand(i, y, oldc); 437 c[l] = newcand(i, y, oldc);
435 oldc = tc; 438 oldc = tc;
436 oldl = l; 439 oldl = l;
437 numtries++; 440 numtries++;
438 } else { 441 } else {
439 c[l] = newcand(i, y, oldc); 442 c[l] = newcand(i, y, oldc);
440 k++; 443 k++;
441 break; 444 break;
442 } 445 }
443 } while ((y = b[++j]) > 0 && numtries < bound); 446 } while ((y = b[++j]) > 0 && numtries < bound);
444 } 447 }
445 return (k); 448 return (k);
446} 449}
447 450
448static void unravel(int p) 451static void unravel(int p)
449{ 452{
450 struct cand *q; 453 struct cand *q;
451 int i; 454 int i;
452 455
453 for (i = 0; i <= len[0]; i++) 456 for (i = 0; i <= len[0]; i++)
454 J[i] = i <= pref ? i : 457 J[i] = i <= pref ? i : i > len[0] - suff ? i + len[1] - len[0] : 0;
455 i > len[0] - suff ? i + len[1] - len[0] : 0; 458 for (q = clist + p; q->y != 0; q = clist + q->pred)
456 for (q = clist + p; q->y != 0; q = clist + q->pred) 459 J[q->x + pref] = q->y + pref;
457 J[q->x + pref] = q->y + pref;
458} 460}
459 461
460 462
461static void unsort(struct line *f, int l, int *b) 463static void unsort(struct line *f, int l, int *b)
462{ 464{
463 int *a, i; 465 int *a, i;
464 466
465 a = xmalloc((l + 1) * sizeof(int)); 467 a = xmalloc((l + 1) * sizeof(int));
466 for (i = 1; i <= l; i++) 468 for (i = 1; i <= l; i++)
467 a[f[i].serial] = f[i].value; 469 a[f[i].serial] = f[i].value;
468 for (i = 1; i <= l; i++) 470 for (i = 1; i <= l; i++)
469 b[i] = a[i]; 471 b[i] = a[i];
470 free(a); 472 free(a);
471} 473}
472 474
473static int skipline(FILE *f) 475static int skipline(FILE * f)
474{ 476{
475 int i, c; 477 int i, c;
476 478
477 for (i = 1; (c = getc(f)) != '\n' && c != EOF; i++) 479 for (i = 1; (c = getc(f)) != '\n' && c != EOF; i++)
478 continue; 480 continue;
479 return (i); 481 return (i);
480} 482}
481 483
482 484
@@ -486,175 +488,174 @@ static int skipline(FILE *f)
486 * to confounding by hashing (which result in "jackpot") 488 * to confounding by hashing (which result in "jackpot")
487 * 2. collect random access indexes to the two files 489 * 2. collect random access indexes to the two files
488 */ 490 */
489static void check(FILE *f1, FILE *f2) 491static void check(FILE * f1, FILE * f2)
490{ 492{
491 int i, j, jackpot, c, d; 493 int i, j, jackpot, c, d;
492 long ctold, ctnew; 494 long ctold, ctnew;
493 495
494 rewind(f1); 496 rewind(f1);
495 rewind(f2); 497 rewind(f2);
496 j = 1; 498 j = 1;
497 ixold[0] = ixnew[0] = 0; 499 ixold[0] = ixnew[0] = 0;
498 jackpot = 0; 500 jackpot = 0;
499 ctold = ctnew = 0; 501 ctold = ctnew = 0;
500 for (i = 1; i <= len[0]; i++) { 502 for (i = 1; i <= len[0]; i++) {
501 if (J[i] == 0) { 503 if (J[i] == 0) {
502 ixold[i] = ctold += skipline(f1); 504 ixold[i] = ctold += skipline(f1);
503 continue; 505 continue;
504 } 506 }
505 while (j < J[i]) { 507 while (j < J[i]) {
506 ixnew[j] = ctnew += skipline(f2); 508 ixnew[j] = ctnew += skipline(f2);
507 j++; 509 j++;
508 } 510 }
509 if ((cmd_flags & FLAG_b) || (cmd_flags & FLAG_w) || (cmd_flags & FLAG_i)) { 511 if ((cmd_flags & FLAG_b) || (cmd_flags & FLAG_w)
510 while (1) { 512 || (cmd_flags & FLAG_i)) {
511 c = getc(f1); 513 while (1) {
512 d = getc(f2); 514 c = getc(f1);
513 /* 515 d = getc(f2);
514 * GNU diff ignores a missing newline 516 /*
515 * in one file if bflag || wflag. 517 * GNU diff ignores a missing newline
516 */ 518 * in one file if bflag || wflag.
517 if (((cmd_flags & FLAG_b) || (cmd_flags & FLAG_w)) && 519 */
518 ((c == EOF && d == '\n') || 520 if (((cmd_flags & FLAG_b) || (cmd_flags & FLAG_w)) &&
519 (c == '\n' && d == EOF))) { 521 ((c == EOF && d == '\n') || (c == '\n' && d == EOF))) {
520 break; 522 break;
521 } 523 }
522 ctold++; 524 ctold++;
523 ctnew++; 525 ctnew++;
524 if ((cmd_flags & FLAG_b) && isspace(c) && isspace(d)) { 526 if ((cmd_flags & FLAG_b) && isspace(c) && isspace(d)) {
525 do { 527 do {
526 if (c == '\n') 528 if (c == '\n')
527 break; 529 break;
528 ctold++; 530 ctold++;
529 } while (isspace(c = getc(f1))); 531 } while (isspace(c = getc(f1)));
530 do { 532 do {
531 if (d == '\n') 533 if (d == '\n')
532 break; 534 break;
533 ctnew++; 535 ctnew++;
534 } while (isspace(d = getc(f2))); 536 } while (isspace(d = getc(f2)));
535 } else if (cmd_flags & FLAG_w) { 537 } else if (cmd_flags & FLAG_w) {
536 while (isspace(c) && c != '\n') { 538 while (isspace(c) && c != '\n') {
537 c = getc(f1); 539 c = getc(f1);
538 ctold++; 540 ctold++;
539 } 541 }
540 while (isspace(d) && d != '\n') { 542 while (isspace(d) && d != '\n') {
541 d = getc(f2); 543 d = getc(f2);
542 ctnew++; 544 ctnew++;
543 } 545 }
544 } 546 }
545 if (c != d) { 547 if (c != d) {
546 jackpot++; 548 jackpot++;
547 J[i] = 0; 549 J[i] = 0;
548 if (c != '\n' && c != EOF) 550 if (c != '\n' && c != EOF)
549 ctold += skipline(f1); 551 ctold += skipline(f1);
550 if (d != '\n' && c != EOF) 552 if (d != '\n' && c != EOF)
551 ctnew += skipline(f2); 553 ctnew += skipline(f2);
552 break; 554 break;
553 } 555 }
554 if (c == '\n' || c == EOF) 556 if (c == '\n' || c == EOF)
555 break; 557 break;
556 } 558 }
557 } else { 559 } else {
558 while (1) { 560 while (1) {
559 ctold++; 561 ctold++;
560 ctnew++; 562 ctnew++;
561 if ((c = getc(f1)) != (d = getc(f2))) { 563 if ((c = getc(f1)) != (d = getc(f2))) {
562 J[i] = 0; 564 J[i] = 0;
563 if (c != '\n' && c != EOF) 565 if (c != '\n' && c != EOF)
564 ctold += skipline(f1); 566 ctold += skipline(f1);
565 if (d != '\n' && c != EOF) 567 if (d != '\n' && c != EOF)
566 ctnew += skipline(f2); 568 ctnew += skipline(f2);
567 break; 569 break;
568 } 570 }
569 if (c == '\n' || c == EOF) 571 if (c == '\n' || c == EOF)
570 break; 572 break;
571 } 573 }
572 } 574 }
573 ixold[i] = ctold; 575 ixold[i] = ctold;
574 ixnew[j] = ctnew; 576 ixnew[j] = ctnew;
575 j++; 577 j++;
576 } 578 }
577 for (; j <= len[1]; j++) 579 for (; j <= len[1]; j++)
578 ixnew[j] = ctnew += skipline(f2); 580 ixnew[j] = ctnew += skipline(f2);
579} 581}
580 582
581/* shellsort CACM #201 */ 583/* shellsort CACM #201 */
582static void sort(struct line *a, int n) 584static void sort(struct line *a, int n)
583{ 585{
584 struct line *ai, *aim, w; 586 struct line *ai, *aim, w;
585 int j, m = 0, k; 587 int j, m = 0, k;
586 588
587 if (n == 0) 589 if (n == 0)
588 return; 590 return;
589 for (j = 1; j <= n; j *= 2) 591 for (j = 1; j <= n; j *= 2)
590 m = 2 * j - 1; 592 m = 2 * j - 1;
591 for (m /= 2; m != 0; m /= 2) { 593 for (m /= 2; m != 0; m /= 2) {
592 k = n - m; 594 k = n - m;
593 for (j = 1; j <= k; j++) { 595 for (j = 1; j <= k; j++) {
594 for (ai = &a[j]; ai > a; ai -= m) { 596 for (ai = &a[j]; ai > a; ai -= m) {
595 aim = &ai[m]; 597 aim = &ai[m];
596 if (aim < ai) 598 if (aim < ai)
597 break; /* wraparound */ 599 break; /* wraparound */
598 if (aim->value > ai[0].value || 600 if (aim->value > ai[0].value ||
599 (aim->value == ai[0].value && 601 (aim->value == ai[0].value && aim->serial > ai[0].serial))
600 aim->serial > ai[0].serial)) 602 break;
601 break; 603 w.value = ai[0].value;
602 w.value = ai[0].value; 604 ai[0].value = aim->value;
603 ai[0].value = aim->value; 605 aim->value = w.value;
604 aim->value = w.value; 606 w.serial = ai[0].serial;
605 w.serial = ai[0].serial; 607 ai[0].serial = aim->serial;
606 ai[0].serial = aim->serial; 608 aim->serial = w.serial;
607 aim->serial = w.serial; 609 }
608 } 610 }
609 } 611 }
610 }
611} 612}
612 613
613 614
614static void uni_range(int a, int b) 615static void uni_range(int a, int b)
615{ 616{
616 if (a < b) 617 if (a < b)
617 printf("%d,%d", a, b - a + 1); 618 printf("%d,%d", a, b - a + 1);
618 else if (a == b) 619 else if (a == b)
619 printf("%d", b); 620 printf("%d", b);
620 else 621 else
621 printf("%d,0", b); 622 printf("%d,0", b);
622} 623}
623 624
624static int fetch(long *f, int a, int b, FILE *lb, int ch) 625static int fetch(long *f, int a, int b, FILE * lb, int ch)
625{ 626{
626 int i, j, c, lastc, col, nc; 627 int i, j, c, lastc, col, nc;
627 628
628 if (a > b) 629 if (a > b)
629 return (0); 630 return (0);
630 for (i = a; i <= b; i++) { 631 for (i = a; i <= b; i++) {
631 fseek(lb, f[i - 1], SEEK_SET); 632 fseek(lb, f[i - 1], SEEK_SET);
632 nc = f[i] - f[i - 1]; 633 nc = f[i] - f[i - 1];
633 if (ch != '\0') { 634 if (ch != '\0') {
634 putchar(ch); 635 putchar(ch);
635 if (cmd_flags & FLAG_T) 636 if (cmd_flags & FLAG_T)
636 putchar('\t'); 637 putchar('\t');
637 } 638 }
638 col = 0; 639 col = 0;
639 for (j = 0, lastc = '\0'; j < nc; j++, lastc = c) { 640 for (j = 0, lastc = '\0'; j < nc; j++, lastc = c) {
640 if ((c = getc(lb)) == EOF) { 641 if ((c = getc(lb)) == EOF) {
641 puts("\n\\ No newline at end of file"); 642 puts("\n\\ No newline at end of file");
642 return (0); 643 return (0);
643 } 644 }
644 if (c == '\t' && (cmd_flags & FLAG_t)) { 645 if (c == '\t' && (cmd_flags & FLAG_t)) {
645 do { 646 do {
646 putchar(' '); 647 putchar(' ');
647 } while (++col & 7); 648 } while (++col & 7);
648 } else { 649 } else {
649 putchar(c); 650 putchar(c);
650 col++; 651 col++;
651 } 652 }
652 } 653 }
653 } 654 }
654 return (0); 655 return (0);
655} 656}
656 657
657static int asciifile(FILE *f) 658static int asciifile(FILE * f)
658{ 659{
659#if ENABLE_FEATURE_DIFF_BINARY 660#if ENABLE_FEATURE_DIFF_BINARY
660 unsigned char buf[BUFSIZ]; 661 unsigned char buf[BUFSIZ];
@@ -677,97 +678,93 @@ static int asciifile(FILE *f)
677} 678}
678 679
679/* dump accumulated "unified" diff changes */ 680/* dump accumulated "unified" diff changes */
680static void dump_unified_vec(FILE *f1, FILE *f2) 681static void dump_unified_vec(FILE * f1, FILE * f2)
681{ 682{
682 struct context_vec *cvp = context_vec_start; 683 struct context_vec *cvp = context_vec_start;
683 int lowa, upb, lowc, upd; 684 int lowa, upb, lowc, upd;
684 int a, b, c, d; 685 int a, b, c, d;
685 char ch; 686 char ch;
686 687
687 if (context_vec_start > context_vec_ptr) 688 if (context_vec_start > context_vec_ptr)
688 return; 689 return;
689 690
690 b = d = 0; /* gcc */ 691 b = d = 0; /* gcc */
691 lowa = MAX(1, cvp->a - context); 692 lowa = MAX(1, cvp->a - context);
692 upb = MIN(len[0], context_vec_ptr->b + context); 693 upb = MIN(len[0], context_vec_ptr->b + context);
693 lowc = MAX(1, cvp->c - context); 694 lowc = MAX(1, cvp->c - context);
694 upd = MIN(len[1], context_vec_ptr->d + context); 695 upd = MIN(len[1], context_vec_ptr->d + context);
695 696
696 fputs("@@ -", stdout); 697 fputs("@@ -", stdout);
697 uni_range(lowa, upb); 698 uni_range(lowa, upb);
698 fputs(" +", stdout); 699 fputs(" +", stdout);
699 uni_range(lowc, upd); 700 uni_range(lowc, upd);
700 fputs(" @@", stdout); 701 fputs(" @@", stdout);
701 putchar('\n'); 702 putchar('\n');
702 703
703 /* 704 /*
704 * Output changes in "unified" diff format--the old and new lines 705 * Output changes in "unified" diff format--the old and new lines
705 * are printed together. 706 * are printed together.
706 */ 707 */
707 for (; cvp <= context_vec_ptr; cvp++) { 708 for (; cvp <= context_vec_ptr; cvp++) {
708 a = cvp->a; 709 a = cvp->a;
709 b = cvp->b; 710 b = cvp->b;
710 c = cvp->c; 711 c = cvp->c;
711 d = cvp->d; 712 d = cvp->d;
712 713
713 /* 714 /*
714 * c: both new and old changes 715 * c: both new and old changes
715 * d: only changes in the old file 716 * d: only changes in the old file
716 * a: only changes in the new file 717 * a: only changes in the new file
717 */ 718 */
718 if (a <= b && c <= d) 719 if (a <= b && c <= d)
719 ch = 'c'; 720 ch = 'c';
720 else 721 else
721 ch = (a <= b) ? 'd' : 'a'; 722 ch = (a <= b) ? 'd' : 'a';
722#if 0 723#if 0
723 switch (ch) { 724 switch (ch) {
724 case 'c': 725 case 'c':
725 fetch(ixold, lowa, a - 1, f1, ' '); 726 fetch(ixold, lowa, a - 1, f1, ' ');
726 fetch(ixold, a, b, f1, '-'); 727 fetch(ixold, a, b, f1, '-');
727 fetch(ixnew, c, d, f2, '+'); 728 fetch(ixnew, c, d, f2, '+');
728 break; 729 break;
729 case 'd': 730 case 'd':
730 fetch(ixold, lowa, a - 1, f1, ' '); 731 fetch(ixold, lowa, a - 1, f1, ' ');
731 fetch(ixold, a, b, f1, '-'); 732 fetch(ixold, a, b, f1, '-');
732 break; 733 break;
733 case 'a': 734 case 'a':
734 fetch(ixnew, lowc, c - 1, f2, ' '); 735 fetch(ixnew, lowc, c - 1, f2, ' ');
735 fetch(ixnew, c, d, f2, '+'); 736 fetch(ixnew, c, d, f2, '+');
736 break; 737 break;
737 } 738 }
738#else 739#else
739 if (ch == 'c' || ch == 'd') { 740 if (ch == 'c' || ch == 'd') {
740 fetch(ixold, lowa, a - 1, f1, ' '); 741 fetch(ixold, lowa, a - 1, f1, ' ');
741 fetch(ixold, a, b, f1, '-'); 742 fetch(ixold, a, b, f1, '-');
742 } 743 }
743 if (ch == 'a') 744 if (ch == 'a')
744 fetch(ixnew, lowc, c - 1, f2, ' '); 745 fetch(ixnew, lowc, c - 1, f2, ' ');
745 if (ch == 'c' || ch == 'a') 746 if (ch == 'c' || ch == 'a')
746 fetch(ixnew, c, d, f2, '+'); 747 fetch(ixnew, c, d, f2, '+');
747#endif 748#endif
748 lowa = b + 1; 749 lowa = b + 1;
749 lowc = d + 1; 750 lowc = d + 1;
750 } 751 }
751 fetch(ixnew, d + 1, upd, f2, ' '); 752 fetch(ixnew, d + 1, upd, f2, ' ');
752 753
753 context_vec_ptr = context_vec_start - 1; 754 context_vec_ptr = context_vec_start - 1;
754} 755}
755 756
756 757
757static void print_header(const char *file1, const char *file2) 758static void print_header(const char *file1, const char *file2)
758{ 759{
759 if (label[0] != NULL) 760 if (label[0] != NULL)
760 printf("%s %s\n", "---", 761 printf("%s %s\n", "---", label[0]);
761 label[0]); 762 else
762 else 763 printf("%s %s\t%s", "---", file1, ctime(&stb1.st_mtime));
763 printf("%s %s\t%s", "---", 764 if (label[1] != NULL)
764 file1, ctime(&stb1.st_mtime)); 765 printf("%s %s\n", "+++", label[1]);
765 if (label[1] != NULL) 766 else
766 printf("%s %s\n", "+++", 767 printf("%s %s\t%s", "+++", file2, ctime(&stb2.st_mtime));
767 label[1]);
768 else
769 printf("%s %s\t%s", "+++",
770 file2, ctime(&stb2.st_mtime));
771} 768}
772 769
773 770
@@ -779,77 +776,82 @@ static void print_header(const char *file1, const char *file2)
779 * lines appended (beginning at b). If c is greater than d then there are 776 * lines appended (beginning at b). If c is greater than d then there are
780 * lines missing from the to file. 777 * lines missing from the to file.
781 */ 778 */
782static void change(char *file1, FILE *f1, char *file2, FILE *f2, int a, int b, int c, int d) 779static void change(char *file1, FILE * f1, char *file2, FILE * f2, int a,
780 int b, int c, int d)
783{ 781{
784 static size_t max_context = 64; 782 static size_t max_context = 64;
785 783
786 if (a > b && c > d) return; 784 if (a > b && c > d)
787 if (cmd_flags & FLAG_q) return; 785 return;
788 786 if (cmd_flags & FLAG_q)
789 /* 787 return;
790 * Allocate change records as needed. 788
791 */ 789 /*
792 if (context_vec_ptr == context_vec_end - 1) { 790 * Allocate change records as needed.
793 ptrdiff_t offset = context_vec_ptr - context_vec_start; 791 */
794 max_context <<= 1; 792 if (context_vec_ptr == context_vec_end - 1) {
795 context_vec_start = xrealloc(context_vec_start, 793 ptrdiff_t offset = context_vec_ptr - context_vec_start;
796 max_context * sizeof(struct context_vec)); 794
797 context_vec_end = context_vec_start + max_context; 795 max_context <<= 1;
798 context_vec_ptr = context_vec_start + offset; 796 context_vec_start = xrealloc(context_vec_start,
799 } 797 max_context *
800 if (anychange == 0) { 798 sizeof(struct context_vec));
801 /* 799 context_vec_end = context_vec_start + max_context;
802 * Print the context/unidiff header first time through. 800 context_vec_ptr = context_vec_start + offset;
803 */ 801 }
804 print_header(file1, file2); 802 if (anychange == 0) {
805 anychange = 1; 803 /*
806 } else if (a > context_vec_ptr->b + (2 * context) + 1 && 804 * Print the context/unidiff header first time through.
807 c > context_vec_ptr->d + (2 * context) + 1) { 805 */
808 /* 806 print_header(file1, file2);
809 * If this change is more than 'context' lines from the 807 anychange = 1;
810 * previous change, dump the record and reset it. 808 } else if (a > context_vec_ptr->b + (2 * context) + 1 &&
811 */ 809 c > context_vec_ptr->d + (2 * context) + 1) {
812 dump_unified_vec(f1, f2); 810 /*
813 } 811 * If this change is more than 'context' lines from the
814 context_vec_ptr++; 812 * previous change, dump the record and reset it.
815 context_vec_ptr->a = a; 813 */
816 context_vec_ptr->b = b; 814 dump_unified_vec(f1, f2);
817 context_vec_ptr->c = c; 815 }
818 context_vec_ptr->d = d; 816 context_vec_ptr++;
819 return; 817 context_vec_ptr->a = a;
820 818 context_vec_ptr->b = b;
819 context_vec_ptr->c = c;
820 context_vec_ptr->d = d;
821 return;
822
821} 823}
822 824
823 825
824static void output(char *file1, FILE *f1, char *file2, FILE *f2) 826static void output(char *file1, FILE * f1, char *file2, FILE * f2)
825{ 827{
826 828
827 /* Note that j0 and j1 can't be used as they are defined in math.h. 829 /* Note that j0 and j1 can't be used as they are defined in math.h.
828 * This also allows the rather amusing variable 'j00'... */ 830 * This also allows the rather amusing variable 'j00'... */
829 int m, i0, i1, j00, j01; 831 int m, i0, i1, j00, j01;
830 832
831 rewind(f1); 833 rewind(f1);
832 rewind(f2); 834 rewind(f2);
833 m = len[0]; 835 m = len[0];
834 J[0] = 0; 836 J[0] = 0;
835 J[m + 1] = len[1] + 1; 837 J[m + 1] = len[1] + 1;
836 for (i0 = 1; i0 <= m; i0 = i1 + 1) { 838 for (i0 = 1; i0 <= m; i0 = i1 + 1) {
837 while (i0 <= m && J[i0] == J[i0 - 1] + 1) 839 while (i0 <= m && J[i0] == J[i0 - 1] + 1)
838 i0++; 840 i0++;
839 j00 = J[i0 - 1] + 1; 841 j00 = J[i0 - 1] + 1;
840 i1 = i0 - 1; 842 i1 = i0 - 1;
841 while (i1 < m && J[i1 + 1] == 0) 843 while (i1 < m && J[i1 + 1] == 0)
842 i1++; 844 i1++;
843 j01 = J[i1 + 1] - 1; 845 j01 = J[i1 + 1] - 1;
844 J[i1] = j01; 846 J[i1] = j01;
845 change(file1, f1, file2, f2, i0, i1, j00, j01); 847 change(file1, f1, file2, f2, i0, i1, j00, j01);
846 } 848 }
847 if (m == 0) { 849 if (m == 0) {
848 change(file1, f1, file2, f2, 1, 0, 1, len[1]); 850 change(file1, f1, file2, f2, 1, 0, 1, len[1]);
849 } 851 }
850 if (anychange != 0) { 852 if (anychange != 0) {
851 dump_unified_vec(f1, f2); 853 dump_unified_vec(f1, f2);
852 } 854 }
853} 855}
854 856
855/* 857/*
@@ -917,108 +919,109 @@ static void output(char *file1, FILE *f1, char *file2, FILE *f2)
917 919
918static int diffreg(char *ofile1, char *ofile2, int flags) 920static int diffreg(char *ofile1, char *ofile2, int flags)
919{ 921{
920 char *file1 = ofile1; 922 char *file1 = ofile1;
921 char *file2 = ofile2; 923 char *file2 = ofile2;
922 FILE *f1 = NULL; 924 FILE *f1 = NULL;
923 FILE *f2 = NULL; 925 FILE *f2 = NULL;
924 int rval = D_SAME; 926 int rval = D_SAME;
925 int i; 927 int i;
926 928
927 anychange = 0; 929 anychange = 0;
928 context_vec_ptr = context_vec_start - 1; 930 context_vec_ptr = context_vec_start - 1;
929 931
930 if (S_ISDIR(stb1.st_mode) != S_ISDIR(stb2.st_mode)) 932 if (S_ISDIR(stb1.st_mode) != S_ISDIR(stb2.st_mode))
931 return (S_ISDIR(stb1.st_mode) ? D_MISMATCH1 : D_MISMATCH2); 933 return (S_ISDIR(stb1.st_mode) ? D_MISMATCH1 : D_MISMATCH2);
932 if (strcmp(file1, "-") == 0 && strcmp(file2, "-") == 0) 934 if (strcmp(file1, "-") == 0 && strcmp(file2, "-") == 0)
933 goto closem; 935 goto closem;
934 936
935 if (flags & D_EMPTY1) 937 if (flags & D_EMPTY1)
936 f1 = bb_xfopen(bb_dev_null, "r"); 938 f1 = bb_xfopen(bb_dev_null, "r");
937 else { 939 else {
938 if (strcmp(file1, "-") == 0) 940 if (strcmp(file1, "-") == 0)
939 f1 = stdin; 941 f1 = stdin;
940 else 942 else
941 f1 = bb_xfopen(file1, "r"); 943 f1 = bb_xfopen(file1, "r");
942 } 944 }
943 945
944 if (flags & D_EMPTY2) 946 if (flags & D_EMPTY2)
945 f2 = bb_xfopen(bb_dev_null, "r"); 947 f2 = bb_xfopen(bb_dev_null, "r");
946 else { 948 else {
947 if (strcmp(file2, "-") == 0) 949 if (strcmp(file2, "-") == 0)
948 f2 = stdin; 950 f2 = stdin;
949 else 951 else
950 f2 = bb_xfopen(file2, "r"); 952 f2 = bb_xfopen(file2, "r");
951 } 953 }
952 954
953 if ((i=files_differ(f1, f2, flags)) == 0) 955 if ((i = files_differ(f1, f2, flags)) == 0)
954 goto closem; 956 goto closem;
955 else if (i != 1) {/* 1 == ok */ 957 else if (i != 1) { /* 1 == ok */
956 /* error */ 958 /* error */
957 status |= 2; 959 status |= 2;
958 goto closem; 960 goto closem;
959 } 961 }
960 962
961 if (!asciifile(f1) || !asciifile(f2)) { 963 if (!asciifile(f1) || !asciifile(f2)) {
962 rval = D_BINARY; 964 rval = D_BINARY;
963 status |= 1; 965 status |= 1;
964 goto closem; 966 goto closem;
965 } 967 }
966 968
967 prepare(0, f1, stb1.st_size); 969 prepare(0, f1, stb1.st_size);
968 prepare(1, f2, stb2.st_size); 970 prepare(1, f2, stb2.st_size);
969 prune(); 971 prune();
970 sort(sfile[0], slen[0]); 972 sort(sfile[0], slen[0]);
971 sort(sfile[1], slen[1]); 973 sort(sfile[1], slen[1]);
972 974
973 member = (int *)file[1]; 975 member = (int *) file[1];
974 equiv(sfile[0], slen[0], sfile[1], slen[1], member); 976 equiv(sfile[0], slen[0], sfile[1], slen[1], member);
975 member = xrealloc(member, (slen[1] + 2) * sizeof(int)); 977 member = xrealloc(member, (slen[1] + 2) * sizeof(int));
976 978
977 class = (int *)file[0]; 979 class = (int *) file[0];
978 unsort(sfile[0], slen[0], class); 980 unsort(sfile[0], slen[0], class);
979 class = xrealloc(class, (slen[0] + 2) * sizeof(int)); 981 class = xrealloc(class, (slen[0] + 2) * sizeof(int));
980 982
981 klist = xmalloc((slen[0] + 2) * sizeof(int)); 983 klist = xmalloc((slen[0] + 2) * sizeof(int));
982 clen = 0; 984 clen = 0;
983 clistlen = 100; 985 clistlen = 100;
984 clist = xmalloc(clistlen * sizeof(struct cand)); 986 clist = xmalloc(clistlen * sizeof(struct cand));
985 i = stone(class, slen[0], member, klist); 987 i = stone(class, slen[0], member, klist);
986 free(member); 988 free(member);
987 free(class); 989 free(class);
988 990
989 J = xrealloc(J, (len[0] + 2) * sizeof(int)); 991 J = xrealloc(J, (len[0] + 2) * sizeof(int));
990 unravel(klist[i]); 992 unravel(klist[i]);
991 free(clist); 993 free(clist);
992 free(klist); 994 free(klist);
993 995
994 ixold = xrealloc(ixold, (len[0] + 2) * sizeof(long)); 996 ixold = xrealloc(ixold, (len[0] + 2) * sizeof(long));
995 ixnew = xrealloc(ixnew, (len[1] + 2) * sizeof(long)); 997 ixnew = xrealloc(ixnew, (len[1] + 2) * sizeof(long));
996 check(f1, f2); 998 check(f1, f2);
997 output(file1, f1, file2, f2); 999 output(file1, f1, file2, f2);
998 1000
999closem: 1001 closem:
1000 if (anychange) { 1002 if (anychange) {
1001 status |= 1; 1003 status |= 1;
1002 if (rval == D_SAME) 1004 if (rval == D_SAME)
1003 rval = D_DIFFER; 1005 rval = D_DIFFER;
1004 } 1006 }
1005 if (f1 != NULL) 1007 if (f1 != NULL)
1006 fclose(f1); 1008 fclose(f1);
1007 if (f2 != NULL) 1009 if (f2 != NULL)
1008 fclose(f2); 1010 fclose(f2);
1009 if (file1 != ofile1) 1011 if (file1 != ofile1)
1010 free(file1); 1012 free(file1);
1011 if (file2 != ofile2) 1013 if (file2 != ofile2)
1012 free(file2); 1014 free(file2);
1013 return (rval); 1015 return (rval);
1014} 1016}
1015 1017
1016#if ENABLE_FEATURE_DIFF_DIR 1018#if ENABLE_FEATURE_DIFF_DIR
1017static void do_diff (char *dir1, char *path1, char *dir2, char *path2) { 1019static void do_diff(char *dir1, char *path1, char *dir2, char *path2)
1018 1020{
1021
1019 int flags = D_HEADER; 1022 int flags = D_HEADER;
1020 int val; 1023 int val;
1021 1024
1022 char *fullpath1 = bb_xasprintf("%s/%s", dir1, path1); 1025 char *fullpath1 = bb_xasprintf("%s/%s", dir1, path1);
1023 char *fullpath2 = bb_xasprintf("%s/%s", dir2, path2); 1026 char *fullpath2 = bb_xasprintf("%s/%s", dir2, path2);
1024 1027
@@ -1036,7 +1039,7 @@ static void do_diff (char *dir1, char *path1, char *dir2, char *path2) {
1036 1039
1037 if (stb1.st_mode == 0) 1040 if (stb1.st_mode == 0)
1038 stb1.st_mode = stb2.st_mode; 1041 stb1.st_mode = stb2.st_mode;
1039 1042
1040 if (S_ISDIR(stb1.st_mode) && S_ISDIR(stb2.st_mode)) { 1043 if (S_ISDIR(stb1.st_mode) && S_ISDIR(stb2.st_mode)) {
1041 printf("Common subdirectories: %s and %s\n", fullpath1, fullpath2); 1044 printf("Common subdirectories: %s and %s\n", fullpath1, fullpath2);
1042 return; 1045 return;
@@ -1048,33 +1051,37 @@ static void do_diff (char *dir1, char *path1, char *dir2, char *path2) {
1048 val = D_SKIPPED2; 1051 val = D_SKIPPED2;
1049 else 1052 else
1050 val = diffreg(fullpath1, fullpath2, flags); 1053 val = diffreg(fullpath1, fullpath2, flags);
1051 1054
1052 print_status(val, fullpath1, fullpath2, NULL); 1055 print_status(val, fullpath1, fullpath2, NULL);
1053} 1056}
1054#endif 1057#endif
1055 1058
1056#if ENABLE_FEATURE_DIFF_DIR 1059#if ENABLE_FEATURE_DIFF_DIR
1057static int dir_strcmp(const void *p1, const void *p2) { 1060static int dir_strcmp(const void *p1, const void *p2)
1058 return strcmp(*(char * const *)p1, *(char * const *)p2); 1061{
1062 return strcmp(*(char *const *) p1, *(char *const *) p2);
1059} 1063}
1060 1064
1061/* This function adds a filename to dl, the directory listing. */ 1065/* This function adds a filename to dl, the directory listing. */
1062 1066
1063static int add_to_dirlist (const char *filename, 1067static int add_to_dirlist(const char *filename,
1064 struct stat ATTRIBUTE_UNUSED *sb, void *userdata) { 1068 struct stat ATTRIBUTE_UNUSED * sb, void *userdata)
1069{
1065 dl_count++; 1070 dl_count++;
1066 dl = xrealloc(dl, dl_count * sizeof(char *)); 1071 dl = xrealloc(dl, dl_count * sizeof(char *));
1067 dl[dl_count - 1] = bb_xstrdup(filename); 1072 dl[dl_count - 1] = bb_xstrdup(filename);
1068 if (cmd_flags & FLAG_r) { 1073 if (cmd_flags & FLAG_r) {
1069 int *pp = (int *) userdata; 1074 int *pp = (int *) userdata;
1070 int path_len = *pp + 1; 1075 int path_len = *pp + 1;
1076
1071 dl[dl_count - 1] = &(dl[dl_count - 1])[path_len]; 1077 dl[dl_count - 1] = &(dl[dl_count - 1])[path_len];
1072 } 1078 }
1073 return TRUE; 1079 return TRUE;
1074} 1080}
1075 1081
1076/* This returns a sorted directory listing. */ 1082/* This returns a sorted directory listing. */
1077static char **get_dir(char *path) { 1083static char **get_dir(char *path)
1084{
1078 1085
1079 int i; 1086 int i;
1080 char **retval; 1087 char **retval;
@@ -1094,7 +1101,8 @@ static char **get_dir(char *path) {
1094 1101
1095 /* Now fill dl with a listing. */ 1102 /* Now fill dl with a listing. */
1096 if (cmd_flags & FLAG_r) 1103 if (cmd_flags & FLAG_r)
1097 recursive_action(path, TRUE, TRUE, FALSE, add_to_dirlist, NULL, userdata); 1104 recursive_action(path, TRUE, TRUE, FALSE, add_to_dirlist, NULL,
1105 userdata);
1098 else { 1106 else {
1099 DIR *dp; 1107 DIR *dp;
1100 struct dirent *ep; 1108 struct dirent *ep;
@@ -1119,29 +1127,30 @@ static char **get_dir(char *path) {
1119 return retval; 1127 return retval;
1120} 1128}
1121 1129
1122static void diffdir (char *p1, char *p2) { 1130static void diffdir(char *p1, char *p2)
1123 1131{
1132
1124 char **dirlist1, **dirlist2; 1133 char **dirlist1, **dirlist2;
1125 char *dp1, *dp2; 1134 char *dp1, *dp2;
1126 int dirlist1_count, dirlist2_count; 1135 int dirlist1_count, dirlist2_count;
1127 int pos; 1136 int pos;
1128 1137
1129 /* Check for trailing slashes. */ 1138 /* Check for trailing slashes. */
1130 1139
1131 if (p1[strlen(p1) - 1] == '/') 1140 if (p1[strlen(p1) - 1] == '/')
1132 p1[strlen(p1) - 1] = '\0'; 1141 p1[strlen(p1) - 1] = '\0';
1133 if (p2[strlen(p2) - 1] == '/') 1142 if (p2[strlen(p2) - 1] == '/')
1134 p2[strlen(p2) - 1] = '\0'; 1143 p2[strlen(p2) - 1] = '\0';
1135 1144
1136 /* Get directory listings for p1 and p2. */ 1145 /* Get directory listings for p1 and p2. */
1137 1146
1138 dirlist1 = get_dir(p1); 1147 dirlist1 = get_dir(p1);
1139 dirlist1_count = dl_count; 1148 dirlist1_count = dl_count;
1140 dirlist1[dirlist1_count] = NULL; 1149 dirlist1[dirlist1_count] = NULL;
1141 dirlist2 = get_dir(p2); 1150 dirlist2 = get_dir(p2);
1142 dirlist2_count = dl_count; 1151 dirlist2_count = dl_count;
1143 dirlist2[dirlist2_count] = NULL; 1152 dirlist2[dirlist2_count] = NULL;
1144 1153
1145 /* If -S was set, find the starting point. */ 1154 /* If -S was set, find the starting point. */
1146 if (start) { 1155 if (start) {
1147 while (*dirlist1 != NULL && strcmp(*dirlist1, start) < 0) 1156 while (*dirlist1 != NULL && strcmp(*dirlist1, start) < 0)
@@ -1151,11 +1160,11 @@ static void diffdir (char *p1, char *p2) {
1151 if ((*dirlist1 == NULL) || (*dirlist2 == NULL)) 1160 if ((*dirlist1 == NULL) || (*dirlist2 == NULL))
1152 bb_error_msg("Invalid argument to -S"); 1161 bb_error_msg("Invalid argument to -S");
1153 } 1162 }
1154 1163
1155 /* Now that both dirlist1 and dirlist2 contain sorted directory 1164 /* Now that both dirlist1 and dirlist2 contain sorted directory
1156 * listings, we can start to go through dirlist1. If both listings 1165 * listings, we can start to go through dirlist1. If both listings
1157 * contain the same file, then do a normal diff. Otherwise, behaviour 1166 * contain the same file, then do a normal diff. Otherwise, behaviour
1158 * is determined by whether the -N flag is set. */ 1167 * is determined by whether the -N flag is set. */
1159 while (*dirlist1 != NULL || *dirlist2 != NULL) { 1168 while (*dirlist1 != NULL || *dirlist2 != NULL) {
1160 dp1 = *dirlist1; 1169 dp1 = *dirlist1;
1161 dp2 = *dirlist2; 1170 dp2 = *dirlist2;
@@ -1164,15 +1173,13 @@ static void diffdir (char *p1, char *p2) {
1164 do_diff(p1, dp1, p2, dp2); 1173 do_diff(p1, dp1, p2, dp2);
1165 dirlist1++; 1174 dirlist1++;
1166 dirlist2++; 1175 dirlist2++;
1167 } 1176 } else if (pos < 0) {
1168 else if (pos < 0) {
1169 if (cmd_flags & FLAG_N) 1177 if (cmd_flags & FLAG_N)
1170 do_diff(p1, dp1, p2, NULL); 1178 do_diff(p1, dp1, p2, NULL);
1171 else 1179 else
1172 print_only(p1, strlen(p1) + 1, dp1); 1180 print_only(p1, strlen(p1) + 1, dp1);
1173 dirlist1++; 1181 dirlist1++;
1174 } 1182 } else {
1175 else {
1176 if (cmd_flags & FLAG_N) 1183 if (cmd_flags & FLAG_N)
1177 do_diff(p1, NULL, p2, dp2); 1184 do_diff(p1, NULL, p2, dp2);
1178 else 1185 else
@@ -1185,14 +1192,18 @@ static void diffdir (char *p1, char *p2) {
1185 1192
1186 1193
1187 1194
1188int diff_main(int argc, char **argv) { 1195int diff_main(int argc, char **argv)
1196{
1189 char *ep; 1197 char *ep;
1190 int gotstdin = 0; 1198 int gotstdin = 0;
1191 1199
1192 char *U_opt; 1200 char *U_opt;
1193 llist_t *L_arg = NULL; 1201 llist_t *L_arg = NULL;
1202
1194 bb_opt_complementally = "L::"; 1203 bb_opt_complementally = "L::";
1195 cmd_flags = bb_getopt_ulflags(argc, argv, "abdiL:NqrsS:tTU:wu", &L_arg, &start, &U_opt); 1204 cmd_flags =
1205 bb_getopt_ulflags(argc, argv, "abdiL:NqrsS:tTU:wu", &L_arg, &start,
1206 &U_opt);
1196 1207
1197 if (cmd_flags & FLAG_L) { 1208 if (cmd_flags & FLAG_L) {
1198 while (L_arg) { 1209 while (L_arg) {
@@ -1209,13 +1220,14 @@ int diff_main(int argc, char **argv) {
1209 /* If both label[0] and label[1] were set, they need to be swapped. */ 1220 /* If both label[0] and label[1] were set, they need to be swapped. */
1210 if (label[0] && label[1]) { 1221 if (label[0] && label[1]) {
1211 char *tmp; 1222 char *tmp;
1223
1212 tmp = label[1]; 1224 tmp = label[1];
1213 label[1] = label[0]; 1225 label[1] = label[0];
1214 label[0] = tmp; 1226 label[0] = tmp;
1215 } 1227 }
1216 } 1228 }
1217 1229
1218 context = 3; /* This is the default number of lines of context. */ 1230 context = 3; /* This is the default number of lines of context. */
1219 if (cmd_flags & FLAG_U) { 1231 if (cmd_flags & FLAG_U) {
1220 context = strtol(U_opt, &ep, 10); 1232 context = strtol(U_opt, &ep, 10);
1221 if (context == 0) { 1233 if (context == 0) {
@@ -1224,36 +1236,35 @@ int diff_main(int argc, char **argv) {
1224 } 1236 }
1225 } 1237 }
1226 argc -= optind; 1238 argc -= optind;
1227 argv += optind; 1239 argv += optind;
1228 1240
1229 /* 1241 /*
1230 * Do sanity checks, fill in stb1 and stb2 and call the appropriate 1242 * Do sanity checks, fill in stb1 and stb2 and call the appropriate
1231 * driver routine. Both drivers use the contents of stb1 and stb2. 1243 * driver routine. Both drivers use the contents of stb1 and stb2.
1232 */ 1244 */
1233 if (argc < 2) { 1245 if (argc < 2) {
1234 bb_error_msg("Missing filename"); 1246 bb_error_msg("Missing filename");
1235 bb_show_usage(); 1247 bb_show_usage();
1236 } 1248 }
1237 if (strcmp(argv[0], "-") == 0) { 1249 if (strcmp(argv[0], "-") == 0) {
1238 fstat(STDIN_FILENO, &stb1); 1250 fstat(STDIN_FILENO, &stb1);
1239 gotstdin = 1; 1251 gotstdin = 1;
1240 } else 1252 } else
1241 xstat(argv[0], &stb1); 1253 xstat(argv[0], &stb1);
1242 if (strcmp(argv[1], "-") == 0) { 1254 if (strcmp(argv[1], "-") == 0) {
1243 fstat(STDIN_FILENO, &stb2); 1255 fstat(STDIN_FILENO, &stb2);
1244 gotstdin = 1; 1256 gotstdin = 1;
1245 } else 1257 } else
1246 xstat(argv[1], &stb2); 1258 xstat(argv[1], &stb2);
1247 if (gotstdin && (S_ISDIR(stb1.st_mode) || S_ISDIR(stb2.st_mode))) 1259 if (gotstdin && (S_ISDIR(stb1.st_mode) || S_ISDIR(stb2.st_mode)))
1248 bb_error_msg_and_die("Can't compare - to a directory"); 1260 bb_error_msg_and_die("Can't compare - to a directory");
1249 if (S_ISDIR(stb1.st_mode) && S_ISDIR(stb2.st_mode)) { 1261 if (S_ISDIR(stb1.st_mode) && S_ISDIR(stb2.st_mode)) {
1250#if ENABLE_FEATURE_DIFF_DIR 1262#if ENABLE_FEATURE_DIFF_DIR
1251 diffdir(argv[0], argv[1]); 1263 diffdir(argv[0], argv[1]);
1252#else 1264#else
1253 bb_error_msg_and_die("Directory comparison not supported"); 1265 bb_error_msg_and_die("Directory comparison not supported");
1254#endif 1266#endif
1255 } 1267 } else {
1256 else {
1257 if (S_ISDIR(stb1.st_mode)) { 1268 if (S_ISDIR(stb1.st_mode)) {
1258 argv[0] = concat_path_file(argv[0], argv[1]); 1269 argv[0] = concat_path_file(argv[0], argv[1]);
1259 xstat(argv[0], &stb1); 1270 xstat(argv[0], &stb1);
@@ -1266,4 +1277,3 @@ int diff_main(int argc, char **argv) {
1266 } 1277 }
1267 exit(status); 1278 exit(status);
1268} 1279}
1269