xref: /minix3/minix/commands/fix/fix.c (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
1*433d6423SLionel Sambuc /* fix file difflist - update file from difflist     Author: Erik Baalbergen */
2*433d6423SLionel Sambuc /* Change all K&R-style functions declarations to ANSI-style
3*433d6423SLionel Sambuc declarations - Author: Alexandre Beletti (rhiguita@gmail.com) */
4*433d6423SLionel Sambuc 
5*433d6423SLionel Sambuc /* Notes: files old and old.patch are equal after the following commands
6*433d6423SLionel Sambuc      diff old new > difflist
7*433d6423SLionel Sambuc      patch old difflist > old.patch
8*433d6423SLionel Sambuc    * the diff output is assumed to be produced by my diff program.
9*433d6423SLionel Sambuc    * the difflist has the following form:
10*433d6423SLionel Sambuc      difflist ::= chunk*
11*433d6423SLionel Sambuc      chunk ::= append | delete | change ;
12*433d6423SLionel Sambuc      append ::= n1 'a' n2 [',' n3]? '\n' ['> ' line '\n'](n3 - n2 + 1)
13*433d6423SLionel Sambuc      delete ::= n1 [',' n2]? 'd' n3 '\n' ['< ' line '\n'](n2 - n1 + 1)
14*433d6423SLionel Sambuc      change ::= n1 [',' n2]? 'c' n3 [',' n4]? '\n'
15*433d6423SLionel Sambuc 	      ['< ' line '\n'](n2 - n1 + 1)
16*433d6423SLionel Sambuc 	      '---\n'
17*433d6423SLionel Sambuc 	      ['> ' line '\n'](n4 - n3 + 1)
18*433d6423SLionel Sambuc      where
19*433d6423SLionel Sambuc      - n[1234] is an unsigned integer
20*433d6423SLionel Sambuc      - "[pat](expr)" means "(expr) occurences of pat"
21*433d6423SLionel Sambuc      - "[pat]?" means "either pat or nothing"
22*433d6423SLionel Sambuc    * the information in the diff listing is checked against the file to which
23*433d6423SLionel Sambuc      it is applied; an error is printed if there is a conflict
24*433d6423SLionel Sambuc */
25*433d6423SLionel Sambuc 
26*433d6423SLionel Sambuc #include <ctype.h>
27*433d6423SLionel Sambuc #include <stdarg.h>
28*433d6423SLionel Sambuc #include <stdlib.h>
29*433d6423SLionel Sambuc #include <string.h>
30*433d6423SLionel Sambuc #include <stdio.h>
31*433d6423SLionel Sambuc 
32*433d6423SLionel Sambuc #define IGNORE_WHITE_SPACE	/* This makes it white space insensitive */
33*433d6423SLionel Sambuc 
34*433d6423SLionel Sambuc #ifdef IGNORE_WHITE_SPACE
35*433d6423SLionel Sambuc #define strcmp strwcmp
36*433d6423SLionel Sambuc #endif
37*433d6423SLionel Sambuc 
38*433d6423SLionel Sambuc #define LINELEN	1024
39*433d6423SLionel Sambuc 
40*433d6423SLionel Sambuc char *prog = 0, *processing = 0;
41*433d6423SLionel Sambuc 
42*433d6423SLionel Sambuc /* getline() already declared in stdio.h */
43*433d6423SLionel Sambuc #define getline fix_getline
44*433d6423SLionel Sambuc char *getline(FILE *fp, char *b);
45*433d6423SLionel Sambuc char *range(char *s, int *p1, int *p2);
46*433d6423SLionel Sambuc int getcommand(FILE *fp, int *o1, int *o2, char *pcmd, int *n1, int
47*433d6423SLionel Sambuc 	*n2);
48*433d6423SLionel Sambuc void fatal(const char *s, ...);
49*433d6423SLionel Sambuc int strwcmp(char *s1, char *s2);
50*433d6423SLionel Sambuc int whitespace(char ch);
51*433d6423SLionel Sambuc 
52*433d6423SLionel Sambuc char *
getline(FILE * fp,char * b)53*433d6423SLionel Sambuc getline(FILE *fp, char *b)
54*433d6423SLionel Sambuc {
55*433d6423SLionel Sambuc   if (fgets(b, LINELEN, fp) == NULL) fatal("unexpected eof");
56*433d6423SLionel Sambuc 
57*433d6423SLionel Sambuc   return b;
58*433d6423SLionel Sambuc }
59*433d6423SLionel Sambuc 
60*433d6423SLionel Sambuc #define copy(str) printf("%s", str)
61*433d6423SLionel Sambuc 
main(int argc,char ** argv)62*433d6423SLionel Sambuc int main(int argc, char **argv)
63*433d6423SLionel Sambuc {
64*433d6423SLionel Sambuc   char cmd, *fl, *fd, obuf[LINELEN], nbuf[LINELEN];
65*433d6423SLionel Sambuc   int o1, o2, n1, n2, here;
66*433d6423SLionel Sambuc   FILE *fpf, *fpd;
67*433d6423SLionel Sambuc 
68*433d6423SLionel Sambuc   prog = argv[0];
69*433d6423SLionel Sambuc   processing = argv[1];
70*433d6423SLionel Sambuc   if (argc != 3) fatal("use: %s original-file diff-list-file", prog);
71*433d6423SLionel Sambuc   if ((fpf = fopen(argv[1], "r")) == NULL) fatal("can't read %s", argv[1]);
72*433d6423SLionel Sambuc   if ((fpd = fopen(argv[2], "r")) == NULL) fatal("can't read %s", argv[2]);
73*433d6423SLionel Sambuc   here = 0;
74*433d6423SLionel Sambuc   while (getcommand(fpd, &o1, &o2, &cmd, &n1, &n2)) {
75*433d6423SLionel Sambuc 	while (here < o1 - 1) {
76*433d6423SLionel Sambuc 		here++;
77*433d6423SLionel Sambuc 		copy(getline(fpf, obuf));
78*433d6423SLionel Sambuc 	}
79*433d6423SLionel Sambuc 	switch (cmd) {
80*433d6423SLionel Sambuc 	    case 'c':
81*433d6423SLionel Sambuc 	    case 'd':
82*433d6423SLionel Sambuc 		if (cmd == 'd' && n1 != n2) fatal("delete count conflict");
83*433d6423SLionel Sambuc 		while (o1 <= o2) {
84*433d6423SLionel Sambuc 			fl = getline(fpf, obuf);
85*433d6423SLionel Sambuc 			here++;
86*433d6423SLionel Sambuc 			fd = getline(fpd, nbuf);
87*433d6423SLionel Sambuc 			if (strncmp(fd, "<", (size_t)1))
88*433d6423SLionel Sambuc 				fatal("illegal delete line");
89*433d6423SLionel Sambuc 			if (strcmp(fl, fd + 2))
90*433d6423SLionel Sambuc 				fatal("delete line conflict");
91*433d6423SLionel Sambuc 			o1++;
92*433d6423SLionel Sambuc 		}
93*433d6423SLionel Sambuc 		if (cmd == 'd') break;
94*433d6423SLionel Sambuc 		if (strcmp(getline(fpd, nbuf), "---\n"))
95*433d6423SLionel Sambuc 			fatal("illegal separator in chunk");
96*433d6423SLionel Sambuc 		/* FALLTHROUGH */
97*433d6423SLionel Sambuc 	    case 'a':
98*433d6423SLionel Sambuc 		if (cmd == 'a') {
99*433d6423SLionel Sambuc 			if (o1 != o2) fatal("append count conflict");
100*433d6423SLionel Sambuc 			copy(getline(fpf, obuf));
101*433d6423SLionel Sambuc 			here++;
102*433d6423SLionel Sambuc 		}
103*433d6423SLionel Sambuc 		while (n1 <= n2) {
104*433d6423SLionel Sambuc 			if (strncmp(getline(fpd, nbuf), ">", (size_t)1))
105*433d6423SLionel Sambuc 				fatal("illegal append line");
106*433d6423SLionel Sambuc 			copy(nbuf + 2);
107*433d6423SLionel Sambuc 			n1++;
108*433d6423SLionel Sambuc 		}
109*433d6423SLionel Sambuc 		break;
110*433d6423SLionel Sambuc 	}
111*433d6423SLionel Sambuc   }
112*433d6423SLionel Sambuc   while (fgets(obuf, LINELEN, fpf) != NULL) copy(obuf);
113*433d6423SLionel Sambuc   return(0);
114*433d6423SLionel Sambuc }
115*433d6423SLionel Sambuc 
116*433d6423SLionel Sambuc char *
range(char * s,int * p1,int * p2)117*433d6423SLionel Sambuc  range(char *s, int *p1, int *p2)
118*433d6423SLionel Sambuc {
119*433d6423SLionel Sambuc   register int v1 = 0, v2;
120*433d6423SLionel Sambuc 
121*433d6423SLionel Sambuc   while (isdigit(*s)) v1 = 10 * v1 + *s++ - '0';
122*433d6423SLionel Sambuc   v2 = v1;
123*433d6423SLionel Sambuc   if (*s == ',') {
124*433d6423SLionel Sambuc 	s++;
125*433d6423SLionel Sambuc 	v2 = 0;
126*433d6423SLionel Sambuc 	while (isdigit(*s)) v2 = 10 * v2 + *s++ - '0';
127*433d6423SLionel Sambuc   }
128*433d6423SLionel Sambuc   if (v1 > v2) fatal("illegal range");
129*433d6423SLionel Sambuc   *p1 = v1;
130*433d6423SLionel Sambuc   *p2 = v2;
131*433d6423SLionel Sambuc   return s;
132*433d6423SLionel Sambuc }
133*433d6423SLionel Sambuc 
getcommand(FILE * fp,int * o1,int * o2,char * pcmd,int * n1,int * n2)134*433d6423SLionel Sambuc int getcommand(FILE *fp, int *o1, int *o2, char *pcmd, int *n1, int *n2)
135*433d6423SLionel Sambuc {
136*433d6423SLionel Sambuc   char buf[LINELEN];
137*433d6423SLionel Sambuc   register char *s;
138*433d6423SLionel Sambuc   char cmd;
139*433d6423SLionel Sambuc 
140*433d6423SLionel Sambuc   if ((s = fgets(buf, LINELEN, fp)) == NULL) return 0;
141*433d6423SLionel Sambuc   s = range(s, o1, o2);
142*433d6423SLionel Sambuc   if ((cmd = *s++) != 'a' && cmd != 'c' && cmd != 'd')
143*433d6423SLionel Sambuc 	fatal("illegal command");
144*433d6423SLionel Sambuc   s = range(s, n1, n2);
145*433d6423SLionel Sambuc   if (*s != '\n' && s[1] != '\0')
146*433d6423SLionel Sambuc 	fatal("extra characters at end of command: %s", s);
147*433d6423SLionel Sambuc   *pcmd = cmd;
148*433d6423SLionel Sambuc   return 1;
149*433d6423SLionel Sambuc }
150*433d6423SLionel Sambuc 
151*433d6423SLionel Sambuc #ifdef __STDC__
fatal(const char * s,...)152*433d6423SLionel Sambuc void fatal(const char *s, ...)
153*433d6423SLionel Sambuc {
154*433d6423SLionel Sambuc   va_list args;
155*433d6423SLionel Sambuc 
156*433d6423SLionel Sambuc   va_start (args, s);
157*433d6423SLionel Sambuc   fprintf(stderr, "%s: processing: %s fatal: ", prog, processing);
158*433d6423SLionel Sambuc   vfprintf(stderr, s, args);
159*433d6423SLionel Sambuc   fprintf(stderr, "\n");
160*433d6423SLionel Sambuc   va_end(args);
161*433d6423SLionel Sambuc   exit(1);
162*433d6423SLionel Sambuc }
163*433d6423SLionel Sambuc #else
164*433d6423SLionel Sambuc /* the K&R lib does not have vfprintf */
fatal(const char * s,const char * a)165*433d6423SLionel Sambuc void fatal(const char *s, const char *a)
166*433d6423SLionel Sambuc {
167*433d6423SLionel Sambuc   fprintf(stderr, "%s: processing: %s fatal: ", prog, processing);
168*433d6423SLionel Sambuc   fprintf(stderr, s, a);
169*433d6423SLionel Sambuc   fprintf(stderr, "\n");
170*433d6423SLionel Sambuc   exit(1);
171*433d6423SLionel Sambuc }
172*433d6423SLionel Sambuc #endif
173*433d6423SLionel Sambuc 
174*433d6423SLionel Sambuc #ifdef IGNORE_WHITE_SPACE
175*433d6423SLionel Sambuc 
176*433d6423SLionel Sambuc /* This routine is a white space insensitive version of strcmp.
177*433d6423SLionel Sambuc    It is needed for testing things which might have undergone
178*433d6423SLionel Sambuc    tab conversion or trailing space removal
179*433d6423SLionel Sambuc    Bret Mckee June, 1988 */
180*433d6423SLionel Sambuc 
strwcmp(char * s1,char * s2)181*433d6423SLionel Sambuc int strwcmp(char *s1, char *s2)
182*433d6423SLionel Sambuc {
183*433d6423SLionel Sambuc   char *x1 = s1, *x2 = s2;
184*433d6423SLionel Sambuc 
185*433d6423SLionel Sambuc   /* Remove leading white space */
186*433d6423SLionel Sambuc   while (whitespace(*s1)) s1++;
187*433d6423SLionel Sambuc   while (whitespace(*s2)) s2++;
188*433d6423SLionel Sambuc   do {
189*433d6423SLionel Sambuc 	while ((*s1 == *s2) && *s1 && *s2) {
190*433d6423SLionel Sambuc 		s1++;
191*433d6423SLionel Sambuc 		s2++;
192*433d6423SLionel Sambuc 	}
193*433d6423SLionel Sambuc 	;			/* consume identical characters */
194*433d6423SLionel Sambuc 	while (whitespace(*s1)) s1++;
195*433d6423SLionel Sambuc 	while (whitespace(*s2)) s2++;
196*433d6423SLionel Sambuc   } while (*s1 && *s2 && (*s1 == *s2));
197*433d6423SLionel Sambuc   if (*s1 - *s2)
198*433d6423SLionel Sambuc 	fprintf(stderr, "Failing for (%x)[%s]\n            (%x)[%s]\n",
199*433d6423SLionel Sambuc 		(int) *s1, x1, (int) *s2, x2);
200*433d6423SLionel Sambuc   return(*s1 - *s2);
201*433d6423SLionel Sambuc }
202*433d6423SLionel Sambuc 
whitespace(char ch)203*433d6423SLionel Sambuc int whitespace(char ch)
204*433d6423SLionel Sambuc {
205*433d6423SLionel Sambuc   switch (ch) {
206*433d6423SLionel Sambuc       case ' ':
207*433d6423SLionel Sambuc       case '\n':
208*433d6423SLionel Sambuc       case 0x0D:
209*433d6423SLionel Sambuc       case '\t':
210*433d6423SLionel Sambuc 	return(1);
211*433d6423SLionel Sambuc       default:	return(0);
212*433d6423SLionel Sambuc }
213*433d6423SLionel Sambuc }
214*433d6423SLionel Sambuc 
215*433d6423SLionel Sambuc #endif
216