#include <u.h>
#include <libc.h>
#include <bio.h>
#include <auth.h>
#include <libsec.h>
#include <fcall.h>
#include <thread.h>
#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;
}
|