[comp.os.minix] source to fix

martin@iris.ucdavis.edu (Bruce K. Martin Jr.) (09/03/87)

I am in need of the source to fix (merges diff files into source).  I was
unable to find it on bugs.nosc.mil or on louie.udel.edu.  Is there
another minix archive or did I just miss it?

Alternatively, could someone mail it to me?

Thanks!
			...bruce

Bruce K. Martin   UC. Davis Div. of Computer Science
martin@iris.ucdavis.edu  --or--  {ucbvax | lll-crg}!ucdavis!iris!martin

ast@cs.vu.nl (Andy Tanenbaum) (09/04/87)

In article <744@ucdavis.UUCP> martin@iris.ucdavis.edu (Bruce K. Martin Jr.) writes:
>
>I am in need of the source to fix.

I am constantly getting a stream of mail asking for fix, probably mostly
from people who have just joined the group, so I will just post it again.
Here it is.
Andy Tanenbaum (ast@cs.vu.nl)
------------------------------- fix.c --------------------------
/* fix - combine file and diff listing	Author: Erik Baalbergen */

/* Notes:
   * files old and old.fix are equal after the following commands
	   diff old new > difflist
	   fix old difflist > old.fix
   * the diff output is assumed to be produced by my diff program.
   * the difflist has the following form:
	   difflist ::= chunk*
	   chunk ::= append | delete | change ;
	   append ::= n1 'a' n2 [',' n3]? '\n' ['> ' line '\n'](n3 - n2 + 1)
	   delete ::= n1 [',' n2]? 'd' n3 '\n' ['< ' line '\n'](n2 - n1 + 1)
	   change ::= n1 [',' n2]? 'c' n3 [',' n4]? '\n'
		      ['< ' line '\n'](n2 - n1 + 1)
		      '---\n'
		      ['> ' line '\n'](n4 - n3 + 1)
	   where
	   - n[1234] is an unsigned integer
	   - "[pat](expr)" means "(expr) occurences of pat"
	   - "[pat]?" means "either pat or nothing"
   * the information in the diff listing is checked against the file to which
     it is applied; an error is printed if there is a conflict
*/

#include <stdio.h>

extern char *fgets();
extern FILE *fopen();
#define LINELEN	1024

char *prog = 0;

char *
getline(fp, b)
	FILE *fp;
	char *b;
{
	if (fgets(b, LINELEN, fp) == NULL)
		fatal("unexpected eof");
	return b;
}

#define copy(str) printf("%s", str)

main(argc, argv)
	char **argv;
{
	char cmd, *fl, *fd, obuf[LINELEN], nbuf[LINELEN];
	int o1, o2, n1, n2, here; 
	FILE *fpf, *fpd;

	prog = argv[0];
	if (argc != 3)
		fatal("use: %s original-file diff-list-file", prog);
	if ((fpf = fopen(argv[1], "r")) == NULL)
		fatal("can't read %s", argv[1]);
	if ((fpd = fopen(argv[2], "r")) == NULL)
		fatal("can't read %s", argv[2]);
	here = 0;
	while (getcommand(fpd, &o1, &o2, &cmd, &n1, &n2)) {
		while (here < o1 - 1) {
			here++;
			copy(getline(fpf, obuf));
		}
		switch (cmd) {
		case 'c':
		case 'd':
			if (cmd == 'd' && n1 != n2)
				fatal("delete count conflict");
			while (o1 <= o2) {
				fl = getline(fpf, obuf);
				here++;
				fd = getline(fpd, nbuf);
				if (strncmp(fd, "< ", 2))
					fatal("illegal delete line");
				if (strcmp(fl, fd + 2))
					fatal("delete line conflict");
				o1++;
			}
			if (cmd == 'd')
				break;
			if (strcmp(getline(fpd, nbuf), "---\n"))
				fatal("illegal separator in chunk");
			/*FALLTHROUGH*/
		case 'a':
			if (cmd == 'a') {
				if (o1 != o2)
					fatal("append count conflict");
				copy(getline(fpf, obuf));
				here++;
			}
			while (n1 <= n2) {
				if (strncmp(getline(fpd, nbuf), "> ", 2))
					fatal("illegal append line");
				copy(nbuf + 2);
				n1++;
			}
			break;
		}
	}
	while (fgets(obuf, LINELEN, fpf) != NULL)
		copy(obuf);
	exit(0);
}

isdigit(c)
	char c;
{
	return c >= '0' && c <= '9';
}

char *
range(s, p1, p2)
	char *s;
	int *p1, *p2;
{
	register int v1 = 0, v2;

	while (isdigit(*s))
		v1 = 10 * v1 + *s++ - '0';
	v2 = v1;
	if (*s == ',') {
		s++;
		v2 = 0;
		while (isdigit(*s))
			v2 = 10 * v2 + *s++ - '0';
	}
	if (v1 == 0 || v2 == 0 || v1 > v2)
		fatal("illegal range");
	*p1 = v1;
	*p2 = v2;
	return s;
}

getcommand(fp, o1, o2, pcmd, n1, n2)
	FILE *fp;
	int *o1, *o2, *n1, *n2;
	char *pcmd;
{
	char buf[LINELEN];
	register char *s;
	char cmd;
	
	if ((s = fgets(buf, LINELEN, fp)) == NULL)
		return 0;
	s = range(s, o1, o2);
	if ((cmd = *s++) != 'a' && cmd != 'c' && cmd != 'd')
		fatal("illegal command");
	s = range(s, n1, n2);
	if (*s != '\n' && s[1] != '\0')
		fatal("extra characters at end of command: %s", s);
	*pcmd = cmd;
	return 1;
}

fatal(s, a)
	char *s, *a;
{
	fprintf(stderr, "%s: fatal: ", prog);
	fprintf(stderr, s, a);
	fprintf(stderr, "\n");
	exit(1);
}