1.1 --- a/razor.c Tue Oct 23 01:57:39 2007 -0400
1.2 +++ b/razor.c Wed Oct 24 00:05:42 2007 -0400
1.3 @@ -35,20 +35,22 @@
1.4 #define RAZOR_MAGIC 0x7a7a7a7a
1.5 #define RAZOR_VERSION 1
1.6
1.7 -#define RAZOR_PACKAGES 0
1.8 -#define RAZOR_REQUIRES 1
1.9 -#define RAZOR_PROVIDES 2
1.10 -#define RAZOR_STRING_POOL 3
1.11 -#define RAZOR_PACKAGE_POOL 4
1.12 -#define RAZOR_REQUIRES_POOL 5
1.13 -#define RAZOR_PROVIDES_POOL 6
1.14 -#define RAZOR_FILE_TREE 7
1.15 +#define RAZOR_STRING_POOL 0
1.16 +#define RAZOR_PACKAGES 1
1.17 +#define RAZOR_REQUIRES 2
1.18 +#define RAZOR_PROVIDES 3
1.19 +#define RAZOR_FILES 4
1.20 +#define RAZOR_PACKAGE_POOL 5
1.21 +#define RAZOR_REQUIRES_POOL 6
1.22 +#define RAZOR_PROVIDES_POOL 7
1.23 +#define RAZOR_FILE_POOL 8
1.24
1.25 struct razor_package {
1.26 unsigned long name;
1.27 unsigned long version;
1.28 unsigned long requires;
1.29 unsigned long provides;
1.30 + unsigned long files;
1.31 };
1.32
1.33 struct razor_property {
1.34 @@ -59,7 +61,6 @@
1.35
1.36 struct razor_entry {
1.37 unsigned long name;
1.38 - unsigned long count;
1.39 unsigned long start;
1.40 unsigned long packages;
1.41 };
1.42 @@ -67,12 +68,13 @@
1.43 struct razor_set {
1.44 struct array string_pool;
1.45 struct array packages;
1.46 - struct array package_pool;
1.47 struct array requires;
1.48 struct array provides;
1.49 + struct array files;
1.50 + struct array package_pool;
1.51 struct array requires_pool;
1.52 struct array provides_pool;
1.53 - struct array file_tree;
1.54 + struct array file_pool;
1.55 struct razor_set_header *header;
1.56 };
1.57
1.58 @@ -170,14 +172,15 @@
1.59 }
1.60
1.61 struct razor_set_section razor_sections[] = {
1.62 + { RAZOR_STRING_POOL, offsetof(struct razor_set, string_pool) },
1.63 { RAZOR_PACKAGES, offsetof(struct razor_set, packages) },
1.64 { RAZOR_REQUIRES, offsetof(struct razor_set, requires) },
1.65 { RAZOR_PROVIDES, offsetof(struct razor_set, provides) },
1.66 - { RAZOR_STRING_POOL, offsetof(struct razor_set, string_pool) },
1.67 + { RAZOR_FILES, offsetof(struct razor_set, files) },
1.68 { RAZOR_PACKAGE_POOL, offsetof(struct razor_set, package_pool) },
1.69 { RAZOR_REQUIRES_POOL, offsetof(struct razor_set, requires_pool) },
1.70 { RAZOR_PROVIDES_POOL, offsetof(struct razor_set, provides_pool) },
1.71 - { RAZOR_FILE_TREE, offsetof(struct razor_set, file_tree) },
1.72 + { RAZOR_FILE_POOL, offsetof(struct razor_set, file_pool) },
1.73 };
1.74
1.75 struct razor_set *
1.76 @@ -737,12 +740,15 @@
1.77 }
1.78 }
1.79
1.80 +#define RAZOR_ENTRY_LAST 0x80000000ul
1.81 +#define RAZOR_ENTRY_MASK 0x00fffffful
1.82 +
1.83 static void
1.84 serialize_files(struct razor_set *set,
1.85 struct import_directory *d, struct array *array)
1.86 {
1.87 struct import_directory *p, *end;
1.88 - struct razor_entry *e;
1.89 + struct razor_entry *e = NULL;
1.90 unsigned long s;
1.91
1.92 p = d->files.data;
1.93 @@ -751,14 +757,15 @@
1.94 while (p < end) {
1.95 e = array_add(array, sizeof *e);
1.96 e->name = p->name;
1.97 - e->count = p->files.size / sizeof *p;
1.98 - e->start = s;
1.99 + e->start = p->count > 0 ? s : 0;
1.100 s += p->count;
1.101 e->packages = add_to_property_pool(&set->package_pool,
1.102 &p->packages);
1.103 array_release(&p->packages);
1.104 p++;
1.105 }
1.106 + if (e != NULL)
1.107 + e->name |= RAZOR_ENTRY_LAST;
1.108
1.109 p = d->files.data;
1.110 end = d->files.data + d->files.size;
1.111 @@ -823,108 +830,48 @@
1.112 }
1.113
1.114 count_entries(&root);
1.115 - array_init(&importer->set->file_tree);
1.116 + array_init(&importer->set->files);
1.117
1.118 - e = array_add(&importer->set->file_tree, sizeof *e);
1.119 - e->name = root.name;
1.120 - e->count = root.files.size / sizeof *d;
1.121 + e = array_add(&importer->set->files, sizeof *e);
1.122 + e->name = root.name | RAZOR_ENTRY_LAST;
1.123 e->start = 1;
1.124 + e->packages = 0;
1.125
1.126 - serialize_files(importer->set, &root, &importer->set->file_tree);
1.127 + serialize_files(importer->set, &root, &importer->set->files);
1.128
1.129 array_release(&importer->files);
1.130 }
1.131
1.132 -static const char *
1.133 -find_dir(struct razor_set *set, struct razor_entry **dir, const char *pattern)
1.134 +static void
1.135 +build_package_file_lists(struct razor_set *set)
1.136 {
1.137 + struct razor_package *p, *packages;
1.138 + struct array *pkgs;
1.139 struct razor_entry *e, *end;
1.140 - const char *n, *pool = set->string_pool.data;
1.141 - int len;
1.142 + unsigned long *r, *q;
1.143 + int i, count;
1.144
1.145 - e = (struct razor_entry *) set->file_tree.data + (*dir)->start;
1.146 - end = e + (*dir)->count;
1.147 + count = set->packages.size / sizeof *p;
1.148 + pkgs = zalloc(count * sizeof *pkgs);
1.149
1.150 + e = set->files.data;
1.151 + end = set->files.data + set->files.size;
1.152 while (e < end) {
1.153 - n = pool + e->name;
1.154 - len = strlen(n);
1.155 - if (len == 0) {
1.156 - /* FIXME: Shouldn't have 0-length entries... */
1.157 - e++;
1.158 - continue;
1.159 - }
1.160 -
1.161 - if (strncmp(pattern + 1, n, len) == 0 &&
1.162 - pattern[len + 1] == '/') {
1.163 - *dir = e;
1.164 - return find_dir(set, dir, pattern + len + 1);
1.165 + r = (unsigned long *) set->package_pool.data + e->packages;
1.166 + while (~*r) {
1.167 + q = array_add(&pkgs[*r++], sizeof *q);
1.168 + *q = e - (struct razor_entry *) set->files.data;
1.169 }
1.170 e++;
1.171 }
1.172
1.173 - return pattern + 1;
1.174 -}
1.175 -
1.176 -static void
1.177 -list_dir(struct razor_set *set, struct razor_entry *dir,
1.178 - const char *pattern, const char *base)
1.179 -{
1.180 - struct razor_entry *e, *end;
1.181 - char *pool = set->string_pool.data;
1.182 -
1.183 - e = (struct razor_entry *) set->file_tree.data + dir->start;
1.184 - end = e + dir->count;
1.185 -
1.186 - for ( ; e < end; e++) {
1.187 - if (base && base[0] && fnmatch(base, &pool[e->name], 0) != 0)
1.188 - continue;
1.189 - if (base && pattern)
1.190 - printf("%.*s%s%s\n",
1.191 - base - pattern, pattern, pool + e->name,
1.192 - e->count > 0 ? "/" : "");
1.193 - else
1.194 - printf("%s%s\n", pool + e->name,
1.195 - e->count > 0 ? "/" : "");
1.196 -
1.197 + packages = set->packages.data;
1.198 + for (i = 0; i < count; i++) {
1.199 + packages[i].files =
1.200 + add_to_property_pool(&set->file_pool, &pkgs[i]);
1.201 + array_release(&pkgs[i]);
1.202 }
1.203 -}
1.204 -
1.205 -void
1.206 -razor_set_list_files(struct razor_set *set, const char *pattern)
1.207 -{
1.208 - struct razor_entry *e;
1.209 - const char *base;
1.210 -
1.211 - if (pattern == NULL)
1.212 - pattern = "/";
1.213 -
1.214 - e = set->file_tree.data;
1.215 - base = find_dir(set, &e, pattern);
1.216 - if (base == NULL)
1.217 - return;
1.218 - list_dir(set, e, pattern, base);
1.219 -}
1.220 -
1.221 -void
1.222 -razor_set_list_file_packages(struct razor_set *set, const char *filename)
1.223 -{
1.224 - struct razor_entry *e;
1.225 - struct razor_package *packages, *p;
1.226 - const char *pool, *base;
1.227 - unsigned long *r;
1.228 -
1.229 - e = set->file_tree.data;
1.230 - base = find_dir(set, &e, filename);
1.231 - if (base == NULL)
1.232 - return;
1.233 -
1.234 - r = (unsigned long *) set->package_pool.data + e->packages;
1.235 - packages = set->packages.data;
1.236 - pool = set->string_pool.data;
1.237 - while (~*r) {
1.238 - p = &packages[*r++];
1.239 - printf("%s %s\n", &pool[p->name], &pool[p->version]);
1.240 - }
1.241 + free(pkgs);
1.242 }
1.243
1.244 struct razor_set *
1.245 @@ -958,6 +905,8 @@
1.246 remap_links(&importer->set->package_pool, rmap);
1.247 free(rmap);
1.248
1.249 + build_package_file_lists(importer->set);
1.250 +
1.251 set = importer->set;
1.252 array_release(&importer->buckets);
1.253 free(importer);
1.254 @@ -1141,6 +1090,167 @@
1.255 razor_set_list_property_packages(set, &set->provides, name, version);
1.256 }
1.257
1.258 +static struct razor_entry *
1.259 +find_entry(struct razor_set *set, struct razor_entry *dir, const char *pattern)
1.260 +{
1.261 + struct razor_entry *e;
1.262 + const char *n, *pool = set->string_pool.data;
1.263 + int len;
1.264 +
1.265 + e = (struct razor_entry *) set->files.data + dir->start;
1.266 + do {
1.267 + n = pool + (e->name & RAZOR_ENTRY_MASK);
1.268 + len = strlen(n);
1.269 + if (len == 0)
1.270 + /* FIXME: Shouldn't have 0-length entries... */
1.271 + continue;
1.272 +
1.273 + if (strcmp(pattern + 1, n) == 0)
1.274 + return e;
1.275 + if (e->start != 0 && strncmp(pattern + 1, n, len) == 0 &&
1.276 + pattern[len + 1] == '/') {
1.277 + return find_entry(set, e, pattern + len + 1);
1.278 + }
1.279 + } while (((e++)->name & RAZOR_ENTRY_LAST) == 0);
1.280 +
1.281 + return NULL;
1.282 +}
1.283 +
1.284 +static void
1.285 +list_dir(struct razor_set *set, struct razor_entry *dir,
1.286 + const char *prefix, const char *pattern)
1.287 +{
1.288 + struct razor_entry *e;
1.289 + const char *n, *pool = set->string_pool.data;
1.290 +
1.291 + e = (struct razor_entry *) set->files.data + dir->start;
1.292 + do {
1.293 + n = pool + (e->name & RAZOR_ENTRY_MASK);
1.294 + if (pattern && pattern[0] && fnmatch(pattern, n, 0) != 0)
1.295 + continue;
1.296 + printf("%s/%s%s\n", prefix, n, e->start > 0 ? "/" : "");
1.297 + } while (((e++)->name & RAZOR_ENTRY_LAST) == 0);
1.298 +}
1.299 +
1.300 +void
1.301 +razor_set_list_files(struct razor_set *set, const char *pattern)
1.302 +{
1.303 + struct razor_entry *e;
1.304 + char buffer[512], *p, *base;
1.305 +
1.306 + if (pattern == NULL)
1.307 + pattern = "/";
1.308 +
1.309 + strcpy(buffer, pattern);
1.310 + e = find_entry(set, set->files.data, buffer);
1.311 + if (e && e->start > 0) {
1.312 + base = NULL;
1.313 + } else {
1.314 + p = strrchr(buffer, '/');
1.315 + if (p) {
1.316 + *p = '\0';
1.317 + base = p + 1;
1.318 + } else {
1.319 + base = NULL;
1.320 + }
1.321 + }
1.322 + e = find_entry(set, set->files.data, buffer);
1.323 + if (e->start != 0)
1.324 + list_dir(set, e, buffer, base);
1.325 +}
1.326 +
1.327 +void
1.328 +razor_set_list_file_packages(struct razor_set *set, const char *filename)
1.329 +{
1.330 + struct razor_entry *e;
1.331 + struct razor_package *packages, *p;
1.332 + const char *pool;
1.333 + unsigned long *r;
1.334 +
1.335 + e = find_entry(set, set->files.data, filename);
1.336 + if (e == NULL)
1.337 + return;
1.338 +
1.339 + r = (unsigned long *) set->package_pool.data + e->packages;
1.340 + packages = set->packages.data;
1.341 + pool = set->string_pool.data;
1.342 + while (~*r) {
1.343 + p = &packages[*r++];
1.344 + printf("%s %s\n", &pool[p->name], &pool[p->version]);
1.345 + }
1.346 +}
1.347 +
1.348 +static unsigned long *
1.349 +list_package_files(struct razor_set *set, unsigned long *r,
1.350 + struct razor_entry *dir, unsigned long end,
1.351 + char *prefix)
1.352 +{
1.353 + struct razor_entry *e, *f, *entries;
1.354 + unsigned long next;
1.355 + char *pool;
1.356 + int len;
1.357 +
1.358 + entries = (struct razor_entry *) set->files.data;
1.359 + pool = set->string_pool.data;
1.360 +
1.361 + e = entries + dir->start;
1.362 + do {
1.363 + if (entries + *r == e) {
1.364 + printf("%s/%s\n", prefix,
1.365 + pool + (e->name & RAZOR_ENTRY_MASK));
1.366 + r++;
1.367 + if (*r >= end)
1.368 + break;
1.369 + }
1.370 + } while (((e++)->name & RAZOR_ENTRY_LAST) == 0);
1.371 +
1.372 + e = entries + dir->start;
1.373 + do {
1.374 + if (e->start == 0)
1.375 + continue;
1.376 +
1.377 + if (e->name & RAZOR_ENTRY_LAST)
1.378 + next = end;
1.379 + else {
1.380 + f = e + 1;
1.381 + while (f->start == 0 && !(f->name & RAZOR_ENTRY_LAST))
1.382 + f++;
1.383 + if (f->start == 0)
1.384 + next = end;
1.385 + else
1.386 + next = f->start;
1.387 + }
1.388 +
1.389 + if (e->start <= *r && *r < next) {
1.390 + len = strlen(prefix);
1.391 + prefix[len] = '/';
1.392 + strcpy(prefix + len + 1,
1.393 + pool + (e->name & RAZOR_ENTRY_MASK));
1.394 + r = list_package_files(set, r, e, next, prefix);
1.395 + prefix[len] = '\0';
1.396 + if (*r >= end)
1.397 + break;
1.398 + }
1.399 + } while (((e++)->name & RAZOR_ENTRY_LAST) == 0);
1.400 +
1.401 + return r;
1.402 +}
1.403 +
1.404 +void
1.405 +razor_set_list_package_files(struct razor_set *set, const char *name)
1.406 +{
1.407 + struct razor_package *package;
1.408 + unsigned long *r, end;
1.409 + char buffer[512];
1.410 +
1.411 + package = razor_set_get_package(set, name);
1.412 +
1.413 + r = (unsigned long *) set->file_pool.data + package->files;
1.414 + end = set->files.size / sizeof (struct razor_entry);
1.415 + buffer[0] = '\0';
1.416 + list_package_files(set, r, set->files.data, end, buffer);
1.417 +}
1.418 +
1.419 static void
1.420 razor_set_validate(struct razor_set *set, struct array *unsatisfied)
1.421 {