| diffdir.c - 9base - revived minimalist port of Plan 9 userland to Unix | |
| git clone git://git.suckless.org/9base | |
| Log | |
| Files | |
| Refs | |
| README | |
| LICENSE | |
| --- | |
| diffdir.c (1900B) | |
| --- | |
| 1 #include <u.h> | |
| 2 #include <libc.h> | |
| 3 #include <bio.h> | |
| 4 #include "diff.h" | |
| 5 | |
| 6 static int | |
| 7 itemcmp(const void *v1, const void *v2) | |
| 8 { | |
| 9 char *const*d1 = v1, *const*d2 = v2; | |
| 10 | |
| 11 return strcmp(*d1, *d2); | |
| 12 } | |
| 13 | |
| 14 static char ** | |
| 15 scandir(char *name) | |
| 16 { | |
| 17 char **cp; | |
| 18 Dir *db; | |
| 19 int nitems; | |
| 20 int fd, n; | |
| 21 | |
| 22 if ((fd = open(name, OREAD)) < 0){ | |
| 23 panic(mflag ? 0 : 2, "can't open %s\n", name); | |
| 24 return nil; | |
| 25 } | |
| 26 cp = 0; | |
| 27 nitems = 0; | |
| 28 if((n = dirreadall(fd, &db)) > 0){ | |
| 29 while (n--) { | |
| 30 cp = REALLOC(cp, char *, (nitems+1)); | |
| 31 cp[nitems] = MALLOC(char, strlen((db+n)->name)+1… | |
| 32 strcpy(cp[nitems], (db+n)->name); | |
| 33 nitems++; | |
| 34 } | |
| 35 free(db); | |
| 36 } | |
| 37 cp = REALLOC(cp, char*, (nitems+1)); | |
| 38 cp[nitems] = 0; | |
| 39 close(fd); | |
| 40 qsort((char *)cp, nitems, sizeof(char*), itemcmp); | |
| 41 return cp; | |
| 42 } | |
| 43 | |
| 44 static int | |
| 45 isdotordotdot(char *p) | |
| 46 { | |
| 47 if (*p == '.') { | |
| 48 if (!p[1]) | |
| 49 return 1; | |
| 50 if (p[1] == '.' && !p[2]) | |
| 51 return 1; | |
| 52 } | |
| 53 return 0; | |
| 54 } | |
| 55 | |
| 56 void | |
| 57 diffdir(char *f, char *t, int level) | |
| 58 { | |
| 59 char **df, **dt, **dirf, **dirt; | |
| 60 char *from, *to; | |
| 61 int res; | |
| 62 char fb[MAXPATHLEN+1], tb[MAXPATHLEN+1]; | |
| 63 | |
| 64 df = scandir(f); | |
| 65 dt = scandir(t); | |
| 66 dirf = df; | |
| 67 dirt = dt; | |
| 68 if(df == nil || dt == nil) | |
| 69 goto Out; | |
| 70 while (*df || *dt) { | |
| 71 from = *df; | |
| 72 to = *dt; | |
| 73 if (from && isdotordotdot(from)) { | |
| 74 df++; | |
| 75 continue; | |
| 76 } | |
| 77 if (to && isdotordotdot(to)) { | |
| 78 dt++; | |
| 79 continue; | |
| 80 } | |
| 81 if (!from) | |
| 82 res = 1; | |
| 83 else if (!to) | |
| 84 res = -1; | |
| 85 else | |
| 86 res = strcmp(from, to); | |
| 87 if (res < 0) { | |
| 88 if (mode == 0 || mode == 'n') | |
| 89 Bprint(&stdout, "Only in %s: %s\n", f, f… | |
| 90 df++; | |
| 91 continue; | |
| 92 } | |
| 93 if (res > 0) { | |
| 94 if (mode == 0 || mode == 'n') | |
| 95 Bprint(&stdout, "Only in %s: %s\n", t, t… | |
| 96 dt++; | |
| 97 continue; | |
| 98 } | |
| 99 if (mkpathname(fb, f, from)) | |
| 100 continue; | |
| 101 if (mkpathname(tb, t, to)) | |
| 102 continue; | |
| 103 diff(fb, tb, level+1); | |
| 104 df++; dt++; | |
| 105 } | |
| 106 Out: | |
| 107 for (df = dirf; df && *df; df++) | |
| 108 FREE(*df); | |
| 109 for (dt = dirt; dt && *dt; dt++) | |
| 110 FREE(*dt); | |
| 111 FREE(dirf); | |
| 112 FREE(dirt); | |
| 113 } |