Changeset View
Changeset View
Standalone View
Standalone View
usr.bin/diff3/diff3.c
Show First 20 Lines • Show All 104 Lines • ▼ Show 20 Lines | |||||
}; | }; | ||||
static size_t szchanges; | static size_t szchanges; | ||||
static struct diff *d13; | static struct diff *d13; | ||||
static struct diff *d23; | static struct diff *d23; | ||||
/* | /* | ||||
* "de" is used to gather editing scripts. These are later spewed out in | * "de" is used to gather editing scripts. These are later spewed out in | ||||
* reverse order. Its first element must be all zero, the "new" component | * reverse order. Its first element must be all zero, the "old" and "new" | ||||
* of "de" contains line positions or byte positions depending on when you | * components of "de" contain line positions. Array overlap indicates which | ||||
* look (!?). Array overlap indicates which sections in "de" correspond to | * sections in "de" correspond to lines that are different in all three files. | ||||
* lines that are different in all three files. | |||||
*/ | */ | ||||
static struct diff *de; | static struct diff *de; | ||||
static char *overlap; | static char *overlap; | ||||
static int overlapcnt; | static int overlapcnt; | ||||
static FILE *fp[3]; | static FILE *fp[3]; | ||||
static int cline[3]; /* # of the last-read line in each file (0-2) */ | static int cline[3]; /* # of the last-read line in each file (0-2) */ | ||||
/* | /* | ||||
* The latest known correspondence between line numbers of the 3 files | * The latest known correspondence between line numbers of the 3 files | ||||
Show All 14 Lines | |||||
static void change(int, struct range *, bool); | static void change(int, struct range *, bool); | ||||
static void keep(int, struct range *); | static void keep(int, struct range *); | ||||
static void merge(int, int); | static void merge(int, int); | ||||
static void prange(struct range *, bool); | static void prange(struct range *, bool); | ||||
static void repos(int); | static void repos(int); | ||||
static void edscript(int) __dead2; | static void edscript(int) __dead2; | ||||
static void increase(void); | static void increase(void); | ||||
static void usage(void) __dead2; | static void usage(void) __dead2; | ||||
static void printrange(FILE *, struct range *); | |||||
enum { | enum { | ||||
DIFFPROG_OPT, | DIFFPROG_OPT, | ||||
STRIPCR_OPT, | STRIPCR_OPT, | ||||
}; | }; | ||||
#define DIFF_PATH "/usr/bin/diff" | #define DIFF_PATH "/usr/bin/diff" | ||||
▲ Show 20 Lines • Show All 347 Lines • ▼ Show 20 Lines | edit(struct diff *diff, bool dup, int j) | ||||
if (((dup + 1) & eflag) == 0) | if (((dup + 1) & eflag) == 0) | ||||
return (j); | return (j); | ||||
j++; | j++; | ||||
overlap[j] = !dup; | overlap[j] = !dup; | ||||
if (!dup) | if (!dup) | ||||
overlapcnt++; | overlapcnt++; | ||||
de[j].old.from = diff->old.from; | de[j].old.from = diff->old.from; | ||||
de[j].old.to = diff->old.to; | de[j].old.to = diff->old.to; | ||||
de[j].new.from = de[j-1].new.to + skip(2, diff->new.from, NULL); | de[j].new.from = diff->new.from; | ||||
de[j].new.to = de[j].new.from + skip(2, diff->new.to, NULL); | de[j].new.to = diff->new.to; | ||||
return (j); | return (j); | ||||
} | } | ||||
static void | |||||
printrange(FILE *p, struct range *r) | |||||
{ | |||||
char *line = NULL; | |||||
size_t len = 0; | |||||
int i = 1; | |||||
ssize_t rlen = 0; | |||||
/* We haven't been asked to print anything */ | |||||
if (r->from == r->to) | |||||
return; | |||||
if (r->from > r->to) | |||||
errx(EXIT_FAILURE, "invalid print range"); | |||||
/* | |||||
* XXX-THJ: We read through all of the file for each range printed. | |||||
* This duplicates work and will probably impact performance on large | |||||
* files with lots of ranges. | |||||
*/ | |||||
fseek(p, 0L, SEEK_SET); | |||||
while ((rlen = getline(&line, &len, p)) > 0) { | |||||
pstef: Missing space after `while` and in `if (++i > r->to-1)`.
I wonder if it would make more sense… | |||||
Done Inline ActionsGreat points, rereading the getline man page and its clearer how it should be used. thj: Great points, rereading the getline man page and its clearer how it should be used. | |||||
if (i >= r->from) | |||||
printf("%s", line); | |||||
if (++i > r->to - 1) | |||||
break; | |||||
} | |||||
free(line); | |||||
} | |||||
/* regurgitate */ | /* regurgitate */ | ||||
static void | static void | ||||
edscript(int n) | edscript(int n) | ||||
{ | { | ||||
int k; | |||||
bool delete; | bool delete; | ||||
size_t j; | |||||
char block[BUFSIZ]; | |||||
for (; n > 0; n--) { | for (; n > 0; n--) { | ||||
delete = (de[n].new.from == de[n].new.to); | delete = (de[n].new.from == de[n].new.to); | ||||
if (!oflag || !overlap[n]) { | if (!oflag || !overlap[n]) { | ||||
prange(&de[n].old, delete); | prange(&de[n].old, delete); | ||||
} else { | } else { | ||||
printf("%da\n", de[n].old.to - 1); | printf("%da\n", de[n].old.to - 1); | ||||
if (Aflag) { | |||||
printf("%s\n", f2mark); | |||||
fseek(fp[1], de[n].old.from, SEEK_SET); | |||||
for (k = de[n].old.to - de[n].old.from; k > 0; k -= j) { | |||||
j = k > BUFSIZ ? BUFSIZ : k; | |||||
if (fread(block, 1, j, fp[1]) != j) | |||||
errx(2, "logic error"); | |||||
fwrite(block, 1, j, stdout); | |||||
} | |||||
printf("\n"); | |||||
} | |||||
printf("=======\n"); | printf("=======\n"); | ||||
} | } | ||||
fseek(fp[2], (long)de[n].new.from, SEEK_SET); | printrange(fp[2], &de[n].new); | ||||
for (k = de[n].new.to - de[n].new.from; k > 0; k -= j) { | |||||
size_t r; | |||||
j = k > BUFSIZ ? BUFSIZ : k; | |||||
r = fread(block, 1, j, fp[2]); | |||||
if (r == 0) { | |||||
if (feof(fp[2])) | |||||
break; | |||||
errx(2, "logic error"); | |||||
} | |||||
if (r != j) | |||||
j = r; | |||||
(void)fwrite(block, 1, j, stdout); | |||||
} | |||||
if (!oflag || !overlap[n]) { | if (!oflag || !overlap[n]) { | ||||
if (!delete) | if (!delete) | ||||
printf(".\n"); | printf(".\n"); | ||||
} else { | } else { | ||||
printf("%s\n.\n", f3mark); | printf("%s\n.\n", f3mark); | ||||
printf("%da\n%s\n.\n", de[n].old.from - 1, f1mark); | printf("%da\n%s\n.\n", de[n].old.from - 1, f1mark); | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 222 Lines • Show Last 20 Lines |
Missing space after while and in if (++i > r->to-1).
I wonder if it would make more sense to never free and nullify the buffer within the loop, but once it's over. I'd expect it'd be cheaper not to allocate every iteration, the buffer will be expanded and the pointer updated.