00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <ctype.h>
00026 #include <stdarg.h>
00027 #include <stdlib.h>
00028 #include <string.h>
00029 #include <stdio.h>
00030
00031 #define IGNORE_WHITE_SPACE
00032
00033 #ifdef IGNORE_WHITE_SPACE
00034 #define strcmp strwcmp
00035 #endif
00036
00037 #define LINELEN 1024
00038
00039 char *prog = 0, *processing = 0;
00040
00041 _PROTOTYPE(int main, (int argc, char **argv));
00042 _PROTOTYPE(char *getline, (FILE *fp, char *b));
00043 _PROTOTYPE(char *range, (char *s, int *p1, int *p2));
00044 _PROTOTYPE(int getcommand, (FILE *fp, int *o1, int *o2, char *pcmd, int *n1, int *n2));
00045 _PROTOTYPE(void fatal, (char *s, ...));
00046 _PROTOTYPE(int strwcmp, (char *s1, char *s2));
00047 _PROTOTYPE(int whitespace, (int ch));
00048
00049 char *
00050 getline(fp, b)
00051 FILE *fp;
00052 char *b;
00053 {
00054 if (fgets(b, LINELEN, fp) == NULL) fatal("unexpected eof");
00055
00056 return b;
00057 }
00058
00059 #define copy(str) printf("%s", str)
00060
00061 int main(argc, argv)
00062 int argc;
00063 char **argv;
00064 {
00065 char cmd, *fl, *fd, obuf[LINELEN], nbuf[LINELEN];
00066 int o1, o2, n1, n2, here;
00067 FILE *fpf, *fpd;
00068
00069 prog = argv[0];
00070 processing = argv[1];
00071 if (argc != 3) fatal("use: %s original-file diff-list-file", prog);
00072 if ((fpf = fopen(argv[1], "r")) == NULL) fatal("can't read %s", argv[1]);
00073 if ((fpd = fopen(argv[2], "r")) == NULL) fatal("can't read %s", argv[2]);
00074 here = 0;
00075 while (getcommand(fpd, &o1, &o2, &cmd, &n1, &n2)) {
00076 while (here < o1 - 1) {
00077 here++;
00078 copy(getline(fpf, obuf));
00079 }
00080 switch (cmd) {
00081 case 'c':
00082 case 'd':
00083 if (cmd == 'd' && n1 != n2) fatal("delete count conflict");
00084 while (o1 <= o2) {
00085 fl = getline(fpf, obuf);
00086 here++;
00087 fd = getline(fpd, nbuf);
00088 if (strncmp(fd, "<", (size_t)1))
00089 fatal("illegal delete line");
00090 if (strcmp(fl, fd + 2))
00091 fatal("delete line conflict");
00092 o1++;
00093 }
00094 if (cmd == 'd') break;
00095 if (strcmp(getline(fpd, nbuf), "---\n"))
00096 fatal("illegal separator in chunk");
00097
00098 case 'a':
00099 if (cmd == 'a') {
00100 if (o1 != o2) fatal("append count conflict");
00101 copy(getline(fpf, obuf));
00102 here++;
00103 }
00104 while (n1 <= n2) {
00105 if (strncmp(getline(fpd, nbuf), ">", (size_t)1))
00106 fatal("illegal append line");
00107 copy(nbuf + 2);
00108 n1++;
00109 }
00110 break;
00111 }
00112 }
00113 while (fgets(obuf, LINELEN, fpf) != NULL) copy(obuf);
00114 return(0);
00115 }
00116
00117 char *
00118 range(s, p1, p2)
00119 char *s;
00120 int *p1, *p2;
00121 {
00122 register int v1 = 0, v2;
00123
00124 while (isdigit(*s)) v1 = 10 * v1 + *s++ - '0';
00125 v2 = v1;
00126 if (*s == ',') {
00127 s++;
00128 v2 = 0;
00129 while (isdigit(*s)) v2 = 10 * v2 + *s++ - '0';
00130 }
00131 if (v1 > v2) fatal("illegal range");
00132 *p1 = v1;
00133 *p2 = v2;
00134 return s;
00135 }
00136
00137 int getcommand(fp, o1, o2, pcmd, n1, n2)
00138 FILE *fp;
00139 int *o1, *o2, *n1, *n2;
00140 char *pcmd;
00141 {
00142 char buf[LINELEN];
00143 register char *s;
00144 char cmd;
00145
00146 if ((s = fgets(buf, LINELEN, fp)) == NULL) return 0;
00147 s = range(s, o1, o2);
00148 if ((cmd = *s++) != 'a' && cmd != 'c' && cmd != 'd')
00149 fatal("illegal command");
00150 s = range(s, n1, n2);
00151 if (*s != '\n' && s[1] != '\0')
00152 fatal("extra characters at end of command: %s", s);
00153 *pcmd = cmd;
00154 return 1;
00155 }
00156
00157 #ifdef __STDC__
00158 void fatal(char *s, ...)
00159 {
00160 va_list args;
00161
00162 va_start (args, s);
00163 fprintf(stderr, "%s: processing: %s fatal: ", prog, processing);
00164 vfprintf(stderr, s, args);
00165 fprintf(stderr, "\n");
00166 va_end(args);
00167 exit(1);
00168 }
00169 #else
00170
00171 void fatal(s, a)
00172 char *s, *a;
00173 {
00174 fprintf(stderr, "%s: processing: %s fatal: ", prog, processing);
00175 fprintf(stderr, s, a);
00176 fprintf(stderr, "\n");
00177 exit(1);
00178 }
00179 #endif
00180
00181 #ifdef IGNORE_WHITE_SPACE
00182
00183
00184
00185
00186
00187
00188 int strwcmp(s1, s2)
00189 char *s1, *s2;
00190 {
00191 char *x1 = s1, *x2 = s2;
00192
00193
00194 while (whitespace(*s1)) s1++;
00195 while (whitespace(*s2)) s2++;
00196 do {
00197 while ((*s1 == *s2) && *s1 && *s2) {
00198 s1++;
00199 s2++;
00200 }
00201 ;
00202 while (whitespace(*s1)) s1++;
00203 while (whitespace(*s2)) s2++;
00204 } while (*s1 && *s2 && (*s1 == *s2));
00205 if (*s1 - *s2)
00206 fprintf(stderr, "Failing for (%x)[%s]\n (%x)[%s]\n",
00207 (int) *s1, x1, (int) *s2, x2);
00208 return(*s1 - *s2);
00209 }
00210
00211 int whitespace(ch)
00212 char ch;
00213 {
00214 switch (ch) {
00215 case ' ':
00216 case '\n':
00217 case 0x0D:
00218 case '\t':
00219 return(1);
00220 default: return(0);
00221 }
00222 }
00223
00224 #endif