diff options
author | John Ankarström <john@ankarstrom.se> | 2021-01-28 21:33:30 +0000 |
---|---|---|
committer | John Ankarström <john@ankarstrom.se> | 2021-01-28 21:33:30 +0000 |
commit | 51b5b02f52cc6f314029f3f2fe97afdc26ba0f25 (patch) | |
tree | 711d1efadeb78ad9b2d9f7b629350358838bc626 /patch/diff-c-plus | |
parent | f3fd330cddade1c66d0f101d5cc6f657c4cd1bb6 (diff) | |
download | plan9-51b5b02f52cc6f314029f3f2fe97afdc26ba0f25.tar.gz |
Add various patches
Diffstat (limited to 'patch/diff-c-plus')
-rw-r--r-- | patch/diff-c-plus/diffio.c | 401 | ||||
-rw-r--r-- | patch/diff-c-plus/diffio.c.orig | 401 | ||||
-rw-r--r-- | patch/diff-c-plus/email | 1 | ||||
-rw-r--r-- | patch/diff-c-plus/files | 1 | ||||
-rw-r--r-- | patch/diff-c-plus/notes | 0 | ||||
-rw-r--r-- | patch/diff-c-plus/readme | 6 |
6 files changed, 810 insertions, 0 deletions
diff --git a/patch/diff-c-plus/diffio.c b/patch/diff-c-plus/diffio.c new file mode 100644 index 0000000..146bef3 --- /dev/null +++ b/patch/diff-c-plus/diffio.c @@ -0,0 +1,401 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include <ctype.h> +#include "diff.h" + +struct line { + int serial; + int value; +}; +extern struct line *file[2]; +extern int len[2]; +extern long *ixold, *ixnew; +extern int *J; + +static Biobuf *input[2]; +static char *file1, *file2; +static int firstchange; + +#define MAXLINELEN 4096 +#define MIN(x, y) ((x) < (y) ? (x): (y)) + +static int +readline(Biobuf *bp, char *buf) +{ + int c; + char *p, *e; + + p = buf; + e = p + MAXLINELEN-1; + do { + c = Bgetc(bp); + if (c < 0) { + if (p == buf) + return -1; + break; + } + if (c == '\n') + break; + *p++ = c; + } while (p < e); + *p = 0; + if (c != '\n' && c >= 0) { + do c = Bgetc(bp); + while (c >= 0 && c != '\n'); + } + return p - buf; +} + +#define HALFLONG 16 +#define low(x) (x&((1L<<HALFLONG)-1)) +#define high(x) (x>>HALFLONG) + +/* + * hashing has the effect of + * arranging line in 7-bit bytes and then + * summing 1-s complement in 16-bit hunks + */ +static int +readhash(Biobuf *bp, char *buf) +{ + long sum; + unsigned shift; + char *p; + int len, space; + + sum = 1; + shift = 0; + if ((len = readline(bp, buf)) == -1) + return 0; + p = buf; + switch(bflag) /* various types of white space handling */ + { + case 0: + while (len--) { + sum += (long)*p++ << (shift &= (HALFLONG-1)); + shift += 7; + } + break; + case 1: + /* + * coalesce multiple white-space + */ + for (space = 0; len--; p++) { + if (isspace(*p)) { + space++; + continue; + } + if (space) { + shift += 7; + space = 0; + } + sum += (long)*p << (shift &= (HALFLONG-1)); + shift += 7; + } + break; + default: + /* + * strip all white-space + */ + while (len--) { + if (isspace(*p)) { + p++; + continue; + } + sum += (long)*p++ << (shift &= (HALFLONG-1)); + shift += 7; + } + break; + } + sum = low(sum) + high(sum); + return ((short)low(sum) + (short)high(sum)); +} + +Biobuf * +prepare(int i, char *arg) +{ + struct line *p; + int j, h; + Biobuf *bp; + char *cp, buf[MAXLINELEN]; + int nbytes; + Rune r; + + bp = Bopen(arg, OREAD); + if (!bp) { + panic(mflag ? 0: 2, "cannot open %s: %r\n", arg); + return 0; + } + if (binary) + return bp; + nbytes = Bread(bp, buf, MIN(1024, MAXLINELEN)); + if (nbytes > 0) { + cp = buf; + while (cp < buf+nbytes-UTFmax) { + /* + * heuristic for a binary file in the + * brave new UNICODE world + */ + cp += chartorune(&r, cp); + if (r == 0 || (r > 0x7f && r <= 0xa0)) { + binary++; + return bp; + } + } + Bseek(bp, 0, 0); + } + p = MALLOC(struct line, 3); + for (j = 0; h = readhash(bp, buf); p[j].value = h) + p = REALLOC(p, struct line, (++j+3)); + len[i] = j; + file[i] = p; + input[i] = bp; /*fix*/ + if (i == 0) { /*fix*/ + file1 = arg; + firstchange = 0; + } + else + file2 = arg; + return bp; +} + +static int +squishspace(char *buf) +{ + char *p, *q; + int space; + + for (space = 0, q = p = buf; *q; q++) { + if (isspace(*q)) { + space++; + continue; + } + if (space && bflag == 1) { + *p++ = ' '; + space = 0; + } + *p++ = *q; + } + *p = 0; + return p - buf; +} + +/* + * need to fix up for unexpected EOF's + */ +void +check(Biobuf *bf, Biobuf *bt) +{ + int f, t, flen, tlen; + char fbuf[MAXLINELEN], tbuf[MAXLINELEN]; + + ixold[0] = ixnew[0] = 0; + for (f = t = 1; f < len[0]; f++) { + flen = readline(bf, fbuf); + ixold[f] = ixold[f-1] + flen + 1; /* ftell(bf) */ + if (J[f] == 0) + continue; + do { + tlen = readline(bt, tbuf); + ixnew[t] = ixnew[t-1] + tlen + 1; /* ftell(bt) */ + } while (t++ < J[f]); + if (bflag) { + flen = squishspace(fbuf); + tlen = squishspace(tbuf); + } + if (flen != tlen || strcmp(fbuf, tbuf)) + J[f] = 0; + } + while (t < len[1]) { + tlen = readline(bt, tbuf); + ixnew[t] = ixnew[t-1] + tlen + 1; /* fseek(bt) */ + t++; + } +} + +static void +range(int a, int b, char *separator) +{ + Bprint(&stdout, "%d", a > b ? b: a); + if (a < b) + Bprint(&stdout, "%s%d", separator, b); +} + +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); + Bprint(&stdout, "%s%s\n", s, buf); + } +} + +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; + anychange = 1; + if (mflag && firstchange == 0) { + if(mode) { + buf[0] = '-'; + buf[1] = mode; + buf[2] = ' '; + buf[3] = '\0'; + } else { + buf[0] = '\0'; + } + Bprint(&stdout, "diff %s%s %s\n", buf, file1, file2); + firstchange = 1; + } + verb = a > b ? 'a': c > d ? 'd': 'c'; + switch(mode) { + case 'e': + range(a, b, ","); + Bputc(&stdout, verb); + break; + case 0: + range(a, b, ","); + Bputc(&stdout, verb); + range(c, d, ","); + break; + case 'n': + Bprint(&stdout, "%s:", file1); + range(a, b, ","); + Bprint(&stdout, " %c ", verb); + Bprint(&stdout, "%s:", file2); + range(c, d, ","); + break; + case 'f': + Bputc(&stdout, verb); + range(a, b, " "); + break; + case 'c': + case 'a': + case 'u': + 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') { + fetch(ixold, a, b, input[0], "< "); + if (a <= b && c <= d) + Bprint(&stdout, "---\n"); + } + fetch(ixnew, c, d, input[1], mode == 0 || mode == 'n' ? "> ": ""); + if (mode != 0 && mode != 'n' && c <= 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 +fileheader(void) +{ + if(mode != 'u') + return; + Bprint(&stdout, "--- %s\n", file1); + Bprint(&stdout, "+++ %s\n", file2); +} + +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-Lines; + b = changes[j-1].b+Lines; + c = changes[i].c-Lines; + d = changes[j-1].d+Lines; + if(a < 1) + a = 1; + if(c < 1) + c = 1; + if(b > len[0]) + b = len[0]; + if(d > len[1]) + d = len[1]; + if(mode == 'a'){ + a = 1; + b = len[0]; + c = 1; + d = len[1]; + j = nchanges; + } + if(mode == 'u'){ + Bprint(&stdout, "@@ -%d,%d +%d,%d @@\n", a, b-a+1, c, d-c+1); + }else{ + Bprint(&stdout, "%s:", file1); + range(a, b, ","); + Bprint(&stdout, " - "); + Bprint(&stdout, "%s:", file2); + range(c, d, ","); + Bputc(&stdout, '\n'); + } + at = a; + for(; i<j; i++){ + fetch(ixold, at, changes[i].a-1, input[0], mode == 'u' ? " " : " "); + fetch(ixold, changes[i].a, changes[i].b, input[0], mode == 'u' ? "-" : "- "); + fetch(ixnew, changes[i].c, changes[i].d, input[1], mode == 'u' ? "+" : "+ "); + at = changes[i].b+1; + } + fetch(ixold, at, b, input[0], mode == 'u' ? " " : " "); + } + nchanges = 0; +} diff --git a/patch/diff-c-plus/diffio.c.orig b/patch/diff-c-plus/diffio.c.orig new file mode 100644 index 0000000..d937b1f --- /dev/null +++ b/patch/diff-c-plus/diffio.c.orig @@ -0,0 +1,401 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include <ctype.h> +#include "diff.h" + +struct line { + int serial; + int value; +}; +extern struct line *file[2]; +extern int len[2]; +extern long *ixold, *ixnew; +extern int *J; + +static Biobuf *input[2]; +static char *file1, *file2; +static int firstchange; + +#define MAXLINELEN 4096 +#define MIN(x, y) ((x) < (y) ? (x): (y)) + +static int +readline(Biobuf *bp, char *buf) +{ + int c; + char *p, *e; + + p = buf; + e = p + MAXLINELEN-1; + do { + c = Bgetc(bp); + if (c < 0) { + if (p == buf) + return -1; + break; + } + if (c == '\n') + break; + *p++ = c; + } while (p < e); + *p = 0; + if (c != '\n' && c >= 0) { + do c = Bgetc(bp); + while (c >= 0 && c != '\n'); + } + return p - buf; +} + +#define HALFLONG 16 +#define low(x) (x&((1L<<HALFLONG)-1)) +#define high(x) (x>>HALFLONG) + +/* + * hashing has the effect of + * arranging line in 7-bit bytes and then + * summing 1-s complement in 16-bit hunks + */ +static int +readhash(Biobuf *bp, char *buf) +{ + long sum; + unsigned shift; + char *p; + int len, space; + + sum = 1; + shift = 0; + if ((len = readline(bp, buf)) == -1) + return 0; + p = buf; + switch(bflag) /* various types of white space handling */ + { + case 0: + while (len--) { + sum += (long)*p++ << (shift &= (HALFLONG-1)); + shift += 7; + } + break; + case 1: + /* + * coalesce multiple white-space + */ + for (space = 0; len--; p++) { + if (isspace(*p)) { + space++; + continue; + } + if (space) { + shift += 7; + space = 0; + } + sum += (long)*p << (shift &= (HALFLONG-1)); + shift += 7; + } + break; + default: + /* + * strip all white-space + */ + while (len--) { + if (isspace(*p)) { + p++; + continue; + } + sum += (long)*p++ << (shift &= (HALFLONG-1)); + shift += 7; + } + break; + } + sum = low(sum) + high(sum); + return ((short)low(sum) + (short)high(sum)); +} + +Biobuf * +prepare(int i, char *arg) +{ + struct line *p; + int j, h; + Biobuf *bp; + char *cp, buf[MAXLINELEN]; + int nbytes; + Rune r; + + bp = Bopen(arg, OREAD); + if (!bp) { + panic(mflag ? 0: 2, "cannot open %s: %r\n", arg); + return 0; + } + if (binary) + return bp; + nbytes = Bread(bp, buf, MIN(1024, MAXLINELEN)); + if (nbytes > 0) { + cp = buf; + while (cp < buf+nbytes-UTFmax) { + /* + * heuristic for a binary file in the + * brave new UNICODE world + */ + cp += chartorune(&r, cp); + if (r == 0 || (r > 0x7f && r <= 0xa0)) { + binary++; + return bp; + } + } + Bseek(bp, 0, 0); + } + p = MALLOC(struct line, 3); + for (j = 0; h = readhash(bp, buf); p[j].value = h) + p = REALLOC(p, struct line, (++j+3)); + len[i] = j; + file[i] = p; + input[i] = bp; /*fix*/ + if (i == 0) { /*fix*/ + file1 = arg; + firstchange = 0; + } + else + file2 = arg; + return bp; +} + +static int +squishspace(char *buf) +{ + char *p, *q; + int space; + + for (space = 0, q = p = buf; *q; q++) { + if (isspace(*q)) { + space++; + continue; + } + if (space && bflag == 1) { + *p++ = ' '; + space = 0; + } + *p++ = *q; + } + *p = 0; + return p - buf; +} + +/* + * need to fix up for unexpected EOF's + */ +void +check(Biobuf *bf, Biobuf *bt) +{ + int f, t, flen, tlen; + char fbuf[MAXLINELEN], tbuf[MAXLINELEN]; + + ixold[0] = ixnew[0] = 0; + for (f = t = 1; f < len[0]; f++) { + flen = readline(bf, fbuf); + ixold[f] = ixold[f-1] + flen + 1; /* ftell(bf) */ + if (J[f] == 0) + continue; + do { + tlen = readline(bt, tbuf); + ixnew[t] = ixnew[t-1] + tlen + 1; /* ftell(bt) */ + } while (t++ < J[f]); + if (bflag) { + flen = squishspace(fbuf); + tlen = squishspace(tbuf); + } + if (flen != tlen || strcmp(fbuf, tbuf)) + J[f] = 0; + } + while (t < len[1]) { + tlen = readline(bt, tbuf); + ixnew[t] = ixnew[t-1] + tlen + 1; /* fseek(bt) */ + t++; + } +} + +static void +range(int a, int b, char *separator) +{ + Bprint(&stdout, "%d", a > b ? b: a); + if (a < b) + Bprint(&stdout, "%s%d", separator, b); +} + +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); + Bprint(&stdout, "%s%s\n", s, buf); + } +} + +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; + anychange = 1; + if (mflag && firstchange == 0) { + if(mode) { + buf[0] = '-'; + buf[1] = mode; + buf[2] = ' '; + buf[3] = '\0'; + } else { + buf[0] = '\0'; + } + Bprint(&stdout, "diff %s%s %s\n", buf, file1, file2); + firstchange = 1; + } + verb = a > b ? 'a': c > d ? 'd': 'c'; + switch(mode) { + case 'e': + range(a, b, ","); + Bputc(&stdout, verb); + break; + case 0: + range(a, b, ","); + Bputc(&stdout, verb); + range(c, d, ","); + break; + case 'n': + Bprint(&stdout, "%s:", file1); + range(a, b, ","); + Bprint(&stdout, " %c ", verb); + Bprint(&stdout, "%s:", file2); + range(c, d, ","); + break; + case 'f': + Bputc(&stdout, verb); + range(a, b, " "); + break; + case 'c': + case 'a': + case 'u': + 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') { + fetch(ixold, a, b, input[0], "< "); + if (a <= b && c <= d) + Bprint(&stdout, "---\n"); + } + fetch(ixnew, c, d, input[1], mode == 0 || mode == 'n' ? "> ": ""); + if (mode != 0 && mode != 'n' && c <= 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 +fileheader(void) +{ + if(mode != 'u') + return; + Bprint(&stdout, "--- %s\n", file1); + Bprint(&stdout, "+++ %s\n", file2); +} + +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-Lines; + b = changes[j-1].b+Lines; + c = changes[i].c-Lines; + d = changes[j-1].d+Lines; + if(a < 1) + a = 1; + if(c < 1) + c = 1; + if(b > len[0]) + b = len[0]; + if(d > len[1]) + d = len[1]; + if(mode == 'a'){ + a = 1; + b = len[0]; + c = 1; + d = len[1]; + j = nchanges; + } + if(mode == 'u'){ + Bprint(&stdout, "@@ -%d,%d +%d,%d @@\n", a, b-a+1, c, d-c+1); + }else{ + Bprint(&stdout, "%s:", file1); + range(a, b, ","); + Bprint(&stdout, " - "); + Bprint(&stdout, "%s:", file2); + range(c, d, ","); + Bputc(&stdout, '\n'); + } + at = a; + for(; i<j; i++){ + fetch(ixold, at, changes[i].a-1, input[0], mode == 'u' ? " " : " "); + fetch(ixold, changes[i].a, changes[i].b, input[0], mode == 'u' ? "-" : "- "); + fetch(ixnew, changes[i].c, changes[i].d, input[1], mode == 'u' ? "+" : "- "); + at = changes[i].b+1; + } + fetch(ixold, at, b, input[0], mode == 'u' ? " " : " "); + } + nchanges = 0; +} diff --git a/patch/diff-c-plus/email b/patch/diff-c-plus/email new file mode 100644 index 0000000..191feb6 --- /dev/null +++ b/patch/diff-c-plus/email @@ -0,0 +1 @@ +john@ankarstrom.se diff --git a/patch/diff-c-plus/files b/patch/diff-c-plus/files new file mode 100644 index 0000000..0b7672d --- /dev/null +++ b/patch/diff-c-plus/files @@ -0,0 +1 @@ +/sys/src/cmd/diff/diffio.c diffio.c diff --git a/patch/diff-c-plus/notes b/patch/diff-c-plus/notes new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/patch/diff-c-plus/notes diff --git a/patch/diff-c-plus/readme b/patch/diff-c-plus/readme new file mode 100644 index 0000000..2fdc300 --- /dev/null +++ b/patch/diff-c-plus/readme @@ -0,0 +1,6 @@ +Use + (plus) prefix for added lines with -c + +This fixes the bug where all lines, both added and removed, +use a - (minus) prefix when diff is run with the -c option. + +The bug is specific to 9front. It was fixed on 16 Nov 2020. |