#include #include #include #include #include #include #include #include <9p.h> #include "cvsfs.h" typedef struct { Ent *ent; Rev *rev; } Log; /* Sort order designed for simplest changelog contents */ static int logcomp(void *a, void *b) { int d; Log *la = a; Log *lb = b; if (labs(la->rev->mtime - lb->rev->mtime) > ATOMIC) return la->rev->mtime - lb->rev->mtime; if ((d = strcmp(la->rev->author, lb->rev->author))) return d; if ((d = strcmp(la->rev->desc, lb->rev->desc))) return d; if ((d = strcmp(la->ent->path, lb->ent->path))) return d; return 0; } static int mklog(Sess *s, Log **log) { Ent *e; Rev *r; Log *l; int nlog; nlog = 0; for (e = s->ents; e < s->ents+s->nents; e++) for (r = e->revs; r; r = r->next) nlog++; *log = emalloc9p(nlog * sizeof(Log)); l = *log; for (e = s->ents; e < s->ents+s->nents; e++) for (r = e->revs; r; r = r->next){ l->ent = e; l->rev = r; l++; } qsort(*log, nlog, sizeof(Log), logcomp); return nlog; } char * changelog(Sess *s) { Fmt f; Tm *tp; int nlog; long omtime; Log *log, *l; char *p, *op, *opath, *path, *oauthor, *odesc, *chglog; char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; omtime = 0; oauthor = ""; odesc = ""; op = opath = ""; nlog = mklog(s, &log); fmtstrinit(&f); for (l = log; l < log+nlog; l++){ if (strcmp(l->rev->desc, odesc) != 0 || strcmp(l->rev->author, oauthor) != 0 || labs(l->rev->mtime - omtime) > 60){ tp = localtime(l->rev->mtime); fmtprint(&f, "\n"); fmtprint(&f, "%d/%s/%d %02d:%02d:%02d %s\n", tp->mday, months[tp->mon], tp->year+1900, tp->hour, tp->min, tp->sec, l->rev->author); fmtprint(&f, "%s", l->rev->desc); op = opath = ""; } path = l->ent->path; assert((p = strrchr(path, '/')) != nil); if (p-path != op-opath || strncmp(path, opath, p-path) != 0) fmtprint(&f, "\t%.*s/...\n", (int)(p-path), path); fmtprint(&f, "\t\t%-32s ", p+1); fmtprint(&f, "%s ", l->rev->rev); if (l->rev->added || l->rev->removed) fmtprint(&f, "+%d-%d ", l->rev->added, l->rev->removed); if (strcmp(l->ent->keysub, "key-val") != 0) fmtprint(&f, "%s ", l->ent->keysub); if (l->rev->locker) fmtprint(&f, "locked-by=%s ", l->rev->locker); fmtprint(&f, "\n"); op = p; opath = l->ent->path; omtime = l->rev->mtime; oauthor = l->rev->author; odesc = l->rev->desc; } chglog = fmtstrflush(&f); free(log); return chglog; }