Книга: UNIX — универсальная среда программирования

3.8.27 idiff.c

3.8.27 idiff.c
/* idiff: interactive diff */
#include <stdio.h>
#include <ctype.h>
char *progname;
#define HUGE 10000 /* large number of lines */
main(argc, argv)
 int argc;
 char *argv[];
{
 FILE *fin, *fout, *f1, *f2, *efopen();
 char buf[BUFSIZ], *mktemp();
 char *diffout = "idiff.XXXXXX";
 progname = argv[0];
 if (argc != 3) {
  fprintf(stderr, "Usage: idiff file1 file2n");
  exit(1);
 }
 f1 = efopen(argv[1], "r");
 f2 = efopen(argv[2], "r");
 fout = efopen("idiff.out", "w");
 mktemp(diffout);
 sprintf(buf, "diff %s %s >%s", argv[1], argv[2], diffout);
 system(buf);
 fin = efopen(diffout, "r");
 idiff(f1, f2, fin, fout); unlink(diffout);
 printf("%s output in file idiff.outn", progname);
 exit(0);
}
idiff(f1, f2, fin, fout) /* process diffs */
 FILE *f1, *f2, *fin, *fout;
{
 char *tempfile = "idiff.XXXXXX";
 char buf[BUFSIZ], buf2[BUFSIZ], *mktemp();
 FILE *ft, *efopen();
 int cmd, n, from1, to1, from2, to2, nf1, nf2;
 mktemp(tempfile);
 nf1 = nf2 = 0;
 while (fgets(buf, sizeof buf, fin) != NULL) {
  parse(buf, &from1, &to1, &cmd, &from2, &to2);
  n = to1-from1 + to2-from2 + 1; /* #lines from diff */
  if (cmd == 'c')
   n += 2;
  else if (cmd == 'a')
   from1++;
  else if (cmd == 'd')
   from2++;
  printf("%s", buf);
  while (n-- > 0) {
   fgets(buf, sizeof buf, fin);
   printf("%s", buf);
  }
  do {
   printf("? ");
   fflush(stdout);
   fgets(buf, sizeof buf, stdin);
   switch (buf[0]) {
   case '>':
    nskip(f1, to1-nf1);
    ncopy(f2, to2-nf2, fout);
    break;
   case '<':
    nskip(f2, to2-nf2);
    ncopy(f1, to1-nf1, fout);
    break;
   case 'e':
    ncopy(f1, from1-1-nf1, fout);
    nskip(f2, from2-1-nf2);
    ft = efopen(tempfile, "w");
    ncopy(f1, to1+1-from1, ft);
    fprintf(ft, "--- n");
    ncopy(f2, to2+1-from2, ft);
    fclose(ft);
    sprintf(buf2, "ed %s", tempfile);
    system(buf2);
    ft = efopen(tempfile, "r");
    ncopy(ft, HUGE, fout);
    fclose(ft);
    break;
   case '!':
    system(buf+1);
    printf("!n");
    break;
   default:
    printf("< or > or e or !n");
    break;
   }
  } while (buf[0]!= '<' && buf[0]!= '>' && buf[0]! = 'e');
  nf1 = to1;
  nf2 = to2;
 }
 ncopy(f1, HUGE, fout); /* can fail on very long files */
 unlink(tempfile);
}
parse(s, pfrom1, pto1, pcmd, pfrom2, pto2)
 char *s;
 int *pcmd, *pfrom1, *pto1, *pfrom2, *pto2;
{
#define a2i(p) while (isdigit(*s))
 p = 10*(p) + *s++ - '0'
 *pfrom1 = *pto1 = *pfrom2 = *pto2 = 0;
 a2i(*pfrom1);
 if (*s == ',') {
  s++;
  a2i(*pto1);
 } else
  *pto1 = *pfrom1;
 *pcmd = *s++;
 a2i(*pfrom2);
 if (*s == ',') {
  s++;
  a2i(*pto2);
 } else
  *pto2 = *pfrom2;
}
nskip(fin, n) /* skip n lines of file fin */
 FILE *fin;
{
 char buf[BUFSIZ];
 while (n-- > 0)
  fgets(buf, sizeof buf, fin);
}
ncopy(fin, n, fout) /* copy n lines from fin to fout */
 FILE *fin, *fout;
{
 char buf[BUFSIZ];
 while (n-- > 0) {
  if (fgets(buf, sizeof buf, fin) == NULL)
   return;
  fputs(buf, fout);
 }
}
#include "efopen.c"

Оглавление книги


Генерация: 1.400. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз