the one true diff.
at least it can handle "diff file1 file2 dir".
This commit is contained in:
108
src/cmd/diff/diffdir.c
Normal file
108
src/cmd/diff/diffdir.c
Normal file
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user