diff options
| author | rsc <devnull@localhost> | 2003-11-23 18:03:02 +0000 |
|---|---|---|
| committer | rsc <devnull@localhost> | 2003-11-23 18:03:02 +0000 |
| commit | 5993a8f2756bc455101a8c9ce95347d5050e7883 (patch) | |
| tree | df94fe66c46612af899e6622c808d42a52542b8c /src/cmd/diff/diffdir.c | |
| parent | cfabc3ed1638efc186ebd26bdaa3dfb5663dff17 (diff) | |
the one true diff.
at least it can handle "diff file1 file2 dir".
Diffstat (limited to 'src/cmd/diff/diffdir.c')
| -rw-r--r-- | src/cmd/diff/diffdir.c | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/src/cmd/diff/diffdir.c b/src/cmd/diff/diffdir.c new file mode 100644 index 00000000..41e4fbf4 --- /dev/null +++ b/src/cmd/diff/diffdir.c @@ -0,0 +1,108 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include "diff.h" + +static int +itemcmp(void *v1, void *v2) +{ + char **d1 = v1, **d2 = v2; + + return strcmp(*d1, *d2); +} + +static char ** +scandir(char *name) +{ + char **cp; + Dir *db; + int nitems; + int fd, n; + + if ((fd = open(name, OREAD)) < 0) + panic(2, "can't open %s\n", name); + cp = 0; + nitems = 0; + if((n = dirreadall(fd, &db)) > 0){ + while (n--) { + cp = REALLOC(cp, char *, (nitems+1)); + cp[nitems] = MALLOC(char, strlen((db+n)->name)+1); + strcpy(cp[nitems], (db+n)->name); + nitems++; + } + free(db); + } + cp = REALLOC(cp, char*, (nitems+1)); + cp[nitems] = 0; + close(fd); + qsort((char *)cp, nitems, sizeof(char*), itemcmp); + return cp; +} + +static int +isdotordotdot(char *p) +{ + if (*p == '.') { + if (!p[1]) + return 1; + if (p[1] == '.' && !p[2]) + return 1; + } + return 0; +} + +void +diffdir(char *f, char *t, int level) +{ + char **df, **dt, **dirf, **dirt; + char *from, *to; + int res; + char fb[MAXPATHLEN+1], tb[MAXPATHLEN+1]; + + df = scandir(f); + dt = scandir(t); + dirf = df; + dirt = dt; + while (*df || *dt) { + from = *df; + to = *dt; + if (from && isdotordotdot(from)) { + df++; + continue; + } + if (to && isdotordotdot(to)) { + dt++; + continue; + } + if (!from) + res = 1; + else if (!to) + res = -1; + else + res = strcmp(from, to); + if (res < 0) { + if (mode == 0 || mode == 'n') + Bprint(&stdout, "Only in %s: %s\n", f, from); + df++; + continue; + } + if (res > 0) { + if (mode == 0 || mode == 'n') + Bprint(&stdout, "Only in %s: %s\n", t, to); + dt++; + continue; + } + if (mkpathname(fb, f, from)) + continue; + if (mkpathname(tb, t, to)) + continue; + diff(fb, tb, level+1); + df++; dt++; + } + for (df = dirf; *df; df++) + FREE(*df); + for (dt = dirt; *dt; dt++) + FREE(*dt); + FREE(dirf); + FREE(dirt); +} |