Add a file tree section to the package set structure.
1.1 --- a/import.c Sun Oct 21 21:42:31 2007 -0400
1.2 +++ b/import.c Sun Oct 21 21:57:22 2007 -0400
1.3 @@ -163,7 +163,7 @@
1.4 struct yum_context {
1.5 struct razor_importer *importer;
1.6 struct import_property_context *current_property_context;
1.7 - char *name;
1.8 + char name[256], buffer[512], *p;
1.9 int state;
1.10 };
1.11
1.12 @@ -176,6 +176,7 @@
1.13
1.14 if (strcmp(name, "name") == 0) {
1.15 ctx->state = YUM_STATE_PACKAGE_NAME;
1.16 + ctx->p = ctx->name;
1.17 } else if (strcmp(name, "version") == 0) {
1.18 version = NULL;
1.19 for (i = 0; atts[i]; i += 2) {
1.20 @@ -214,6 +215,7 @@
1.21 }
1.22 } else if (strcmp(name, "file") == 0) {
1.23 ctx->state = YUM_STATE_FILE;
1.24 + ctx->p = ctx->buffer;
1.25 }
1.26 }
1.27
1.28 @@ -223,23 +225,24 @@
1.29 struct yum_context *ctx = data;
1.30
1.31 ctx->state = YUM_STATE_BEGIN;
1.32 - if (strcmp(name, "package") == 0) {
1.33 - free(ctx->name);
1.34 + if (strcmp(name, "package") == 0)
1.35 razor_importer_finish_package(ctx->importer);
1.36 - }
1.37 + else if (strcmp(name, "file") == 0)
1.38 + razor_importer_add_file(ctx->importer, ctx->buffer);
1.39 }
1.40
1.41 static void
1.42 yum_character_data (void *data, const XML_Char *s, int len)
1.43 {
1.44 struct yum_context *ctx = data;
1.45 - char filename[PATH_MAX];
1.46
1.47 - if (ctx->state == YUM_STATE_PACKAGE_NAME)
1.48 - ctx->name = strndup(s, len);
1.49 - else if (ctx->state == YUM_STATE_FILE) {
1.50 - snprintf(filename, sizeof filename, "%.*s", len, s);
1.51 - razor_importer_add_file(ctx->importer, filename);
1.52 + switch (ctx->state) {
1.53 + case YUM_STATE_PACKAGE_NAME:
1.54 + case YUM_STATE_FILE:
1.55 + memcpy(ctx->p, s, len);
1.56 + ctx->p += len;
1.57 + *ctx->p = '\0';
1.58 + break;
1.59 }
1.60 }
1.61
2.1 --- a/main.c Sun Oct 21 21:42:31 2007 -0400
2.2 +++ b/main.c Sun Oct 21 21:57:22 2007 -0400
2.3 @@ -47,6 +47,20 @@
2.4 }
2.5
2.6 static int
2.7 +command_list_files(int argc, const char *argv[])
2.8 +{
2.9 + struct razor_set *set;
2.10 +
2.11 + set = razor_set_open(repo_filename);
2.12 + if (set == NULL)
2.13 + return 1;
2.14 + razor_set_list_files(set);
2.15 + razor_set_destroy(set);
2.16 +
2.17 + return 0;
2.18 +}
2.19 +
2.20 +static int
2.21 command_what_requires(int argc, const char *argv[])
2.22 {
2.23 struct razor_set *set;
2.24 @@ -168,6 +182,7 @@
2.25 { "list", "list all packages", command_list },
2.26 { "list-requires", "list all requires or requires for the given package", command_list_requires },
2.27 { "list-provides", "list all provides or provides for the give package", command_list_provides },
2.28 + { "list-files", "list files for package set", command_list_files },
2.29 { "what-requires", "list the packages that have the given requires", command_what_requires },
2.30 { "what-provides", "list the packages that have the given provides", command_what_provides },
2.31 { "import-yum", "import yum filelist.xml on stdin", command_import_yum },
3.1 --- a/razor.c Sun Oct 21 21:42:31 2007 -0400
3.2 +++ b/razor.c Sun Oct 21 21:57:22 2007 -0400
3.3 @@ -41,6 +41,7 @@
3.4 #define RAZOR_PACKAGE_POOL 4
3.5 #define RAZOR_REQUIRES_POOL 5
3.6 #define RAZOR_PROVIDES_POOL 6
3.7 +#define RAZOR_FILE_TREE 7
3.8
3.9 struct razor_package {
3.10 unsigned long name;
3.11 @@ -55,6 +56,12 @@
3.12 unsigned long packages;
3.13 };
3.14
3.15 +struct razor_entry {
3.16 + unsigned long name;
3.17 + unsigned long count;
3.18 + unsigned long start;
3.19 +};
3.20 +
3.21 struct razor_set {
3.22 struct array string_pool;
3.23 struct array packages;
3.24 @@ -63,6 +70,7 @@
3.25 struct array provides;
3.26 struct array requires_pool;
3.27 struct array provides_pool;
3.28 + struct array file_tree;
3.29 struct razor_set_header *header;
3.30 };
3.31
3.32 @@ -77,6 +85,7 @@
3.33 struct import_property_context requires;
3.34 struct import_property_context provides;
3.35 struct razor_package *package;
3.36 + struct array files;
3.37 };
3.38
3.39 static void
3.40 @@ -154,6 +163,7 @@
3.41 { RAZOR_PACKAGE_POOL, offsetof(struct razor_set, package_pool) },
3.42 { RAZOR_REQUIRES_POOL, offsetof(struct razor_set, requires_pool) },
3.43 { RAZOR_PROVIDES_POOL, offsetof(struct razor_set, provides_pool) },
3.44 + { RAZOR_FILE_TREE, offsetof(struct razor_set, file_tree) },
3.45 };
3.46
3.47 struct razor_set *
3.48 @@ -453,6 +463,10 @@
3.49 void
3.50 razor_importer_add_file(struct razor_importer *importer, const char *name)
3.51 {
3.52 + char **p;
3.53 +
3.54 + p = array_add(&importer->files, sizeof *p);
3.55 + *p = strdup(name);
3.56 }
3.57
3.58 struct razor_importer *
3.59 @@ -682,6 +696,147 @@
3.60 *p = map[*p];
3.61 }
3.62
3.63 +static int
3.64 +compare_filenames(const void *p1, const void *p2, void *data)
3.65 +{
3.66 + char *f1 = *(char **) p1;
3.67 + char *f2 = *(char **) p2;
3.68 +
3.69 + return strcmp(f1, f2);
3.70 +}
3.71 +
3.72 +struct directory {
3.73 + unsigned long name, count;
3.74 + struct array files;
3.75 + struct directory *last;
3.76 +};
3.77 +
3.78 +static void
3.79 +count_entries(struct directory *d)
3.80 +{
3.81 + struct directory *p, *end;
3.82 +
3.83 + p = d->files.data;
3.84 + end = d->files.data + d->files.size;
3.85 + d->count = 0;
3.86 + while (p < end) {
3.87 + count_entries(p);
3.88 + d->count += p->count + 1;
3.89 + p++;
3.90 + }
3.91 +}
3.92 +
3.93 +static void
3.94 +serialize_files(struct directory *d, struct array *array)
3.95 +{
3.96 + struct directory *p, *end;
3.97 + struct razor_entry *e;
3.98 + unsigned long s;
3.99 +
3.100 + p = d->files.data;
3.101 + end = d->files.data + d->files.size;
3.102 + s = array->size / sizeof *e + d->files.size / sizeof *p;
3.103 + while (p < end) {
3.104 + e = array_add(array, sizeof *e);
3.105 + e->name = p->name;
3.106 + e->count = p->files.size / sizeof *p;
3.107 + e->start = s;
3.108 + s += p->count;
3.109 + p++;
3.110 + }
3.111 +
3.112 + p = d->files.data;
3.113 + end = d->files.data + d->files.size;
3.114 + while (p < end) {
3.115 + serialize_files(p, array);
3.116 + p++;
3.117 + }
3.118 +}
3.119 +
3.120 +static void
3.121 +build_file_tree(struct razor_importer *importer)
3.122 +{
3.123 + int count, i, length;
3.124 + char **filenames, *f, *end;
3.125 + unsigned long name;
3.126 + char dirname[256];
3.127 + struct directory *d, root;
3.128 + struct razor_entry *e;
3.129 +
3.130 + count = importer->files.size / sizeof (char *);
3.131 + qsort_with_data(importer->files.data,
3.132 + count,
3.133 + sizeof (char *),
3.134 + compare_filenames,
3.135 + NULL);
3.136 +
3.137 + root.name = razor_importer_tokenize(importer, "");
3.138 + array_init(&root.files);
3.139 + root.last = NULL;
3.140 +
3.141 + filenames = importer->files.data;
3.142 + for (i = 0; i < count; i++) {
3.143 + f = filenames[i];
3.144 + if (*f != '/')
3.145 + continue;
3.146 +
3.147 + d = &root;
3.148 + while (*f) {
3.149 + end = strchr(f + 1, '/');
3.150 + if (end == NULL)
3.151 + end = f + strlen(f);
3.152 + length = end - (f + 1);
3.153 + memcpy(dirname, f + 1, length);
3.154 + dirname[length] ='\0';
3.155 + name = razor_importer_tokenize(importer, dirname);
3.156 + if (d->last == NULL || d->last->name != name) {
3.157 + d->last = array_add(&d->files, sizeof *d);
3.158 + d->last->name = name;
3.159 + d->last->last = NULL;
3.160 + array_init(&d->last->files);
3.161 + }
3.162 + d = d->last;
3.163 + f = end;
3.164 + }
3.165 +
3.166 + free(filenames[i]);
3.167 + }
3.168 +
3.169 + count_entries(&root);
3.170 + array_init(&importer->set->file_tree);
3.171 +
3.172 + e = array_add(&importer->set->file_tree, sizeof *e);
3.173 + e->name = root.name;
3.174 + e->count = root.files.size / sizeof *d;
3.175 + e->start = 1;
3.176 +
3.177 + serialize_files(&root, &importer->set->file_tree);
3.178 +
3.179 + array_release(&importer->files);
3.180 +}
3.181 +
3.182 +static void
3.183 +list_dir(struct razor_set *set, struct razor_entry *e, int indent)
3.184 +{
3.185 + struct razor_entry *c;
3.186 + char *pool = set->string_pool.data;
3.187 + int i;
3.188 +
3.189 + for (i = 0; i < indent; i++)
3.190 + putchar(' ');
3.191 + printf("%s\n", pool + e->name);
3.192 + for (i = 0; i < e->count; i++) {
3.193 + c = (struct razor_entry *) set->file_tree.data + e->start + i;
3.194 + list_dir(set, c, indent + 2);
3.195 + }
3.196 +}
3.197 +
3.198 +void
3.199 +razor_set_list_files(struct razor_set *set)
3.200 +{
3.201 + list_dir(set, set->file_tree.data, 2);
3.202 +}
3.203 +
3.204 struct razor_set *
3.205 razor_importer_finish(struct razor_importer *importer)
3.206 {
3.207 @@ -712,6 +867,8 @@
3.208 free(map);
3.209 free(rmap);
3.210
3.211 + build_file_tree(importer);
3.212 +
3.213 set = importer->set;
3.214 array_release(&importer->buckets);
3.215 free(importer);
4.1 --- a/razor.h Sun Oct 21 21:42:31 2007 -0400
4.2 +++ b/razor.h Sun Oct 21 21:57:22 2007 -0400
4.3 @@ -18,6 +18,7 @@
4.4 void razor_set_list_provides_packages(struct razor_set *set,
4.5 const char *name,
4.6 const char *version);
4.7 +void razor_set_list_files(struct razor_set *set);
4.8
4.9 void razor_set_list_unsatisfied(struct razor_set *set);
4.10 struct razor_set *razor_set_update(struct razor_set *set,