summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO6
-rw-r--r--bash-completion.sh5
-rw-r--r--main.c14
-rw-r--r--razor.c310
-rw-r--r--razor.h1
5 files changed, 234 insertions, 102 deletions
diff --git a/TODO b/TODO
index b29ac63..eea05b0 100644
--- a/TODO
+++ b/TODO
@@ -47,3 +47,9 @@
- split out hash table code from importer, make the merger use just
the hash table.
+
+- try to clean up the
+
+ do { ... } while (((e++)->name & RAZOR_ENTRY_LAST) == 0);
+
+ idiom for iteration of directories.
diff --git a/bash-completion.sh b/bash-completion.sh
index b0b0ce8..782f3e9 100644
--- a/bash-completion.sh
+++ b/bash-completion.sh
@@ -1,6 +1,6 @@
__razor_commands () {
local IFS=$'\n'
- COMPREPLY=($(IFS=: compgen -S' ' -W "list-requires:list-provides:list-files:list-file-packages:what-requires:what-provides:import-yum:import-rpmdb:validate:update:diff" -- $1))
+ COMPREPLY=($(IFS=: compgen -S' ' -W "list-requires:list-provides:list-files:list-file-packages:list-package-files:what-requires:what-provides:import-yum:import-rpmdb:validate:update:diff" -- $1))
}
__razor_packages () {
@@ -28,7 +28,8 @@ __razor() {
__razor_commands $cur
else
case "${COMP_WORDS[1]}" in
- list-requires|list-provides) __razor_packages $cur ;;
+ list-requires|list-provides|list-package-files)
+ __razor_packages $cur ;;
list-files|list-file-packages) __razor_files $cur ;;
what-requires) __razor_requires $cur ;;
what-provides) __razor_provides $cur ;;
diff --git a/main.c b/main.c
index eb0c177..48db52e 100644
--- a/main.c
+++ b/main.c
@@ -74,6 +74,19 @@ command_list_file_packages(int argc, const char *argv[])
return 0;
}
+static int
+command_list_package_files(int argc, const char *argv[])
+{
+ struct razor_set *set;
+
+ set = razor_set_open(repo_filename);
+ if (set == NULL)
+ return 1;
+ razor_set_list_package_files(set, argv[0]);
+ razor_set_destroy(set);
+
+ return 0;
+}
static int
command_what_requires(int argc, const char *argv[])
@@ -199,6 +212,7 @@ static struct {
{ "list-provides", "list all provides or provides for the give package", command_list_provides },
{ "list-files", "list files for package set", command_list_files },
{ "list-file-packages", "list packages owning file", command_list_file_packages },
+ { "list-package-files", "list files in package", command_list_package_files },
{ "what-requires", "list the packages that have the given requires", command_what_requires },
{ "what-provides", "list the packages that have the given provides", command_what_provides },
{ "import-yum", "import yum filelist.xml on stdin", command_import_yum },
diff --git a/razor.c b/razor.c
index b6b83c0..dfc567e 100644
--- a/razor.c
+++ b/razor.c
@@ -35,20 +35,22 @@ struct razor_set_header {
#define RAZOR_MAGIC 0x7a7a7a7a
#define RAZOR_VERSION 1
-#define RAZOR_PACKAGES 0
-#define RAZOR_REQUIRES 1
-#define RAZOR_PROVIDES 2
-#define RAZOR_STRING_POOL 3
-#define RAZOR_PACKAGE_POOL 4
-#define RAZOR_REQUIRES_POOL 5
-#define RAZOR_PROVIDES_POOL 6
-#define RAZOR_FILE_TREE 7
+#define RAZOR_STRING_POOL 0
+#define RAZOR_PACKAGES 1
+#define RAZOR_REQUIRES 2
+#define RAZOR_PROVIDES 3
+#define RAZOR_FILES 4
+#define RAZOR_PACKAGE_POOL 5
+#define RAZOR_REQUIRES_POOL 6
+#define RAZOR_PROVIDES_POOL 7
+#define RAZOR_FILE_POOL 8
struct razor_package {
unsigned long name;
unsigned long version;
unsigned long requires;
unsigned long provides;
+ unsigned long files;
};
struct razor_property {
@@ -59,7 +61,6 @@ struct razor_property {
struct razor_entry {
unsigned long name;
- unsigned long count;
unsigned long start;
unsigned long packages;
};
@@ -67,12 +68,13 @@ struct razor_entry {
struct razor_set {
struct array string_pool;
struct array packages;
- struct array package_pool;
struct array requires;
struct array provides;
+ struct array files;
+ struct array package_pool;
struct array requires_pool;
struct array provides_pool;
- struct array file_tree;
+ struct array file_pool;
struct razor_set_header *header;
};
@@ -170,14 +172,15 @@ zalloc(size_t size)
}
struct razor_set_section razor_sections[] = {
+ { RAZOR_STRING_POOL, offsetof(struct razor_set, string_pool) },
{ RAZOR_PACKAGES, offsetof(struct razor_set, packages) },
{ RAZOR_REQUIRES, offsetof(struct razor_set, requires) },
{ RAZOR_PROVIDES, offsetof(struct razor_set, provides) },
- { RAZOR_STRING_POOL, offsetof(struct razor_set, string_pool) },
+ { RAZOR_FILES, offsetof(struct razor_set, files) },
{ RAZOR_PACKAGE_POOL, offsetof(struct razor_set, package_pool) },
{ RAZOR_REQUIRES_POOL, offsetof(struct razor_set, requires_pool) },
{ RAZOR_PROVIDES_POOL, offsetof(struct razor_set, provides_pool) },
- { RAZOR_FILE_TREE, offsetof(struct razor_set, file_tree) },
+ { RAZOR_FILE_POOL, offsetof(struct razor_set, file_pool) },
};
struct razor_set *
@@ -737,12 +740,15 @@ count_entries(struct import_directory *d)
}
}
+#define RAZOR_ENTRY_LAST 0x80000000ul
+#define RAZOR_ENTRY_MASK 0x00fffffful
+
static void
serialize_files(struct razor_set *set,
struct import_directory *d, struct array *array)
{
struct import_directory *p, *end;
- struct razor_entry *e;
+ struct razor_entry *e = NULL;
unsigned long s;
p = d->files.data;
@@ -751,14 +757,15 @@ serialize_files(struct razor_set *set,
while (p < end) {
e = array_add(array, sizeof *e);
e->name = p->name;
- e->count = p->files.size / sizeof *p;
- e->start = s;
+ e->start = p->count > 0 ? s : 0;
s += p->count;
e->packages = add_to_property_pool(&set->package_pool,
&p->packages);
array_release(&p->packages);
p++;
}
+ if (e != NULL)
+ e->name |= RAZOR_ENTRY_LAST;
p = d->files.data;
end = d->files.data + d->files.size;
@@ -823,108 +830,48 @@ build_file_tree(struct razor_importer *importer)
}
count_entries(&root);
- array_init(&importer->set->file_tree);
+ array_init(&importer->set->files);
- e = array_add(&importer->set->file_tree, sizeof *e);
- e->name = root.name;
- e->count = root.files.size / sizeof *d;
+ e = array_add(&importer->set->files, sizeof *e);
+ e->name = root.name | RAZOR_ENTRY_LAST;
e->start = 1;
+ e->packages = 0;
- serialize_files(importer->set, &root, &importer->set->file_tree);
+ serialize_files(importer->set, &root, &importer->set->files);
array_release(&importer->files);
}
-static const char *
-find_dir(struct razor_set *set, struct razor_entry **dir, const char *pattern)
+static void
+build_package_file_lists(struct razor_set *set)
{
+ struct razor_package *p, *packages;
+ struct array *pkgs;
struct razor_entry *e, *end;
- const char *n, *pool = set->string_pool.data;
- int len;
+ unsigned long *r, *q;
+ int i, count;
- e = (struct razor_entry *) set->file_tree.data + (*dir)->start;
- end = e + (*dir)->count;
+ count = set->packages.size / sizeof *p;
+ pkgs = zalloc(count * sizeof *pkgs);
+ e = set->files.data;
+ end = set->files.data + set->files.size;
while (e < end) {
- n = pool + e->name;
- len = strlen(n);
- if (len == 0) {
- /* FIXME: Shouldn't have 0-length entries... */
- e++;
- continue;
- }
-
- if (strncmp(pattern + 1, n, len) == 0 &&
- pattern[len + 1] == '/') {
- *dir = e;
- return find_dir(set, dir, pattern + len + 1);
+ r = (unsigned long *) set->package_pool.data + e->packages;
+ while (~*r) {
+ q = array_add(&pkgs[*r++], sizeof *q);
+ *q = e - (struct razor_entry *) set->files.data;
}
e++;
}
- return pattern + 1;
-}
-
-static void
-list_dir(struct razor_set *set, struct razor_entry *dir,
- const char *pattern, const char *base)
-{
- struct razor_entry *e, *end;
- char *pool = set->string_pool.data;
-
- e = (struct razor_entry *) set->file_tree.data + dir->start;
- end = e + dir->count;
-
- for ( ; e < end; e++) {
- if (base && base[0] && fnmatch(base, &pool[e->name], 0) != 0)
- continue;
- if (base && pattern)
- printf("%.*s%s%s\n",
- base - pattern, pattern, pool + e->name,
- e->count > 0 ? "/" : "");
- else
- printf("%s%s\n", pool + e->name,
- e->count > 0 ? "/" : "");
-
- }
-}
-
-void
-razor_set_list_files(struct razor_set *set, const char *pattern)
-{
- struct razor_entry *e;
- const char *base;
-
- if (pattern == NULL)
- pattern = "/";
-
- e = set->file_tree.data;
- base = find_dir(set, &e, pattern);
- if (base == NULL)
- return;
- list_dir(set, e, pattern, base);
-}
-
-void
-razor_set_list_file_packages(struct razor_set *set, const char *filename)
-{
- struct razor_entry *e;
- struct razor_package *packages, *p;
- const char *pool, *base;
- unsigned long *r;
-
- e = set->file_tree.data;
- base = find_dir(set, &e, filename);
- if (base == NULL)
- return;
-
- r = (unsigned long *) set->package_pool.data + e->packages;
packages = set->packages.data;
- pool = set->string_pool.data;
- while (~*r) {
- p = &packages[*r++];
- printf("%s %s\n", &pool[p->name], &pool[p->version]);
+ for (i = 0; i < count; i++) {
+ packages[i].files =
+ add_to_property_pool(&set->file_pool, &pkgs[i]);
+ array_release(&pkgs[i]);
}
+ free(pkgs);
}
struct razor_set *
@@ -958,6 +905,8 @@ razor_importer_finish(struct razor_importer *importer)
remap_links(&importer->set->package_pool, rmap);
free(rmap);
+ build_package_file_lists(importer->set);
+
set = importer->set;
array_release(&importer->buckets);
free(importer);
@@ -1141,6 +1090,167 @@ razor_set_list_provides_packages(struct razor_set *set,
razor_set_list_property_packages(set, &set->provides, name, version);
}
+static struct razor_entry *
+find_entry(struct razor_set *set, struct razor_entry *dir, const char *pattern)
+{
+ struct razor_entry *e;
+ const char *n, *pool = set->string_pool.data;
+ int len;
+
+ e = (struct razor_entry *) set->files.data + dir->start;
+ do {
+ n = pool + (e->name & RAZOR_ENTRY_MASK);
+ len = strlen(n);
+ if (len == 0)
+ /* FIXME: Shouldn't have 0-length entries... */
+ continue;
+
+ if (strcmp(pattern + 1, n) == 0)
+ return e;
+ if (e->start != 0 && strncmp(pattern + 1, n, len) == 0 &&
+ pattern[len + 1] == '/') {
+ return find_entry(set, e, pattern + len + 1);
+ }
+ } while (((e++)->name & RAZOR_ENTRY_LAST) == 0);
+
+ return NULL;
+}
+
+static void
+list_dir(struct razor_set *set, struct razor_entry *dir,
+ const char *prefix, const char *pattern)
+{
+ struct razor_entry *e;
+ const char *n, *pool = set->string_pool.data;
+
+ e = (struct razor_entry *) set->files.data + dir->start;
+ do {
+ n = pool + (e->name & RAZOR_ENTRY_MASK);
+ if (pattern && pattern[0] && fnmatch(pattern, n, 0) != 0)
+ continue;
+ printf("%s/%s%s\n", prefix, n, e->start > 0 ? "/" : "");
+ } while (((e++)->name & RAZOR_ENTRY_LAST) == 0);
+}
+
+void
+razor_set_list_files(struct razor_set *set, const char *pattern)
+{
+ struct razor_entry *e;
+ char buffer[512], *p, *base;
+
+ if (pattern == NULL)
+ pattern = "/";
+
+ strcpy(buffer, pattern);
+ e = find_entry(set, set->files.data, buffer);
+ if (e && e->start > 0) {
+ base = NULL;
+ } else {
+ p = strrchr(buffer, '/');
+ if (p) {
+ *p = '\0';
+ base = p + 1;
+ } else {
+ base = NULL;
+ }
+ }
+ e = find_entry(set, set->files.data, buffer);
+ if (e->start != 0)
+ list_dir(set, e, buffer, base);
+}
+
+void
+razor_set_list_file_packages(struct razor_set *set, const char *filename)
+{
+ struct razor_entry *e;
+ struct razor_package *packages, *p;
+ const char *pool;
+ unsigned long *r;
+
+ e = find_entry(set, set->files.data, filename);
+ if (e == NULL)
+ return;
+
+ r = (unsigned long *) set->package_pool.data + e->packages;
+ packages = set->packages.data;
+ pool = set->string_pool.data;
+ while (~*r) {
+ p = &packages[*r++];
+ printf("%s %s\n", &pool[p->name], &pool[p->version]);
+ }
+}
+
+static unsigned long *
+list_package_files(struct razor_set *set, unsigned long *r,
+ struct razor_entry *dir, unsigned long end,
+ char *prefix)
+{
+ struct razor_entry *e, *f, *entries;
+ unsigned long next;
+ char *pool;
+ int len;
+
+ entries = (struct razor_entry *) set->files.data;
+ pool = set->string_pool.data;
+
+ e = entries + dir->start;
+ do {
+ if (entries + *r == e) {
+ printf("%s/%s\n", prefix,
+ pool + (e->name & RAZOR_ENTRY_MASK));
+ r++;
+ if (*r >= end)
+ break;
+ }
+ } while (((e++)->name & RAZOR_ENTRY_LAST) == 0);
+
+ e = entries + dir->start;
+ do {
+ if (e->start == 0)
+ continue;
+
+ if (e->name & RAZOR_ENTRY_LAST)
+ next = end;
+ else {
+ f = e + 1;
+ while (f->start == 0 && !(f->name & RAZOR_ENTRY_LAST))
+ f++;
+ if (f->start == 0)
+ next = end;
+ else
+ next = f->start;
+ }
+
+ if (e->start <= *r && *r < next) {
+ len = strlen(prefix);
+ prefix[len] = '/';
+ strcpy(prefix + len + 1,
+ pool + (e->name & RAZOR_ENTRY_MASK));
+ r = list_package_files(set, r, e, next, prefix);
+ prefix[len] = '\0';
+ if (*r >= end)
+ break;
+ }
+ } while (((e++)->name & RAZOR_ENTRY_LAST) == 0);
+
+ return r;
+}
+
+void
+razor_set_list_package_files(struct razor_set *set, const char *name)
+{
+ struct razor_package *package;
+ unsigned long *r, end;
+ char buffer[512];
+
+ package = razor_set_get_package(set, name);
+
+ r = (unsigned long *) set->file_pool.data + package->files;
+ end = set->files.size / sizeof (struct razor_entry);
+ buffer[0] = '\0';
+ list_package_files(set, r, set->files.data, end, buffer);
+}
+
static void
razor_set_validate(struct razor_set *set, struct array *unsatisfied)
{
diff --git a/razor.h b/razor.h
index 09e98f9..4fbafa9 100644
--- a/razor.h
+++ b/razor.h
@@ -20,6 +20,7 @@ void razor_set_list_provides_packages(struct razor_set *set,
const char *version);
void razor_set_list_files(struct razor_set *set, const char *prefix);
void razor_set_list_file_packages(struct razor_set *set, const char *filename);
+void razor_set_list_package_files(struct razor_set *set, const char *name);
void razor_set_list_unsatisfied(struct razor_set *set);
struct razor_set *razor_set_update(struct razor_set *set,