shithub: riscv

Download patch

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)