#include "fns.h"
char*
-nodepath(char *s, char *e, Revnode *nd)
+nodepath(char *s, char *e, Revnode *nd, int mangle)
{
static char *frogs[] = {
"con", "prn", "aux", "nul",
"lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9",
};
char *p;
- int i;
+ int i, l;
if(nd == nil || nd->name == nil)
return s;
- s = seprint(nodepath(s, e, nd->up), e, "/");
-
+ s = seprint(nodepath(s, e, nd->up, mangle), e, "/");
p = nd->name;
- for(i=0; i<nelem(frogs); i++)
- if(strcmp(frogs[i], p) == 0)
- return seprint(s, e, "%.2s~%.2x%s", p, p[2], p+3);
+ if(!mangle)
+ return seprint(s, e, "%s", p);
+ for(i=0; i<nelem(frogs); i++){
+ l = strlen(frogs[i]);
+ if((strncmp(frogs[i], p, l) == 0) && (p[l] == 0 || p[l] == '.'))
+ return seprint(s, e, "%.2s~%.2x%s", p, p[2], p+3);
+ }
for(; s+4 < e && *p; p++){
if(*p == '_'){
*s++ = '_';
return s;
}
+Revnode*
+mknode(char *name, uchar *hash, char mode)
+{
+ Revnode *d;
+ char *s;
+
+ d = malloc(sizeof(*d) + (hash ? HASHSZ : 0) + (name ? strlen(name)+1 : 0));
+ memset(d, 0, sizeof(*d));
+ s = (char*)&d[1];
+ if(hash){
+ d->path = hash2qid(hash);
+ memmove(d->hash = (uchar*)s, hash, HASHSZ);
+ s += HASHSZ;
+ }else
+ d->path = 1;
+ if(name)
+ strcpy(d->name = s, name);
+ d->mode = mode;
+ return d;
+}
+
static void
addnode(Revnode *d, char *path, uchar *hash, char mode)
{
- char *slash, *x;
+ char *slash;
Revnode *c, *p;
while(path && *path){
if(strcmp(c->name, path) == 0)
break;
if(c == nil){
- c = malloc(sizeof(*c) + (!slash ? HASHSZ : 0) + strlen(path)+1);
- c->path = 1;
- x = (char*)&c[1];
- if(!slash){
- c->mode = mode;
- memmove(c->hash = (uchar*)x, hash, HASHSZ);
- x += HASHSZ;
- }else{
- c->mode = 0;
- c->hash = nil;
- }
- strcpy(c->name = x, path);
+ c = mknode(path, slash ? nil : hash, slash ? 0 : mode);
c->up = d;
- c->down = nil;
if(p){
c->next = p->next;
p->next = c;
c->next = d->down;
d->down = c;
}
-
- if(c->hash){
+ if(!slash){
p = c;
- p->path = *((uvlong*)c->hash);
- while(d->up){
+ while(d){
d->path += p->path;
p = d;
d = d->up;
x = buf;
x += strlen(x) + 1;
- strhash(x, hash);
+ hex2hash(x, hash);
x += HASHSZ*2;
if(ht == nil)
t = malloc(sizeof(*t));
memset(t, 0, sizeof(*t));
incref(t);
-
- t->root = malloc(sizeof(Revnode));
- t->root->path = 0;
- t->root->name = 0;
- t->root->up = nil;
- t->root->down = nil;
- t->root->next = nil;
- t->root->hash = nil;
-
+ t->root = mknode(nil, nil, 0);
if(loadmanifest(t->root, fd, ht, nh) < 0){
close(fd);
closerevtree(t);
return nil;
}
-
close(fd);
return t;
{
char buf[BUFSZ], *p, *e;
Hashstr *ht[256], *he, **hp;
- int fd, done, line, n;
+ int fd, n;
Revtree *t;
+ vlong off;
if((fd = revlogopentemp(changelog, hashrev(changelog, ri->chash))) < 0)
return nil;
- done = 0;
- line = 0;
+ off = seek(fd, ri->logoff, 0);
+ if(off < 0){
+ close(fd);
+ return nil;
+ }
+
memset(ht, 0, sizeof(ht));
p = buf;
e = buf + BUFSZ;
- while((n = read(fd, p, e - p)) > 0){
+ while((off - ri->logoff) < ri->loglen){
+ if((n = read(fd, p, e - p)) <= 0)
+ break;
p += n;
while((p > buf) && (e = memchr(buf, '\n', p - buf))){
*e++ = 0;
- if(++line >= 4){
- if(*buf == 0){
- done = 1;
- break;
- }
-
- he = malloc(sizeof(*he) + strlen(buf)+1);
- hp = &ht[hashstr(strcpy(he->str, buf)) % nelem(ht)];
- he->next = *hp;
- *hp = he;
- }
+ he = malloc(sizeof(*he) + strlen(buf)+1);
+ hp = &ht[hashstr(strcpy(he->str, buf)) % nelem(ht)];
+ he->next = *hp;
+ *hp = he;
- p -= e - buf;
+ n = e - buf;
+ p -= n;
if(p > buf)
memmove(buf, e, p - buf);
+ off += n;
}
- if(done)
- break;
e = buf + BUFSZ;
}
close(fd);
return;
freenode(nd->down);
freenode(nd->next);
+ freenode(nd->before);
free(nd);
}