8 nodepath(char *s, char *e, Revnode *nd, int mangle)
10 static char *frogs[] = {
11 "con", "prn", "aux", "nul",
12 "com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9",
13 "lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9",
18 if(nd == nil || nd->name == nil)
21 s = seprint(nodepath(s, e, nd->up, mangle), e, "/");
24 return seprint(s, e, "%s", p);
26 for(i=0; i<nelem(frogs); i++){
28 if((strncmp(frogs[i], p, l) == 0) && (p[l] == 0 || p[l] == '.'))
29 return seprint(s, e, "%.2s~%.2x%s", p, (uchar)p[2], p+3);
31 for(; s+4 < e && *p; p++){
35 } else if(*p >= 'A' && *p <= 'Z'){
37 *s++ = 'a' + (*p - 'A');
38 } else if((uchar)*p >= 126 || strchr("\\:*?\"<>|", *p)){
40 s = seprint(s, e, "%.2x", (uchar)*p);
50 mknode(char *name, uchar *hash, char mode)
55 d = malloc(sizeof(*d) + (hash ? HASHSZ : 0) + (name ? strlen(name)+1 : 0));
56 memset(d, 0, sizeof(*d));
59 d->path = hash2qid(hash);
60 memmove(d->hash = (uchar*)s, hash, HASHSZ);
65 strcpy(d->name = s, name);
71 addnode(Revnode *d, char *path, uchar *hash, char mode)
77 if(slash = strchr(path, '/'))
80 for(c = d->down; c; p = c, c = c->next)
81 if(strcmp(c->name, path) == 0)
84 c = mknode(path, slash ? nil : hash, slash ? 0 : mode);
107 typedef struct Hashstr Hashstr;
115 loadmanifest(Revnode *root, int fd, Hashstr **ht, int nh)
117 char buf[BUFSZ], *p, *e, *x;
123 while((n = read(fd, p, e - p)) > 0){
125 while((p > buf) && (e = memchr(buf, '\n', p - buf))){
134 addnode(root, buf, hash, *x);
138 for(he = ht[hashstr(buf) % nh]; he; he = he->next){
139 if(strcmp(he->str, buf) == 0){
140 addnode(root, buf, hash, *x);
148 memmove(buf, e, p - buf);
156 loadtree(Revlog *manifest, Revinfo *ri, Hashstr **ht, int nh)
161 if((fd = revlogopentemp(manifest, hashrev(manifest, ri->mhash))) < 0)
164 t = malloc(sizeof(*t));
165 memset(t, 0, sizeof(*t));
167 t->root = mknode(nil, nil, 0);
168 if(loadmanifest(t->root, fd, ht, nh) < 0){
179 loadfilestree(Revlog *, Revlog *manifest, Revinfo *ri)
181 return loadtree(manifest, ri, nil, 0);
185 loadchangestree(Revlog *changelog, Revlog *manifest, Revinfo *ri)
187 char buf[BUFSZ], *p, *e;
188 Hashstr *ht[256], *he, **hp;
193 if((fd = revlogopentemp(changelog, hashrev(changelog, ri->chash))) < 0)
196 off = seek(fd, ri->logoff, 0);
202 memset(ht, 0, sizeof(ht));
206 while((off - ri->logoff) < ri->loglen){
207 if((n = read(fd, p, e - p)) <= 0)
210 while((p > buf) && (e = memchr(buf, '\n', p - buf))){
213 he = malloc(sizeof(*he) + strlen(buf)+1);
214 hp = &ht[hashstr(strcpy(he->str, buf)) % nelem(ht)];
221 memmove(buf, e, p - buf);
228 t = loadtree(manifest, ri, ht, nelem(ht));
230 for(hp = ht; hp != &ht[nelem(ht)]; hp++){
241 freenode(Revnode *nd)
247 freenode(nd->before);
252 closerevtree(Revtree *t)
254 if(t == nil || decref(t))