From 9cb611555bcd493e3cf70f47e61c905ac43e0db4 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Wed, 29 Jun 2022 13:12:07 -0500 Subject: [PATCH] Cleanup pass on diff. --- toys/pending/diff.c | 196 +++++++++++++++++--------------------------- 1 file changed, 77 insertions(+), 119 deletions(-) diff --git a/toys/pending/diff.c b/toys/pending/diff.c index 2f73bd8b..10b57dd9 100644 --- a/toys/pending/diff.c +++ b/toys/pending/diff.c @@ -49,18 +49,13 @@ GLOBALS( long ct; char *start; struct arg_list *L_list; - char *new_line_format; - char *old_line_format; - char *unchanged_line_format; + char *new_line_format, *old_line_format, *unchanged_line_format; - int dir_num, size, is_binary, status, change, len[2]; - int *offset[2]; + int dir_num, size, is_binary, differ, change, len[2], *offset[2]; struct stat st[2]; ) -#define MIN(x,y) ((x) < (y) ? (x) : (y)) -#define MAX(x,y) ((x) > (y) ? (x) : (y)) -#define IS_STDIN(s) ((s)[0] == '-' && !(s)[1]) +#define IS_STDIN(s) (*(s)=='-' && !(s)[1]) struct v_vector { unsigned serial:31; @@ -102,14 +97,11 @@ enum { space = 1 << 12 }; -static int comp(const void *a, const void* b) +static int comp(void *a, void *b) { - int i = ((struct v_vector *)a)->hash - - ((struct v_vector *)b)->hash; + int i = ((struct v_vector *)a)->hash - ((struct v_vector *)b)->hash; - if (!i) i = ((struct v_vector *)a)->serial - - ((struct v_vector *)b)->serial; - return i; + return i ? : ((struct v_vector *)a)->serial - ((struct v_vector *)b)->serial; } static int search (struct candidate **K, int r, int k, int j) @@ -118,12 +110,12 @@ static int search (struct candidate **K, int r, int k, int j) mid = (low + upper) / 2; while (low <= mid) { - if (((struct candidate*)(K[mid]))->b < j && - ((struct candidate*)(K[mid + 1]))->b > j) + if (((struct candidate *)(K[mid]))->b < j && + ((struct candidate *)(K[mid + 1]))->b > j) return mid; - if (((struct candidate*)(K[mid]))->b < j) low = mid + 1; - else if (((struct candidate*)(K[mid]))->b > j) upper = mid - 1; + if (((struct candidate *)(K[mid]))->b < j) low = mid + 1; + else if (((struct candidate *)(K[mid]))->b > j) upper = mid - 1; else return -1; mid = (low + upper) / 2; @@ -131,7 +123,7 @@ static int search (struct candidate **K, int r, int k, int j) return -1; } -static struct candidate * new_candidate (int i, int j, struct candidate* prev) +static struct candidate * new_candidate (int i, int j, struct candidate *prev) { struct candidate *c = xzalloc(sizeof(struct candidate)); @@ -169,10 +161,10 @@ static void do_merge(struct candidate **K, int *k, int i, while (1) { j = E[p].serial; s = search(K, r, *k, j); - if (s >= 0 && (((struct candidate*)(K[s]))->b < j && - ((struct candidate*)(K[s + 1]))->b > j)) { + if (s >= 0 && (((struct candidate *)(K[s]))->b < j && + ((struct candidate *)(K[s + 1]))->b > j)) { - if (((struct candidate*)(K[s + 1]))->b > j) { + if (((struct candidate *)(K[s + 1]))->b > j) { pr = K[s]; if (r && K[r]) c->next = K[r]; K[r] = c; @@ -191,7 +183,7 @@ static void do_merge(struct candidate **K, int *k, int i, K[r] = c; } -static FILE* read_stdin() +static FILE *read_stdin() { char *tmp_name; int tmpfd = xtempfile("stdin", &tmp_name); @@ -203,7 +195,7 @@ static FILE* read_stdin() return fdopen(tmpfd, "r"); } -static FILE* read_fifo(char* name) +static FILE *read_fifo(char *name) { char *tmp_name; int srcfd = open(name, O_RDONLY); @@ -259,17 +251,11 @@ static int read_tok(FILE *fp, off_t *off, int tok) return tok; } -int bcomp(const void *a, const void *b) +int bcomp(void *a, void *b) { - struct v_vector *l = (struct v_vector*)a, - *r = (struct v_vector*)b; - int ret = l->hash - r->hash; + struct v_vector *l = (struct v_vector *)a, *r = (struct v_vector *)b; - if (!ret) { - if ((r -1)->last) return 0; - else return -1; - } - return ret; + return (l->hash-r->hash) ? : r[-1].last ? 0 : -1; } /* file[0] corresponds file 1 and file[1] correspond file 2. * 1. calc hashes for both the files and store them in vector(v[0], v[1]) @@ -284,7 +270,7 @@ int bcomp(const void *a, const void *b) * 6. Create a vector J[i] = j, such that i'th line in file[0] is j'th line of * file[1], i.e J comprises LCS */ -static int * create_j_vector() +static int *create_j_vector() { int tok, i, j, size = 100, k; off_t off; @@ -328,31 +314,30 @@ static int * create_j_vector() } for (i = 0; i <= file[1].len; i++) v[1][i].serial = i; - qsort(v[1] + 1, file[1].len, sizeof(struct v_vector), comp); + qsort(v[1] + 1, file[1].len, sizeof(struct v_vector), (void *)comp); e = v[1]; e[0].serial = 0; e[0].last = 1; - for ( i = 1; i <= file[1].len; i++) { + for (i = 1; i <= file[1].len; i++) { if ((i == file[1].len) || (v[1][i].hash != v[1][i+1].hash)) e[i].last = 1; else e[i].last = 0; } p_vector = xzalloc((file[0].len + 2) * sizeof(int)); for (i = 1; i <= file[0].len; i++) { - void *r = bsearch(&v[0][i], (e + 1), file[1].len, sizeof(e[0]), bcomp); - if (r) p_vector[i] = (struct v_vector*)r - e; + void *r = bsearch(&v[0][i], e+1, file[1].len, sizeof(e[0]), (void *)bcomp); + if (r) p_vector[i] = (struct v_vector *)r - e; } - for (i = 1; i <= file[0].len; i++) - e[i].p = p_vector[i]; + for (i = 1; i<=file[0].len; i++) e[i].p = p_vector[i]; free(p_vector); size = 100; - kcand = xzalloc(size * sizeof(struct candidate*)); + kcand = xzalloc(size * sizeof(struct candidate *)); - kcand[0] = new_candidate(0 , 0, NULL); - kcand[1] = new_candidate(file[0].len+1, file[1].len+1, NULL); //the fence + kcand[0] = new_candidate(0 , 0, 0); + kcand[1] = new_candidate(file[0].len+1, file[1].len+1, 0); //the fence k = 0; //last successfully filled k candidate. for (i = 1; i <= file[0].len; i++) { @@ -360,7 +345,7 @@ static int * create_j_vector() if (!e[i].p) continue; if ((size - 2) == k) { size = size * 11 / 10; - kcand = xrealloc(kcand, (size * sizeof(struct candidate*))); + kcand = xrealloc(kcand, (size * sizeof(struct candidate *))); } do_merge(kcand, &k, i, e, e[i].p); } @@ -403,7 +388,7 @@ static int *diff(char **files) char *bufi, *bufj; TT.is_binary = 0; //loop calls to diff - TT.status = SAME; + TT.differ = 0; for (i = 0; i < 2; i++) { if (IS_STDIN(files[i])) file[i].fp = read_stdin(); @@ -412,8 +397,8 @@ static int *diff(char **files) if (!file[i].fp){ perror_msg("%s",files[i]); - TT.status = 2; - return NULL; //return SAME + TT.differ = 2; + return 0; //return SAME } } @@ -430,20 +415,18 @@ static int *diff(char **files) i = fread(bufi, 1, s, file[0].fp); j = fread(bufj, 1, s, file[1].fp); - if (i != j) TT.status = DIFFER; + if (i != j) TT.differ = 1; - for (t = 0; t < i && !TT.is_binary; t++) - if (!bufi[t]) TT.is_binary = 1; - for (t = 0; t < j && !TT.is_binary; t++) - if (!bufj[t]) TT.is_binary = 1; + for (t = 0; t < i && !TT.is_binary; t++) if (!bufi[t]) TT.is_binary = 1; + for (t = 0; t < j && !TT.is_binary; t++) if (!bufj[t]) TT.is_binary = 1; - i = MIN(i, j); - for (t = 0; t < i; t++) - if (bufi[t] != bufj[t]) TT.status = DIFFER; + i = minof(i, j); + for (t = 0; t < i; t++) if (bufi[t] != bufj[t]) TT.differ = 1; if (!i || !j) break; } - if (TT.is_binary || (TT.status == SAME)) return NULL; + if (TT.is_binary || !TT.differ) return 0; + return create_j_vector(); } @@ -571,9 +554,9 @@ static int list_dir (struct dirtree *node) } } -static int cmp(const void *p1, const void *p2) +static int cmp(void *p1, void *p2) { - return strcmp(* (char * const *)p1, * (char * const *)p2); + return strcmp(*(char **)p1, *(char **)p2); } // quote and escape filenames that have awkward characters @@ -638,7 +621,6 @@ static void show_label(char *prefix, char *filename, struct stat *sb) static void do_diff(char **files) { - long i = 1, size = 1, x = 0, change = 0, ignore_white, start1, end1, start2, end2; struct diff *d; @@ -677,8 +659,8 @@ static void do_diff(char **files) } } - if ((d[x].a <= d[x].b || d[x].c <= d[x].d) && !ignore_white) - change = 1; //is we have diff ? + //is we have diff ? TODO: lolcat? + if ((d[x].a <= d[x].b || d[x].c <= d[x].d) && !ignore_white) change = 1; if (!ignore_white) d = xrealloc(d, (x + 2) *sizeof(struct diff)); i = d[x].b + 1; @@ -688,42 +670,37 @@ static void do_diff(char **files) } while (i <= file[0].len); i = x+1; - TT.status = change; //update status, may change bcoz of -w etc. + TT.differ = change; //update status, may change bcoz of -w etc. - if (!(toys.optflags & FLAG_q) && change) { //start of !FLAG_q + if (!FLAG(q) && change) { if (!TT.new_line_format) { - if (toys.optflags & FLAG_color) printf("\e[1m"); - if (toys.optflags & FLAG_L) printf("--- %s\n", llist->arg); + if (FLAG(color)) printf("\e[1m"); + if (FLAG(L)) printf("--- %s\n", llist->arg); else show_label("---", files[0], &(TT).st[0]); - if (((toys.optflags & FLAG_L) && !llist->next) || !(toys.optflags & FLAG_L)) - show_label("+++", files[1], &(TT).st[1]); + if (!FLAG(L) || !llist->next) show_label("+++", files[1], &(TT).st[1]); else { while (llist->next) llist = llist->next; printf("+++ %s\n", llist->arg); } - if (toys.optflags & FLAG_color) printf("\e[0m"); + if (FLAG(color)) printf("\e[0m"); } struct diff *t, *ptr1 = d, *ptr2 = d; while (i) { long a,b; - if (TT.new_line_format || TT.ct > file[0].len) TT.ct = file[0].len; //trim context to file len. + // trim context to file len. + if (TT.new_line_format || TT.ct > file[0].len) TT.ct = file[0].len; if (ptr1->b < ptr1->a && ptr1->d < ptr1->c) { i--; continue; } //Handle the context stuff a = ptr1->a; - b = ptr1->b; - - b = MIN(file[0].len, b); - if (i == x + 1) ptr1->suff = MAX(1,a - TT.ct); - else { - if ((ptr1 - 1)->prev >= (ptr1->a - TT.ct)) - ptr1->suff = (ptr1 - 1)->prev + 1; - else ptr1->suff = ptr1->a - TT.ct; - } + b = minof(file[0].len, ptr1->b); + if (i == x + 1) ptr1->suff = maxof(1, a-TT.ct); + else if (ptr1[-1].prev >= ptr1->a-TT.ct) ptr1->suff = ptr1[-1].prev+1; + else ptr1->suff = ptr1->a-TT.ct; calc_ct: if (i > 1) { if ((ptr2->b + TT.ct) >= (ptr2 + 1)->a) { @@ -734,7 +711,7 @@ calc_ct: } else ptr2->prev = ptr2->b; start1 = (ptr2->prev - ptr1->suff + 1); end1 = (start1 == 1) ? -1 : start1; - start2 = MAX(1, ptr1->c - (ptr1->a - ptr1->suff)); + start2 = maxof(1, ptr1->c - (ptr1->a - ptr1->suff)); end2 = ptr2->prev - ptr2->b + ptr2->d; if (!TT.new_line_format) { @@ -772,16 +749,10 @@ calc_ct: static void show_status(char **files) { - switch (TT.status) { - case SAME: - if (toys.optflags & FLAG_s) - printf("Files %s and %s are identical\n",files[0], files[1]); - break; - case DIFFER: - if ((toys.optflags & FLAG_q) || TT.is_binary) - printf("Files %s and %s differ\n",files[0], files[1]); - break; - } + if (TT.differ==2) return; // TODO: needed? + if (TT.differ ? FLAG(q) || TT.is_binary : FLAG(s)) + printf("Files %s and %s %s\n", files[0], files[1], + TT.differ ? "differ" : "are identical"); } static void create_empty_entry(int l , int r, int j) @@ -858,7 +829,7 @@ static void diff_dir(int *start) free(dir[0].list[l]); l++; } - TT.status = DIFFER; + TT.differ = 1; } else { create_empty_entry(l, r, j); //create non empty dirs/files if -N. if (j > 0) { @@ -880,7 +851,7 @@ static void diff_dir(int *start) while (r < dir[1].nr_elm) { if (!(toys.optflags & FLAG_N)) { printf ("Only in %s: %s\n", dir[1].list[0], dir[1].list[r] + TT.len[1]); - TT.status = DIFFER; + TT.differ = 1; } else create_empty_entry(l, r, 1); free(dir[1].list[r]); r++; @@ -889,7 +860,7 @@ static void diff_dir(int *start) while (l < dir[0].nr_elm) { if (!(toys.optflags & FLAG_N)) { printf ("Only in %s: %s\n", dir[0].list[0], dir[0].list[l] + TT.len[0]); - TT.status = DIFFER; + TT.differ = 1; } else create_empty_entry(l, r, -1); free(dir[0].list[l]); l++; @@ -906,35 +877,23 @@ void diff_main(void) toys.exitval = 2; - if ((toys.optflags & FLAG_color) && !isatty(1)) toys.optflags ^= FLAG_color; + if (FLAG(color) && !isatty(1)) toys.optflags ^= FLAG_color; for (j = 0; j < 2; j++) { files[j] = toys.optargs[j]; - if (IS_STDIN(files[j])) { - if (fstat(0, &TT.st[j]) == -1) - perror_exit("can't fstat %s", files[j]); - } else { - xstat(files[j], &TT.st[j]); - } + if (IS_STDIN(files[j])) fstat(0, &TT.st[j]); + else xstat(files[j], &TT.st[j]); } - if ((IS_STDIN(files[0]) || IS_STDIN(files[1])) - && (S_ISDIR(TT.st[0].st_mode) || S_ISDIR(TT.st[1].st_mode))) - error_exit("can't compare stdin to directory"); - - if ((S_ISFIFO(TT.st[0].st_mode) || S_ISFIFO(TT.st[1].st_mode)) - && (S_ISDIR(TT.st[0].st_mode) || S_ISDIR(TT.st[1].st_mode))) - error_exit("can't compare pipe to directory"); + if (S_ISDIR(TT.st[0].st_mode) != S_ISDIR(TT.st[1].st_mode)) + error_exit("can't compare directory to non-directory"); if (TT.unchanged_line_format || TT.old_line_format || TT.new_line_format) { if (S_ISDIR(TT.st[0].st_mode) && S_ISDIR(TT.st[1].st_mode)) error_exit("can't use line format with directories"); - if (!TT.unchanged_line_format) - TT.unchanged_line_format = "%l\n"; - if (!TT.old_line_format) - TT.old_line_format = "%l\n"; - if (!TT.new_line_format) - TT.new_line_format = "%l\n"; + if (!TT.unchanged_line_format) TT.unchanged_line_format = "%l\n"; + if (!TT.old_line_format) TT.old_line_format = "%l\n"; + if (!TT.new_line_format) TT.new_line_format = "%l\n"; } if ((TT.st[0].st_ino == TT.st[1].st_ino) //physicaly same device @@ -945,10 +904,10 @@ void diff_main(void) if (S_ISDIR(TT.st[0].st_mode) && S_ISDIR(TT.st[1].st_mode)) { for (j = 0; j < 2; j++) { - memset(&dir[j], 0, sizeof(struct dir_t)); + memset(dir+j, 0, sizeof(struct dir_t)); dirtree_flagread(files[j], DIRTREE_SYMFOLLOW, list_dir); dir[j].nr_elm = TT.size; //size updated in list_dir - qsort(&(dir[j].list[1]), (TT.size - 1), sizeof(char*), cmp); + qsort(&(dir[j].list[1]), TT.size - 1, sizeof(char *), (void *)cmp); TT.len[j] = strlen(dir[j].list[0]); //calc root node len TT.len[j] += (dir[j].list[0][TT.len[j] -1] != '/'); @@ -965,21 +924,20 @@ void diff_main(void) k = 1; } diff_dir(start); - free(dir[0].list); //free array + free(dir[0].list); free(dir[1].list); } else { if (S_ISDIR(TT.st[0].st_mode) || S_ISDIR(TT.st[1].st_mode)) { int d = S_ISDIR(TT.st[0].st_mode); char *slash = strrchr(files[d], '/'); - files[1 - d] = concat_file_path(files[1 - d], slash ? slash + 1 : files[d]); - if ((stat(files[1 - d], &TT.st[1 - d])) == -1) - perror_exit("%s", files[1 - d]); + files[!d] = concat_file_path(files[!d], slash ? slash+1 : files[d]); + if (stat(files[!d], &TT.st[!d])) perror_exit("%s", files[!d]); } do_diff(files); show_status(files); if (file[0].fp) fclose(file[0].fp); if (file[1].fp) fclose(file[1].fp); } - toys.exitval = TT.status; //exit status will be the status + toys.exitval = TT.differ; //exit status will be the status } -- 2.39.2