aboutsummaryrefslogtreecommitdiff
path: root/editors/diff.c
diff options
context:
space:
mode:
Diffstat (limited to 'editors/diff.c')
-rw-r--r--editors/diff.c84
1 files changed, 49 insertions, 35 deletions
diff --git a/editors/diff.c b/editors/diff.c
index e4d74abca..07594e8d8 100644
--- a/editors/diff.c
+++ b/editors/diff.c
@@ -227,10 +227,12 @@ struct cand {
227 227
228static int search(const int *c, int k, int y, const struct cand *list) 228static int search(const int *c, int k, int y, const struct cand *list)
229{ 229{
230 int i, j;
231
230 if (list[c[k]].y < y) /* quick look for typical case */ 232 if (list[c[k]].y < y) /* quick look for typical case */
231 return k + 1; 233 return k + 1;
232 234
233 for (int i = 0, j = k + 1;;) { 235 for (i = 0, j = k + 1;;) {
234 const int l = (i + j) >> 1; 236 const int l = (i + j) >> 1;
235 if (l > i) { 237 if (l > i) {
236 const int t = list[c[l]].y; 238 const int t = list[c[l]].y;
@@ -265,11 +267,13 @@ static void stone(const int *a, int n, const int *b, int *J, int pref)
265 int clistlen = 100; 267 int clistlen = 100;
266 int k = 0; 268 int k = 0;
267 struct cand *clist = xzalloc(clistlen * sizeof(clist[0])); 269 struct cand *clist = xzalloc(clistlen * sizeof(clist[0]));
270 struct cand cand;
271 struct cand *q;
268 int *klist = xzalloc((n + 2) * sizeof(klist[0])); 272 int *klist = xzalloc((n + 2) * sizeof(klist[0]));
269 /*clist[0] = (struct cand){0}; - xzalloc did it */ 273 /*clist[0] = (struct cand){0}; - xzalloc did it */
270 /*klist[0] = 0; */ 274 /*klist[0] = 0; */
271 275
272 for (struct cand cand = {1}; cand.x <= n; cand.x++) { 276 for (cand.x = 1; cand.x <= n; cand.x++) {
273 int j = a[cand.x], oldl = 0; 277 int j = a[cand.x], oldl = 0;
274 unsigned numtries = 0; 278 unsigned numtries = 0;
275 if (j == 0) 279 if (j == 0)
@@ -303,7 +307,7 @@ static void stone(const int *a, int n, const int *b, int *J, int pref)
303 } while ((cand.y = b[++j]) > 0 && numtries < bound); 307 } while ((cand.y = b[++j]) > 0 && numtries < bound);
304 } 308 }
305 /* Unravel */ 309 /* Unravel */
306 for (struct cand *q = clist + klist[k]; q->y; q = clist + q->pred) 310 for (q = clist + klist[k]; q->y; q = clist + q->pred)
307 J[q->x + pref] = q->y + pref; 311 J[q->x + pref] = q->y + pref;
308 free(klist); 312 free(klist);
309 free(clist); 313 free(clist);
@@ -348,10 +352,11 @@ static void equiv(struct line *a, int n, struct line *b, int m, int *c)
348 352
349static void unsort(const struct line *f, int l, int *b) 353static void unsort(const struct line *f, int l, int *b)
350{ 354{
355 int i;
351 int *a = xmalloc((l + 1) * sizeof(a[0])); 356 int *a = xmalloc((l + 1) * sizeof(a[0]));
352 for (int i = 1; i <= l; i++) 357 for (i = 1; i <= l; i++)
353 a[f[i].serial] = f[i].value; 358 a[f[i].serial] = f[i].value;
354 for (int i = 1; i <= l; i++) 359 for (i = 1; i <= l; i++)
355 b[i] = a[i]; 360 b[i] = a[i];
356 free(a); 361 free(a);
357} 362}
@@ -370,12 +375,13 @@ static int line_compar(const void *a, const void *b)
370 375
371static void fetch(FILE_and_pos_t *ft, const off_t *ix, int a, int b, int ch) 376static void fetch(FILE_and_pos_t *ft, const off_t *ix, int a, int b, int ch)
372{ 377{
373 for (int i = a; i <= b; i++) { 378 int i, j, col;
379 for (i = a; i <= b; i++) {
374 seek_ft(ft, ix[i - 1]); 380 seek_ft(ft, ix[i - 1]);
375 putchar(ch); 381 putchar(ch);
376 if (option_mask32 & FLAG(T)) 382 if (option_mask32 & FLAG(T))
377 putchar('\t'); 383 putchar('\t');
378 for (int j = 0, col = 0; j < ix[i] - ix[i - 1]; j++) { 384 for (j = 0, col = 0; j < ix[i] - ix[i - 1]; j++) {
379 int c = fgetc(ft->ft_fp); 385 int c = fgetc(ft->ft_fp);
380 if (c == EOF) { 386 if (c == EOF) {
381 printf("\n\\ No newline at end of file\n"); 387 printf("\n\\ No newline at end of file\n");
@@ -410,19 +416,20 @@ static NOINLINE int *create_J(FILE_and_pos_t ft[2], int nlen[2], off_t *ix[2])
410{ 416{
411 int *J, slen[2], *class, *member; 417 int *J, slen[2], *class, *member;
412 struct line *nfile[2], *sfile[2]; 418 struct line *nfile[2], *sfile[2];
413 int pref = 0, suff = 0; 419 int pref = 0, suff = 0, i, j, delta;
414 420
415 /* Lines of both files are hashed, and in the process 421 /* Lines of both files are hashed, and in the process
416 * their offsets are stored in the array ix[fileno] 422 * their offsets are stored in the array ix[fileno]
417 * where fileno == 0 points to the old file, and 423 * where fileno == 0 points to the old file, and
418 * fileno == 1 points to the new one. 424 * fileno == 1 points to the new one.
419 */ 425 */
420 for (int i = 0; i < 2; i++) { 426 for (i = 0; i < 2; i++) {
421 unsigned hash; 427 unsigned hash;
422 token_t tok; 428 token_t tok;
423 size_t sz = 100; 429 size_t sz = 100;
424 nfile[i] = xmalloc((sz + 3) * sizeof(nfile[i][0])); 430 nfile[i] = xmalloc((sz + 3) * sizeof(nfile[i][0]));
425 /* ft gets here without the correct position, cant use seek_ft */ 431 /* ft gets here without the correct position, cant use seek_ft */
432 ft[i].ft_pos = 0;
426 fseeko(ft[i].ft_fp, 0, SEEK_SET); 433 fseeko(ft[i].ft_fp, 0, SEEK_SET);
427 434
428 nlen[i] = 0; 435 nlen[i] = 0;
@@ -460,11 +467,11 @@ start:
460 nlen[i]--; 467 nlen[i]--;
461 /* Now we copy the line offsets into ix */ 468 /* Now we copy the line offsets into ix */
462 ix[i] = xmalloc((nlen[i] + 2) * sizeof(ix[i][0])); 469 ix[i] = xmalloc((nlen[i] + 2) * sizeof(ix[i][0]));
463 for (int j = 0; j < nlen[i] + 1; j++) 470 for (j = 0; j < nlen[i] + 1; j++)
464 ix[i][j] = nfile[i][j].offset; 471 ix[i][j] = nfile[i][j].offset;
465 } 472 }
466 473
467 /* lenght of prefix and suffix is calculated */ 474 /* length of prefix and suffix is calculated */
468 for (; pref < nlen[0] && pref < nlen[1] && 475 for (; pref < nlen[0] && pref < nlen[1] &&
469 nfile[0][pref + 1].value == nfile[1][pref + 1].value; 476 nfile[0][pref + 1].value == nfile[1][pref + 1].value;
470 pref++); 477 pref++);
@@ -475,10 +482,10 @@ start:
475 * the result being sorted and stored in sfile[fileno], 482 * the result being sorted and stored in sfile[fileno],
476 * and their sizes are stored in slen[fileno] 483 * and their sizes are stored in slen[fileno]
477 */ 484 */
478 for (int j = 0; j < 2; j++) { 485 for (j = 0; j < 2; j++) {
479 sfile[j] = nfile[j] + pref; 486 sfile[j] = nfile[j] + pref;
480 slen[j] = nlen[j] - pref - suff; 487 slen[j] = nlen[j] - pref - suff;
481 for (int i = 0; i <= slen[j]; i++) 488 for (i = 0; i <= slen[j]; i++)
482 sfile[j][i].serial = i; 489 sfile[j][i].serial = i;
483 qsort(sfile[j] + 1, slen[j], sizeof(*sfile[j]), line_compar); 490 qsort(sfile[j] + 1, slen[j], sizeof(*sfile[j]), line_compar);
484 } 491 }
@@ -494,7 +501,7 @@ start:
494 free(nfile[1]); 501 free(nfile[1]);
495 502
496 class = xmalloc((slen[0] + 1) * sizeof(class[0])); 503 class = xmalloc((slen[0] + 1) * sizeof(class[0]));
497 for (int i = 1; i <= slen[0]; i++) /* Unsorting */ 504 for (i = 1; i <= slen[0]; i++) /* Unsorting */
498 class[sfile[0][i].serial] = sfile[0][i].value; 505 class[sfile[0][i].serial] = sfile[0][i].value;
499 free(nfile[0]); 506 free(nfile[0]);
500#else 507#else
@@ -512,7 +519,7 @@ start:
512 * are initialized with 0 (no matches), so that function stone can 519 * are initialized with 0 (no matches), so that function stone can
513 * then assign them their right values 520 * then assign them their right values
514 */ 521 */
515 for (int i = 0, delta = nlen[1] - nlen[0]; i <= nlen[0]; i++) 522 for (i = 0, delta = nlen[1] - nlen[0]; i <= nlen[0]; i++)
516 J[i] = i <= pref ? i : 523 J[i] = i <= pref ? i :
517 i > (nlen[0] - suff) ? (i + delta) : 0; 524 i > (nlen[0] - suff) ? (i + delta) : 0;
518 /* Here the magic is performed */ 525 /* Here the magic is performed */
@@ -526,14 +533,14 @@ start:
526 * which, due to limitations intrinsic to any hashing algorithm, 533 * which, due to limitations intrinsic to any hashing algorithm,
527 * are different but ended up confounded as the same 534 * are different but ended up confounded as the same
528 */ 535 */
529 for (int i = 1; i <= nlen[0]; i++) { 536 for (i = 1; i <= nlen[0]; i++) {
530 if (!J[i]) 537 if (!J[i])
531 continue; 538 continue;
532 539
533 seek_ft(&ft[0], ix[0][i - 1]); 540 seek_ft(&ft[0], ix[0][i - 1]);
534 seek_ft(&ft[1], ix[1][J[i] - 1]); 541 seek_ft(&ft[1], ix[1][J[i] - 1]);
535 542
536 for (int j = J[i]; i <= nlen[0] && J[i] == j; i++, j++) { 543 for (j = J[i]; i <= nlen[0] && J[i] == j; i++, j++) {
537 token_t tok0 = 0, tok1 = 0; 544 token_t tok0 = 0, tok1 = 0;
538 do { 545 do {
539 tok0 = read_token(&ft[0], tok0); 546 tok0 = read_token(&ft[0], tok0);
@@ -555,13 +562,18 @@ static bool diff(FILE* fp[2], char *file[2])
555{ 562{
556 int nlen[2]; 563 int nlen[2];
557 off_t *ix[2]; 564 off_t *ix[2];
558 FILE_and_pos_t ft[2] = { { fp[0] }, { fp[1] } }; 565 FILE_and_pos_t ft[2];
559 int *J = create_J(ft, nlen, ix);
560
561 bool anychange = false;
562 typedef struct { int a, b; } vec_t[2]; 566 typedef struct { int a, b; } vec_t[2];
563 vec_t *vec = NULL; 567 vec_t *vec = NULL;
564 int i = 1, idx = -1; 568 int i = 1, j, k, idx = -1;
569 bool anychange = false;
570 int *J;
571
572 ft[0].ft_fp = fp[0];
573 ft[1].ft_fp = fp[1];
574 /* note that ft[i].ft_pos is unintitalized, create_J()
575 * must not assume otherwise */
576 J = create_J(ft, nlen, ix);
565 577
566 do { 578 do {
567 bool nonempty = false; 579 bool nonempty = false;
@@ -596,8 +608,8 @@ static bool diff(FILE* fp[2], char *file[2])
596 break; 608 break;
597 } 609 }
598 610
599 for (int j = 0; j < 2; j++) 611 for (j = 0; j < 2; j++)
600 for (int k = v[j].a; k < v[j].b; k++) 612 for (k = v[j].a; k < v[j].b; k++)
601 nonempty |= (ix[j][k+1] - ix[j][k] != 1); 613 nonempty |= (ix[j][k+1] - ix[j][k] != 1);
602 614
603 vec = xrealloc_vector(vec, 6, ++idx); 615 vec = xrealloc_vector(vec, 6, ++idx);
@@ -612,6 +624,7 @@ static bool diff(FILE* fp[2], char *file[2])
612 if (idx < 0 || ((option_mask32 & FLAG(B)) && !nonempty)) 624 if (idx < 0 || ((option_mask32 & FLAG(B)) && !nonempty))
613 goto cont; 625 goto cont;
614 if (!(option_mask32 & FLAG(q))) { 626 if (!(option_mask32 & FLAG(q))) {
627 int lowa;
615 vec_t span, *cvp = vec; 628 vec_t span, *cvp = vec;
616 629
617 if (!anychange) { 630 if (!anychange) {
@@ -621,7 +634,7 @@ static bool diff(FILE* fp[2], char *file[2])
621 } 634 }
622 635
623 printf("@@"); 636 printf("@@");
624 for (int j = 0; j < 2; j++) { 637 for (j = 0; j < 2; j++) {
625 int a = span[j].a = MAX(1, (*cvp)[j].a - opt_U_context); 638 int a = span[j].a = MAX(1, (*cvp)[j].a - opt_U_context);
626 int b = span[j].b = MIN(nlen[j], vec[idx][j].b + opt_U_context); 639 int b = span[j].b = MIN(nlen[j], vec[idx][j].b + opt_U_context);
627 640
@@ -635,12 +648,12 @@ static bool diff(FILE* fp[2], char *file[2])
635 * Output changes in "unified" diff format--the old and new lines 648 * Output changes in "unified" diff format--the old and new lines
636 * are printed together. 649 * are printed together.
637 */ 650 */
638 for (int lowa = span[0].a; ; lowa = (*cvp++)[0].b + 1) { 651 for (lowa = span[0].a; ; lowa = (*cvp++)[0].b + 1) {
639 bool end = cvp > &vec[idx]; 652 bool end = cvp > &vec[idx];
640 fetch(&ft[0], ix[0], lowa, end ? span[0].b : (*cvp)[0].a - 1, ' '); 653 fetch(&ft[0], ix[0], lowa, end ? span[0].b : (*cvp)[0].a - 1, ' ');
641 if (end) 654 if (end)
642 break; 655 break;
643 for (int j = 0; j < 2; j++) 656 for (j = 0; j < 2; j++)
644 fetch(&ft[j], ix[j], (*cvp)[j].a, (*cvp)[j].b, j ? '+' : '-'); 657 fetch(&ft[j], ix[j], (*cvp)[j].a, (*cvp)[j].b, j ? '+' : '-');
645 } 658 }
646 } 659 }
@@ -660,9 +673,9 @@ static int diffreg(char *file[2])
660{ 673{
661 FILE *fp[2] = { stdin, stdin }; 674 FILE *fp[2] = { stdin, stdin };
662 bool binary = false, differ = false; 675 bool binary = false, differ = false;
663 int status = STATUS_SAME; 676 int status = STATUS_SAME, i;
664 677
665 for (int i = 0; i < 2; i++) { 678 for (i = 0; i < 2; i++) {
666 int fd = open_or_warn_stdin(file[i]); 679 int fd = open_or_warn_stdin(file[i]);
667 if (fd == -1) 680 if (fd == -1)
668 goto out; 681 goto out;
@@ -688,7 +701,7 @@ static int diffreg(char *file[2])
688 const size_t sz = COMMON_BUFSIZE / 2; 701 const size_t sz = COMMON_BUFSIZE / 2;
689 char *const buf0 = bb_common_bufsiz1; 702 char *const buf0 = bb_common_bufsiz1;
690 char *const buf1 = buf0 + sz; 703 char *const buf1 = buf0 + sz;
691 int i, j; 704 int j, k;
692 i = fread(buf0, 1, sz, fp[0]); 705 i = fread(buf0, 1, sz, fp[0]);
693 j = fread(buf1, 1, sz, fp[1]); 706 j = fread(buf1, 1, sz, fp[1]);
694 if (i != j) { 707 if (i != j) {
@@ -697,7 +710,7 @@ static int diffreg(char *file[2])
697 } 710 }
698 if (i == 0) 711 if (i == 0)
699 break; 712 break;
700 for (int k = 0; k < i; k++) { 713 for (k = 0; k < i; k++) {
701 if (!buf0[k] || !buf1[k]) 714 if (!buf0[k] || !buf1[k])
702 binary = true; 715 binary = true;
703 if (buf0[k] != buf1[k]) 716 if (buf0[k] != buf1[k])
@@ -771,9 +784,10 @@ static int FAST_FUNC skip_dir(const char *filename,
771static void diffdir(char *p[2], const char *s_start) 784static void diffdir(char *p[2], const char *s_start)
772{ 785{
773 struct dlist list[2]; 786 struct dlist list[2];
787 int i;
774 788
775 memset(&list, 0, sizeof(list)); 789 memset(&list, 0, sizeof(list));
776 for (int i = 0; i < 2; i++) { 790 for (i = 0; i < 2; i++) {
777 /*list[i].s = list[i].e = 0; - memset did it */ 791 /*list[i].s = list[i].e = 0; - memset did it */
778 /*list[i].dl = NULL; */ 792 /*list[i].dl = NULL; */
779 793
@@ -815,7 +829,7 @@ static void diffdir(char *p[2], const char *s_start)
815 else { 829 else {
816 char *fullpath[2], *path[2]; /* if -N */ 830 char *fullpath[2], *path[2]; /* if -N */
817 831
818 for (int i = 0; i < 2; i++) { 832 for (i = 0; i < 2; i++) {
819 if (pos == 0 || i == k) { 833 if (pos == 0 || i == k) {
820 path[i] = fullpath[i] = concat_path_file(p[i], dp[i]); 834 path[i] = fullpath[i] = concat_path_file(p[i], dp[i]);
821 stat(fullpath[i], &stb[i]); 835 stat(fullpath[i], &stb[i]);
@@ -883,7 +897,7 @@ static const char diff_longopts[] ALIGN1 =
883int diff_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 897int diff_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
884int diff_main(int argc UNUSED_PARAM, char **argv) 898int diff_main(int argc UNUSED_PARAM, char **argv)
885{ 899{
886 int gotstdin = 0; 900 int gotstdin = 0, i;
887 char *file[2], *s_start = NULL; 901 char *file[2], *s_start = NULL;
888 llist_t *L_arg = NULL; 902 llist_t *L_arg = NULL;
889 903
@@ -900,7 +914,7 @@ int diff_main(int argc UNUSED_PARAM, char **argv)
900 while (L_arg) 914 while (L_arg)
901 label[!!label[0]] = llist_pop(&L_arg); 915 label[!!label[0]] = llist_pop(&L_arg);
902 xfunc_error_retval = 2; 916 xfunc_error_retval = 2;
903 for (int i = 0; i < 2; i++) { 917 for (i = 0; i < 2; i++) {
904 file[i] = argv[i]; 918 file[i] = argv[i];
905 /* Compat: "diff file name_which_doesnt_exist" exits with 2 */ 919 /* Compat: "diff file name_which_doesnt_exist" exits with 2 */
906 if (LONE_DASH(file[i])) { 920 if (LONE_DASH(file[i])) {