/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */ /* The copyright notice above does not evidence any */ /* actual or intended publication of such source code. */ #ident "@(#)diffh.c 1.10 95/03/22 SMI" /* SVr4.0 1.3 */ #include #include #include #include #include #include #define C 3 #define RANGE 30 #define LEN 255 #define INF 16384 char *text[2][RANGE]; long lineno[2] = {1, 1}; /* no. of 1st stored line in each file */ int ntext[2]; /* number of stored lines in each */ long n0, n1; /* scan pointer in each */ int bflag; int debug = 0; FILE *file[2]; /* return pointer to line n of file f */ char * getl(f, n) long n; { register char *t; register delta, nt; again: delta = n - lineno[f]; nt = ntext[f]; if (delta < 0) progerr("1"); if (delta < nt) return (text[f][delta]); if (delta > nt) progerr("2"); if (nt >= RANGE) progerr("3"); if (feof(file[f])) return (NULL); t = text[f][nt]; if (t == 0) { t = text[f][nt] = (char *)malloc(LEN+1); if (t == NULL) if (hardsynch()) goto again; else progerr("5"); } t = fgets(t, LEN, file[f]); if (t != NULL) ntext[f]++; return (t); } /* remove thru line n of file f from storage */ clrl(f, n) long n; { register i, j; j = n-lineno[f]+1; for (i = 0; i+j < ntext[f]; i++) movstr(text[f][i+j], text[f][i]); lineno[f] = n+1; ntext[f] -= j; } movstr(s, t) register char *s, *t; { while (*t++ = *s++) continue; } main(argc, argv) char **argv; { char *s0, *s1; FILE *dopen(); if (*argv[1] == '-') { argc--; argv++; while (*++argv[0]) if (*argv[0] == 'b') bflag++; } (void) setlocale(LC_ALL, ""); #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ #endif (void) textdomain(TEXT_DOMAIN); if (argc != 3) error("must have 2 file arguments", ""); file[0] = dopen(argv[1], argv[2]); file[1] = dopen(argv[2], argv[1]); for (;;) { s0 = getl(0, ++n0); s1 = getl(1, ++n1); if (s0 == NULL || s1 == NULL) break; if (cmp(s0, s1) != 0) { if (!easysynch() && !hardsynch()) progerr("5"); } else { clrl(0, n0); clrl(1, n1); } } if (s0 == NULL && s1 == NULL) return; if (s0 == NULL) output(-1, INF); if (s1 == NULL) output(INF, -1); } /* synch on C successive matches */ easysynch() { int i, j; register k, m; char *s0, *s1; for (i = j = 1; i < RANGE && j < RANGE; i++, j++) { s0 = getl(0, n0+i); if (s0 == NULL) return (output(INF, INF)); for (k = C-1; k < j; k++) { for (m = 0; m < C; m++) if (cmp(getl(0, n0+i-m), getl(1, n1+k-m)) != 0) goto cont1; return (output(i-C, k-C)); cont1: ; } s1 = getl(1, n1+j); if (s1 == NULL) return (output(INF, INF)); for (k = C-1; k <= i; k++) { for (m = 0; m < C; m++) if (cmp(getl(0, n0+k-m), getl(1, n1+j-m)) != 0) goto cont2; return (output(k-C, j-C)); cont2: ; } } return (0); } output(a, b) { register i; char *s; if (a < 0) change(n0-1, 0, n1, b, "a"); else if (b < 0) change(n0, a, n1-1, 0, "d"); else change(n0, a, n1, b, "c"); for (i = 0; i <= a; i++) { s = getl(0, n0+i); if (s == NULL) break; printf("< %s", s); clrl(0, n0+i); } n0 += i-1; if (a >= 0 && b >= 0) printf("---\n"); for (i = 0; i <= b; i++) { s = getl(1, n1+i); if (s == NULL) break; printf("> %s", s); clrl(1, n1+i); } n1 += i-1; return (1); } change(a, b, c, d, s) long a, c; char *s; { range(a, b); printf("%s", s); range(c, d); printf("\n"); } range(a, b) long a; { if (b == INF) printf("%ld,$", a); else if (b == 0) printf("%ld", a); else printf("%ld,%ld", a, a+b); } cmp(s, t) char *s, *t; { if (debug) printf("%s:%s\n", s, t); for (;;) { if (bflag && isspace(*s) && isspace(*t)) { while (isspace(*++s)) ; while (isspace(*++t)) ; } if (*s != *t || *s == 0) break; s++; t++; } return (*s-*t); } FILE * dopen(f1, f2) char *f1, *f2; { FILE *f; char b[PATH_MAX], *bptr, *eptr; struct stat statbuf; if (cmp(f1, "-") == 0) if (cmp(f2, "-") == 0) error("can't do - -", ""); else return (stdin); if (stat(f1, &statbuf) == -1) error("can't access ", f1); if ((statbuf.st_mode & S_IFMT) == S_IFDIR) { for (bptr = b; *bptr = *f1++; bptr++) ; *bptr++ = '/'; for (eptr = f2; *eptr; eptr++) if (*eptr == '/' && eptr[1] != 0 && eptr[1] != '/') f2 = eptr+1; while (*bptr++ = *f2++) ; f1 = b; } f = fopen(f1, "r"); if (f == NULL) error("can't open", f1); return (f); } progerr(s) char *s; { error("program error ", s); } error(s, t) char *s, *t; { fprintf(stderr, "diffh: %s%s\n", gettext(s), t); exit(1); } /* stub for resychronization beyond limits of text buf */ hardsynch() { change(n0, INF, n1, INF, "c"); printf(gettext("---change record omitted\n")); error("can't resynchronize", ""); return (0); }