Suggestion from James Beal: support a '--title' option to override the
[sgt/agedu] / trie.c
diff --git a/trie.c b/trie.c
index 345756f..4857891 100644 (file)
--- a/trie.c
+++ b/trie.c
@@ -15,9 +15,9 @@
  */
 static int trieccmp(unsigned char a, unsigned char b)
 {
-    a = (a == '\0' ? '\0' : a == pathsep ? '\1' : a+1);
-    b = (b == '\0' ? '\0' : b == pathsep ? '\1' : b+1);
-    return (int)a - (int)b;
+    int ia = (a == '\0' ? '\0' : a == pathsep ? '\1' : a+1);
+    int ib = (b == '\0' ? '\0' : b == pathsep ? '\1' : b+1);
+    return ia - ib;
 }
 
 static int triencmp(const char *a, size_t alen,
@@ -218,7 +218,8 @@ static off_t triebuild_unwind(triebuild *tb, int targetdepth, int *outcount)
     while (depth > targetdepth) {
        int odepth = depth;
        while (depth > targetdepth &&
-              (depth-1 > tb->switchsize || tb->switches[depth-1].len == 0))
+              (depth-1 > tb->switchsize || !tb->switches ||
+               tb->switches[depth-1].len == 0))
            depth--;
        if (odepth > depth) {
            /*
@@ -483,6 +484,7 @@ static unsigned long long fake_atime_recurse(void *t, struct trie_common *node,
 
        return max;
     }
+    return 0;                         /* placate lint */
 }
 
 void trie_fake_dir_atimes(void *t)
@@ -592,7 +594,36 @@ void trie_getpath(const void *t, unsigned long n, char *buf)
            assert(i < sw->len);
        }
     }
-}    
+}
+
+const struct trie_file *trie_getfile(const void *t, unsigned long n)
+{
+    const struct trie_header *hdr = NODE(t, 0, trie_header);
+    off_t off = hdr->root;
+
+    while (1) {
+       const struct trie_common *node = NODE(t, off, trie_common);
+       if (node->type == TRIE_LEAF) {
+           const struct trie_leaf *leaf = NODE(t, off, trie_leaf);
+           return &leaf->file;
+       } else if (node->type == TRIE_STRING) {
+           const struct trie_string *st = NODE(t, off, trie_string);
+           off = st->subnode;
+       } else if (node->type == TRIE_SWITCH) {
+           const struct trie_switch *sw = NODE(t, off, trie_switch);
+           int i;
+
+           for (i = 0; i < sw->len; i++) {
+               if (n < sw->sw[i].subcount) {
+                   off = sw->sw[i].subnode;
+                   break;
+               } else
+                   n -= sw->sw[i].subcount;
+           }
+           assert(i < sw->len);
+       }
+    }
+}
 
 unsigned long trie_count(const void *t)
 {