Шрифт:
4,6с4,5
Второе различие
< your
< skill
< and comprehension.
– --
> our
> ability.
? <
Пользователь выбрал первую (<) версию
idiff output in file idiff.out
$ cat idiff.out
Выходной поток направляется в этот файл
This is
not a test of
your skill
and comprehension.
$
Если вместо
<
или >
выдан ответ е
, idiff
вызывает ed
с двумя группами уже прочитанных строк. Если вторым был ответ е
, буфер редактора выглядел бы следующим образом:
your
skill
and comprehension.
– --
our
ability.
Все, что пишется редактором обратно в файл, идет в окончательный выходной поток.
И, наконец, любая команда может быть выполнена внутри
idiff
с помощью временного выхода посредством !cmd. Технически самая трудная часть работы
diff
, и она уже выполнена. Таким образом, в задачи idiff
входит разбор выходного потока diff
, открытие, закрытие, чтение и считывание соответствующих файлов в нужное время. Главная функция idiff
поддерживает файлы и запускает процесс diff
:
/* 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 file2\n");
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.out\n", progname);
exit(0);
}
Функция
mktemp(3)
создает файл, имя которого гарантированно отличается от имени любого существующего файла. Mktemp
переписывает свой аргумент: шесть символов X
заменяются идентификатором процесса и буквой. Системный вызов unlink(2)
удаляет поименованный файл из файловой системы. Циклическая обработка изменений, о которых сообщает
diff
, выполняется функцией idiff
. Основная идея достаточно проста: печатать порцию выходного потока diff
, пропускать нежелательные данные в одном файле, а затем копировать требуемый вариант из другого файла. В программе есть много утомительных подробностей, так что она оказывается несколько больше, чем нам бы хотелось, но по частям ее довольно легко понять.
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, ftto1, &cmd, &from2, &to2);