1.1 --- a/razor.c Sun Oct 07 14:25:06 2007 -0400
1.2 +++ b/razor.c Sun Oct 21 21:57:22 2007 -0400
1.3 @@ -41,6 +41,7 @@
1.4 #define RAZOR_PACKAGE_POOL 4
1.5 #define RAZOR_REQUIRES_POOL 5
1.6 #define RAZOR_PROVIDES_POOL 6
1.7 +#define RAZOR_FILE_TREE 7
1.8
1.9 struct razor_package {
1.10 unsigned long name;
1.11 @@ -55,6 +56,12 @@
1.12 unsigned long packages;
1.13 };
1.14
1.15 +struct razor_entry {
1.16 + unsigned long name;
1.17 + unsigned long count;
1.18 + unsigned long start;
1.19 +};
1.20 +
1.21 struct razor_set {
1.22 struct array string_pool;
1.23 struct array packages;
1.24 @@ -63,6 +70,7 @@
1.25 struct array provides;
1.26 struct array requires_pool;
1.27 struct array provides_pool;
1.28 + struct array file_tree;
1.29 struct razor_set_header *header;
1.30 };
1.31
1.32 @@ -77,6 +85,7 @@
1.33 struct import_property_context requires;
1.34 struct import_property_context provides;
1.35 struct razor_package *package;
1.36 + struct array files;
1.37 };
1.38
1.39 static void
1.40 @@ -154,6 +163,7 @@
1.41 { RAZOR_PACKAGE_POOL, offsetof(struct razor_set, package_pool) },
1.42 { RAZOR_REQUIRES_POOL, offsetof(struct razor_set, requires_pool) },
1.43 { RAZOR_PROVIDES_POOL, offsetof(struct razor_set, provides_pool) },
1.44 + { RAZOR_FILE_TREE, offsetof(struct razor_set, file_tree) },
1.45 };
1.46
1.47 struct razor_set *
1.48 @@ -453,6 +463,10 @@
1.49 void
1.50 razor_importer_add_file(struct razor_importer *importer, const char *name)
1.51 {
1.52 + char **p;
1.53 +
1.54 + p = array_add(&importer->files, sizeof *p);
1.55 + *p = strdup(name);
1.56 }
1.57
1.58 struct razor_importer *
1.59 @@ -682,6 +696,147 @@
1.60 *p = map[*p];
1.61 }
1.62
1.63 +static int
1.64 +compare_filenames(const void *p1, const void *p2, void *data)
1.65 +{
1.66 + char *f1 = *(char **) p1;
1.67 + char *f2 = *(char **) p2;
1.68 +
1.69 + return strcmp(f1, f2);
1.70 +}
1.71 +
1.72 +struct directory {
1.73 + unsigned long name, count;
1.74 + struct array files;
1.75 + struct directory *last;
1.76 +};
1.77 +
1.78 +static void
1.79 +count_entries(struct directory *d)
1.80 +{
1.81 + struct directory *p, *end;
1.82 +
1.83 + p = d->files.data;
1.84 + end = d->files.data + d->files.size;
1.85 + d->count = 0;
1.86 + while (p < end) {
1.87 + count_entries(p);
1.88 + d->count += p->count + 1;
1.89 + p++;
1.90 + }
1.91 +}
1.92 +
1.93 +static void
1.94 +serialize_files(struct directory *d, struct array *array)
1.95 +{
1.96 + struct directory *p, *end;
1.97 + struct razor_entry *e;
1.98 + unsigned long s;
1.99 +
1.100 + p = d->files.data;
1.101 + end = d->files.data + d->files.size;
1.102 + s = array->size / sizeof *e + d->files.size / sizeof *p;
1.103 + while (p < end) {
1.104 + e = array_add(array, sizeof *e);
1.105 + e->name = p->name;
1.106 + e->count = p->files.size / sizeof *p;
1.107 + e->start = s;
1.108 + s += p->count;
1.109 + p++;
1.110 + }
1.111 +
1.112 + p = d->files.data;
1.113 + end = d->files.data + d->files.size;
1.114 + while (p < end) {
1.115 + serialize_files(p, array);
1.116 + p++;
1.117 + }
1.118 +}
1.119 +
1.120 +static void
1.121 +build_file_tree(struct razor_importer *importer)
1.122 +{
1.123 + int count, i, length;
1.124 + char **filenames, *f, *end;
1.125 + unsigned long name;
1.126 + char dirname[256];
1.127 + struct directory *d, root;
1.128 + struct razor_entry *e;
1.129 +
1.130 + count = importer->files.size / sizeof (char *);
1.131 + qsort_with_data(importer->files.data,
1.132 + count,
1.133 + sizeof (char *),
1.134 + compare_filenames,
1.135 + NULL);
1.136 +
1.137 + root.name = razor_importer_tokenize(importer, "");
1.138 + array_init(&root.files);
1.139 + root.last = NULL;
1.140 +
1.141 + filenames = importer->files.data;
1.142 + for (i = 0; i < count; i++) {
1.143 + f = filenames[i];
1.144 + if (*f != '/')
1.145 + continue;
1.146 +
1.147 + d = &root;
1.148 + while (*f) {
1.149 + end = strchr(f + 1, '/');
1.150 + if (end == NULL)
1.151 + end = f + strlen(f);
1.152 + length = end - (f + 1);
1.153 + memcpy(dirname, f + 1, length);
1.154 + dirname[length] ='\0';
1.155 + name = razor_importer_tokenize(importer, dirname);
1.156 + if (d->last == NULL || d->last->name != name) {
1.157 + d->last = array_add(&d->files, sizeof *d);
1.158 + d->last->name = name;
1.159 + d->last->last = NULL;
1.160 + array_init(&d->last->files);
1.161 + }
1.162 + d = d->last;
1.163 + f = end;
1.164 + }
1.165 +
1.166 + free(filenames[i]);
1.167 + }
1.168 +
1.169 + count_entries(&root);
1.170 + array_init(&importer->set->file_tree);
1.171 +
1.172 + e = array_add(&importer->set->file_tree, sizeof *e);
1.173 + e->name = root.name;
1.174 + e->count = root.files.size / sizeof *d;
1.175 + e->start = 1;
1.176 +
1.177 + serialize_files(&root, &importer->set->file_tree);
1.178 +
1.179 + array_release(&importer->files);
1.180 +}
1.181 +
1.182 +static void
1.183 +list_dir(struct razor_set *set, struct razor_entry *e, int indent)
1.184 +{
1.185 + struct razor_entry *c;
1.186 + char *pool = set->string_pool.data;
1.187 + int i;
1.188 +
1.189 + for (i = 0; i < indent; i++)
1.190 + putchar(' ');
1.191 + printf("%s\n", pool + e->name);
1.192 + for (i = 0; i < e->count; i++) {
1.193 + c = (struct razor_entry *) set->file_tree.data + e->start + i;
1.194 + list_dir(set, c, indent + 2);
1.195 + }
1.196 +}
1.197 +
1.198 +void
1.199 +razor_set_list_files(struct razor_set *set)
1.200 +{
1.201 + list_dir(set, set->file_tree.data, 2);
1.202 +}
1.203 +
1.204 struct razor_set *
1.205 razor_importer_finish(struct razor_importer *importer)
1.206 {
1.207 @@ -712,6 +867,8 @@
1.208 free(map);
1.209 free(rmap);
1.210
1.211 + build_file_tree(importer);
1.212 +
1.213 set = importer->set;
1.214 array_release(&importer->buckets);
1.215 free(importer);