ref: 26e4a18e7060b0300f57f6592e3440b5e0a4aea1
parent: 172dc0005aa16dea8451bf2bcef7f3eb04df2c04
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Sep 18 12:34:33 EDT 2023
patch: fix offsets in reverse mode we would not swap all of the fields in the forward and reverse modes for patch, which means that we may accidentally make a hunk unfindable if the line numbers matcch up correctly. This does the reverse in a less ad-hoc way, just swapping the forward and reverse hunks once in one place. It also swaps all of them.
--- a/sys/src/cmd/patch.c
+++ b/sys/src/cmd/patch.c
@@ -50,8 +50,6 @@
int strip;
int reverse;
-void (*addnew)(Hunk*, char*);
-void (*addold)(Hunk*, char*);
Fchg *changed;
int nchanged;
int dryrun;
@@ -158,9 +156,9 @@
return -1;
e++;
h->newln = strtol(e, &e, 10);
+ h->newcnt = 1;
if(e == s)
return -1;
- h->newcnt = 1;
if(*e == ','){
e++;
h->newcnt = strtol(e, &e, 10);
@@ -183,7 +181,7 @@
}
void
-addnewfn(Hunk *h, char *ln)
+addnew(Hunk *h, char *ln)
{
int n;
@@ -198,7 +196,7 @@
}
void
-addoldfn(Hunk *h, char *ln)
+addold(Hunk *h, char *ln)
{
int n;
@@ -247,24 +245,37 @@
return ((Hunk*)a)->oldln - ((Hunk*)b)->oldln;
}
+void
+swapint(int *a, int *b)
+{
+ int t;
+
+ t = *a;
+ *a = *b;
+ *b = t;
+}
+
+void
+swapstr(char **a, char **b)
+{
+ char *t;
+
+ t = *a;
+ *a = *b;
+ *b = t;
+}
+
Patch*
parse(Biobuf *f, char *name)
{
- char *ln, *old, *new, **oldp, **newp;
- int oldcnt, newcnt, lnum;
+ char *ln, *old, *new;
+ int i, oldcnt, newcnt, lnum;
Patch *p;
- Hunk h;
+ Hunk h, *ph;
ln = nil;
lnum = 0;
p = emalloc(sizeof(Patch));
- if(!reverse){
- oldp = &old;
- newp = &new;
- }else{
- oldp = &new;
- newp = &old;
- }
comment:
free(ln);
while((ln = readline(f, &lnum)) != nil){
@@ -277,13 +288,13 @@
goto out;
patch:
- if(fileheader(ln, "--- ", oldp) == -1)
+ if(fileheader(ln, "--- ", &old) == -1)
goto comment;
free(ln);
if((ln = readline(f, &lnum)) == nil)
goto out;
- if(fileheader(ln, "+++ ", newp) == -1)
+ if(fileheader(ln, "+++ ", &new) == -1)
goto comment;
free(ln);
@@ -298,8 +309,10 @@
while(1){
if((ln = readline(f, &lnum)) == nil){
- if(oldcnt != h.oldcnt || newcnt != h.newcnt)
- sysfatal("%s:%d: malformed hunk: mismatched counts", name, lnum);
+ if(oldcnt != h.oldcnt)
+ sysfatal("%s:%d: malformed hunk: mismatched -hunk size %d != %d", name, lnum, oldcnt, h.oldcnt);
+ if(newcnt != h.newcnt)
+ sysfatal("%s:%d: malformed hunk: mismatched +hunk size %d != %d", name, lnum, newcnt, h.newcnt);
addhunk(p, &h);
break;
}
@@ -345,6 +358,17 @@
}
out:
+ if(reverse){
+ for(i = 0; i < p->nhunk; i++){
+ ph = &p->hunk[i];
+ swapint(&ph->oldln, &ph->newln);
+ swapint(&ph->oldcnt, &ph->newcnt);
+ swapint(&ph->oldlen, &ph->newlen);
+ swapint(&ph->oldsz, &ph->newsz);
+ swapstr(&ph->oldpath, &ph->newpath);
+ swapstr(&ph->old, &ph->new);
+ }
+ }
qsort(p->hunk, p->nhunk, sizeof(Hunk), hunkcmp);
free(old);
free(new);
@@ -668,13 +692,6 @@
break;
}ARGEND;
- if(reverse){
- addnew = addoldfn;
- addold = addnewfn;
- }else{
- addnew = addnewfn;
- addold = addoldfn;
- }
ok = 1;
if(argc == 0){
if((f = Bfdopen(0, OREAD)) == nil)