tadd -c option - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 4ac5f249ad40f3452fc87dc9a3f4b9d9546c83b0
 (DIR) parent 57d2613621107f7ee9d9e717c3c2903b1caf4bbe
 (HTM) Author: rsc <devnull@localhost>
       Date:   Wed, 26 Jan 2005 07:10:02 +0000
       
       add -c option
       
       Diffstat:
         M man/man1/diff.1                     |       7 ++++++-
         M src/cmd/diff/diff.h                 |       2 +-
         M src/cmd/diff/diffio.c               |      80 +++++++++++++++++++++++++++++++
         M src/cmd/diff/diffreg.c              |       1 +
       
       4 files changed, 88 insertions(+), 2 deletions(-)
       ---
 (DIR) diff --git a/man/man1/diff.1 b/man/man1/diff.1
       t@@ -4,7 +4,7 @@ diff \- differential file comparator
        .SH SYNOPSIS
        .B diff
        [
       -.B -efmnbwr
       +.B -cefmnbwr
        ] file1 ... file2
        .SH DESCRIPTION
        .I Diff
       t@@ -123,6 +123,11 @@ not useful with
        in the opposite order. It may, however, be
        useful as input to a stream-oriented post-processor.
        .PP
       +The
       +.B -c
       +option includes three lines of context around each
       +change, merging changes whose contexts overlap.
       +.PP
        Except in rare circumstances,
        .I diff
        finds a smallest sufficient set of file
 (DIR) diff --git a/src/cmd/diff/diff.h b/src/cmd/diff/diff.h
       t@@ -24,4 +24,4 @@ Biobuf *prepare(int, char *);
        void panic(int, char *, ...);
        void check(Biobuf *, Biobuf *);
        void change(int, int, int, int);
       -
       +void flushchanges(void);
 (DIR) diff --git a/src/cmd/diff/diffio.c b/src/cmd/diff/diffio.c
       t@@ -226,7 +226,18 @@ static void
        fetch(long *f, int a, int b, Biobuf *bp, char *s)
        {
                char buf[MAXLINELEN];
       +        int maxb;
        
       +        if(a <= 1)
       +                a = 1;
       +        if(bp == input[0])
       +                maxb = len[0];
       +        else
       +                maxb = len[1];
       +        if(b > maxb)
       +                b = maxb;
       +        if(a > maxb)
       +                return;
                Bseek(bp, f[a-1], 0);
                while (a++ <= b) {
                        readline(bp, buf);
       t@@ -234,11 +245,24 @@ fetch(long *f, int a, int b, Biobuf *bp, char *s)
                }
        }
        
       +typedef struct Change Change;
       +struct Change
       +{
       +        int a;
       +        int b;
       +        int c;
       +        int d;
       +};
       +
       +Change *changes;
       +int nchanges;
       +
        void
        change(int a, int b, int c, int d)
        {
                char verb;
                char buf[4];
       +        Change *ch;
        
                if (a > b && c > d)
                        return;
       t@@ -277,6 +301,15 @@ change(int a, int b, int c, int d)
                        Bputc(&stdout, verb);
                        range(a, b, " ");
                        break;
       +        case 'c':
       +                if(nchanges%1024 == 0)
       +                        changes = erealloc(changes, (nchanges+1024)*sizeof(changes[0]));
       +                ch = &changes[nchanges++];
       +                ch->a = a;
       +                ch->b = b;
       +                ch->c = c;
       +                ch->d = d;
       +                return;
                }
                Bputc(&stdout, '\n');
                if (mode == 0 || mode == 'n') {
       t@@ -289,3 +322,50 @@ change(int a, int b, int c, int d)
                        Bprint(&stdout, ".\n");
        }
        
       +enum
       +{
       +        Lines = 3,        /* number of lines of context shown */
       +};
       +
       +int
       +changeset(int i)
       +{
       +        while(i<nchanges && changes[i].b+1+2*Lines > changes[i+1].a)
       +                i++;
       +        if(i<nchanges)
       +                return i+1;
       +        return nchanges;
       +}
       +
       +void
       +flushchanges(void)
       +{
       +        int a, b, c, d, at;
       +        int i, j;
       +
       +        if(nchanges == 0)
       +                return;
       +        
       +        for(i=0; i<nchanges; ){
       +                j = changeset(i);
       +                a = changes[i].a;
       +                b = changes[j-1].b;
       +                c = changes[i].c;
       +                d = changes[j-1].d;
       +                Bprint(&stdout, "%s:", file1);
       +                range(a, b, ",");
       +                Bprint(&stdout, " - ");
       +                Bprint(&stdout, "%s:", file2);
       +                range(c, d, ",");
       +                Bputc(&stdout, '\n');
       +                at = a-Lines;
       +                for(; i<j; i++){
       +                        fetch(ixold, at, changes[i].a-1, input[0], "  ");
       +                        fetch(ixold, changes[i].a, changes[i].b, input[0], "< ");
       +                        fetch(ixnew, changes[i].c, changes[i].d, input[1], "> ");
       +                        at = changes[i].b+1;
       +                }
       +                fetch(ixold, at, b+Lines, input[0], "  ");
       +        }
       +        nchanges = 0;
       +}
 (DIR) diff --git a/src/cmd/diff/diffreg.c b/src/cmd/diff/diffreg.c
       t@@ -313,6 +313,7 @@ output(void)
                }
                if (m == 0)
                        change(1, 0, 1, len[1]);
       +        flushchanges();
        }
        
        #define BUF 4096