test-driver : razor.o util.o test-driver.o
test : test-driver
- ./test-driver sets.xml test.xml
+ ./test-driver test.xml
clean :
rm -f *.o razor
command_list(int argc, const char *argv[])
{
struct razor_set *set;
+ struct razor_package_iterator *pi;
+ struct razor_package *package;
+ const char *pattern = argv[0], *name, *version;
set = razor_set_open(repo_filename);
- razor_set_list(set, argv[0]);
+ pi = razor_package_iterator_create(set);
+ while (razor_package_iterator_next(pi, &package, &name, &version)) {
+ if (pattern && fnmatch(pattern, name, 0) != 0)
+ continue;
+
+ printf("%s-%s\n", name, version);
+ }
+ razor_package_iterator_destroy(pi);
razor_set_destroy(set);
return 0;
}
static int
-command_list_requires(int argc, const char *argv[])
+list_properties(const char *package_name,
+ enum razor_property_type required_type)
{
struct razor_set *set;
+ struct razor_property *property;
+ struct razor_package *package;
+ struct razor_property_iterator *pi;
+ const char *name, *version;
+ enum razor_property_type type;
set = razor_set_open(repo_filename);
- razor_set_list_properties(set, argv[0], RAZOR_PROPERTY_REQUIRES);
+ if (package_name)
+ package = razor_set_get_package(set, package_name);
+ else
+ package = NULL;
+
+ pi = razor_property_iterator_create(set, package);
+ while (razor_property_iterator_next(pi, &property,
+ &name, &version, &type)) {
+ if (type != required_type)
+ continue;
+ if (version[0] == '\0')
+ printf("%s\n", name);
+ else
+ printf("%s-%s\n", name, version);
+ }
+ razor_property_iterator_destroy(pi);
+
razor_set_destroy(set);
return 0;
}
static int
-command_list_provides(int argc, const char *argv[])
+command_list_requires(int argc, const char *argv[])
{
- struct razor_set *set;
-
- set = razor_set_open(repo_filename);
- razor_set_list_properties(set, argv[0], RAZOR_PROPERTY_PROVIDES);
- razor_set_destroy(set);
+ return list_properties(argv[0], RAZOR_PROPERTY_REQUIRES);
+}
- return 0;
+static int
+command_list_provides(int argc, const char *argv[])
+{
+ return list_properties(argv[0], RAZOR_PROPERTY_PROVIDES);
}
static int
command_list_obsoletes(int argc, const char *argv[])
{
- struct razor_set *set;
-
- set = razor_set_open(repo_filename);
- razor_set_list_properties(set, argv[0], RAZOR_PROPERTY_OBSOLETES);
- razor_set_destroy(set);
-
- return 0;
+ return list_properties(argv[0], RAZOR_PROPERTY_OBSOLETES);
}
static int
command_list_conflicts(int argc, const char *argv[])
{
- struct razor_set *set;
-
- set = razor_set_open(repo_filename);
- razor_set_list_properties(set, argv[0], RAZOR_PROPERTY_CONFLICTS);
- razor_set_destroy(set);
-
- return 0;
+ return list_properties(argv[0], RAZOR_PROPERTY_CONFLICTS);
}
static int
static unsigned long
add_to_property_pool(struct array *pool, struct array *properties)
{
- unsigned long *p;
+ unsigned long *p;
+
+ if (properties->size == 0)
+ return ~0;
+ else if (properties->size == sizeof *p)
+ return *(unsigned long *) properties->data | RAZOR_IMMEDIATE;
p = array_add(pool, properties->size);
memcpy(p, properties->data, properties->size);
s += p->count;
if (p->packages.size == 0) {
- /* FIXME: We need to make sure this is handled
- * correctly as the empty list. */
- e->packages = 0 | RAZOR_IMMEDIATE;
+ e->packages = ~0;
} else if (p->packages.size / sizeof *r == 1) {
r = p->packages.data;
e->packages = *r | RAZOR_IMMEDIATE;
e = array_add(&importer->set->files, sizeof *e);
e->name = root.name | RAZOR_ENTRY_LAST;
e->start = 1;
- e->packages = 0;
+ e->packages = ~0;
serialize_files(importer->set, &root, &importer->set->files);
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) {
- if (e->packages & RAZOR_IMMEDIATE) {
+ for (e = set->files.data; e < end; e++) {
+ if (e->packages == ~0) {
+ continue;
+ } else if (e->packages & RAZOR_IMMEDIATE) {
e->packages = rmap[e->packages & RAZOR_ENTRY_MASK] |
RAZOR_IMMEDIATE;
r = &e->packages;
if (*r++ & RAZOR_IMMEDIATE)
break;
}
- e++;
}
packages = set->packages.data;
return set;
}
-void
-razor_set_list(struct razor_set *set, const char *pattern)
+struct razor_package_iterator {
+ struct razor_set *set;
+ struct razor_package *package, *end;
+};
+
+struct razor_package_iterator *
+razor_package_iterator_create(struct razor_set *set)
+{
+ struct razor_package_iterator *pi;
+
+ pi = zalloc(sizeof *pi);
+ pi->set = set;
+ pi->package = set->packages.data;
+ pi->end = set->packages.data + set->packages.size;
+
+ return pi;
+}
+
+int
+razor_package_iterator_next(struct razor_package_iterator *pi,
+ struct razor_package **package,
+ const char **name, const char **version)
{
- struct razor_package *p, *end;
- int with_version = 0;
char *pool;
- pool = set->string_pool.data;
- end = set->packages.data + set->packages.size;
- for (p = set->packages.data; p < end; p++) {
- if (pattern && fnmatch(pattern, &pool[p->name], 0) != 0)
- continue;
- if (with_version)
- printf("%s-%s\n", &pool[p->name], &pool[p->version]);
- else
- printf("%s\n", &pool[p->name]);
- }
+ pool = pi->set->string_pool.data;
+ *package = pi->package;
+ *name = &pool[pi->package->name];
+ *version = &pool[pi->package->version];
+
+ return pi->package++ < pi->end;
+}
+
+void
+razor_package_iterator_destroy(struct razor_package_iterator *pi)
+{
+ free(pi);
}
struct razor_set *bsearch_set;
return p;
}
-void
-razor_set_list_properties(struct razor_set *set, const char *name,
- enum razor_property_type type)
-{
- struct razor_property *p, *properties, *end;
- struct razor_package *package;
- unsigned long *r;
- char *pool;
+struct razor_property_iterator {
+ struct razor_set *set;
+ struct razor_property *property, *end;
+ unsigned long *index;
+ int last;
+};
- pool = set->string_pool.data;
+struct razor_property_iterator *
+razor_property_iterator_create(struct razor_set *set,
+ struct razor_package *package)
+{
+ struct razor_property_iterator *pi;
- if (name) {
- package = razor_set_get_package(set, name);
- r = (unsigned long *) set->property_pool.data +
- package->properties;
- properties = set->properties.data;
- while (1) {
- p = &properties[*r & RAZOR_ENTRY_MASK];
- if ((p->name >> 30) != type)
- goto next;
- if (pool[p->version] == '\0')
- printf("%s\n",
- &pool[p->name & RAZOR_ENTRY_MASK]);
- else
- printf("%s-%s\n",
- &pool[p->name & RAZOR_ENTRY_MASK],
- &pool[p->version]);
- next:
- if (*r++ & RAZOR_IMMEDIATE)
- break;
- }
+ pi = zalloc(sizeof *pi);
+ pi->set = set;
+ pi->property = set->properties.data;
+ pi->end = set->properties.data + set->properties.size;
+ if (package) {
+ pi->index = (unsigned long *)
+ set->property_pool.data + package->properties;
+ pi->last = 0;
} else {
- end = set->properties.data + set->properties.size;
- for (p = set->properties.data; p < end; p++) {
- if ((p->name >> 30) != type)
- continue;
- if (pool[p->version] == '\0')
- printf("%s\n",
- &pool[p->name & RAZOR_ENTRY_MASK]);
- else
- printf("%s-%s\n",
- &pool[p->name & RAZOR_ENTRY_MASK],
- &pool[p->version]);
- }
+ pi->index = NULL;
+ pi->last = 0;
}
+
+ return pi;
+}
+
+int
+razor_property_iterator_next(struct razor_property_iterator *pi,
+ struct razor_property **property,
+ const char **name, const char **version,
+ enum razor_property_type *type)
+{
+ char *pool;
+ unsigned long flags, index;
+ int valid;
+ struct razor_property *p, *properties;
+
+ if (pi->index) {
+ properties = pi->set->properties.data;
+ p = &properties[*pi->index & RAZOR_ENTRY_MASK];
+ valid = !pi->last;
+ pi->last = (*pi->index++ & RAZOR_IMMEDIATE) != 0;
+ if (!valid)
+ return valid;
+ } else {
+ p = pi->property++;
+ valid = p < pi->end;
+ }
+
+ pool = pi->set->string_pool.data;
+ *property = p;
+ *name = &pool[p->name & RAZOR_ENTRY_MASK];
+ *version = &pool[p->version];
+ *type = p->name >> 30;
+
+ return valid;
+}
+
+void
+razor_property_iterator_destroy(struct razor_property_iterator *pi)
+{
+ free(pi);
}
void
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
struct razor_set;
+struct razor_package;
+struct razor_property;
enum razor_property_type {
RAZOR_PROPERTY_REQUIRES,
void razor_set_destroy(struct razor_set *set);
int razor_set_write(struct razor_set *set, const char *filename);
-void razor_set_list(struct razor_set *set, const char *pattern);
+struct razor_package *
+razor_set_get_package(struct razor_set *set, const char *package);
+
+struct razor_property *
+razor_set_get_property(struct razor_set *set, const char *property);
+
+struct razor_package_iterator;
+struct razor_package_iterator *
+razor_package_iterator_create(struct razor_set *set);
+
+int razor_package_iterator_next(struct razor_package_iterator *pi,
+ struct razor_package **package,
+ const char **name, const char **version);
+void razor_package_iterator_destroy(struct razor_package_iterator *pi);
+
+struct razor_property_iterator;
+struct razor_property_iterator *
+razor_property_iterator_create(struct razor_set *set,
+ struct razor_package *package);
+int razor_property_iterator_next(struct razor_property_iterator *pi,
+ struct razor_property **property,
+ const char **name, const char **version,
+ enum razor_property_type *type);
+void
+razor_property_iterator_destroy(struct razor_property_iterator *pi);
+
+
void razor_set_list_properties(struct razor_set *set, const char *name,
enum razor_property_type type);
void razor_set_list_property_packages(struct razor_set *set,
<test-sets>
+
<set name="b">
<package name="bash" version="3.2-18.fc8">
<requires name="libc.so.6"/>
<file name="/bin/bash"/>
</package>
</set>
+
+ <set name="c">
+ <package name="nss" version="1.8-fc10">
+ <provides name="nss" eq="1.8-fc10"/>
+ <file name="/bin/nss"/>
+ </package>
+
+ <package name="x" version="2">
+ <conflicts name="y" eq="1.1"/>
+ </package>
+ </set>
+
</test-sets>
fd = open(filename, O_RDONLY);
if (fd < 0) {
- fprintf(stderr, "open: %m\n");
+ fprintf(stderr, "failed to open %s: %m\n", filename);
exit(-1);
}
struct test_context {
struct razor_importer *importer;
struct test_set *sets;
+ struct razor_package_iterator *package_iterator;
+ struct razor_property_iterator *property_iterator;
};
static void
va_start(ap, atts);
while (name = va_arg(ap, const char *), name != NULL) {
ptr = va_arg(ap, const char **);
+ *ptr = NULL;
for (i = 0; atts[i]; i += 2) {
if (strcmp(atts[i], name) == 0)
*ptr = atts[i + 1];
enum razor_property_type type)
{
const char *name = NULL, *version = NULL;
- int i;
- for (i = 0; atts[i]; i += 2) {
- if (strcmp(atts[i], "name") == 0)
- name = atts[i + 1];
- else if (strcmp(atts[i], "eq") == 0)
- version = atts[i + 1];
- }
+ get_atts(atts, "name", &name, "eq", &version, NULL);
if (name == NULL) {
fprintf(stderr, "no name specified for property\n");
}
static void
-start_test_sets_element(void *data, const char *element, const char **atts)
+start_set_element(void *data, const char *element, const char **atts)
{
struct test_context *ctx = data;
struct test_set *set;
}
static void
-end_test_sets_element (void *data, const char *name)
+end_set_element (void *data, const char *name)
{
struct test_context *ctx = data;
}
}
+static struct razor_set *
+lookup_set(struct test_context *ctx, const char *name)
+{
+ struct test_set *set;
+
+ for (set = ctx->sets; set != NULL; set = set->next) {
+ if (strcmp(set->name, name) == 0)
+ return set->set;
+ }
+
+ return NULL;
+}
+
+static void
+verify_begin(struct test_context *ctx, const char **atts)
+{
+ struct razor_set *set;
+ const char *type, *name;
+
+ get_atts(atts, "type", &type, "set", &name, NULL);
+ set = lookup_set(ctx, name);
+ if (set == NULL) {
+ fprintf(stderr, "set %s not found\n", name);
+ exit(-1);
+ }
+
+ if (strcmp(type, "packages") == 0) {
+ ctx->package_iterator =
+ razor_package_iterator_create(set);
+ } else if (strcmp(type, "properties") == 0) {
+ ctx->property_iterator =
+ razor_property_iterator_create(set, NULL);
+ } else {
+ fprintf(stderr,
+ "unknown compare type \"%s\"\n", type);
+ exit(-1);
+ }
+}
+
+static void
+verify_end(struct test_context *ctx)
+{
+ struct razor_package *package;
+ struct razor_property *property;
+ const char *name, *version, *ref_name, *ref_version;
+ enum razor_property_type type;
+
+ if (ctx->package_iterator != NULL) {
+ if (razor_package_iterator_next(ctx->package_iterator,
+ &package,
+ &name, &version)) {
+ fprintf(stderr, "too few packages in set\n");
+ exit(-1);
+ }
+
+ razor_package_iterator_destroy(ctx->package_iterator);
+ ctx->package_iterator = NULL;
+ }
+
+ if (ctx->property_iterator != NULL) {
+ if (razor_property_iterator_next(ctx->property_iterator,
+ &property,
+ &name, &version, &type)) {
+ fprintf(stderr, "too few properties in set\n");
+ exit(-1);
+ }
+
+ razor_property_iterator_destroy(ctx->property_iterator);
+ ctx->property_iterator = NULL;
+ }
+}
+
+static void
+verify_package(struct test_context *ctx, const char **atts)
+{
+ struct razor_package *package;
+ const char *name, *version, *ref_name, *ref_version;
+
+ if (ctx->package_iterator == NULL) {
+ fprintf(stderr,
+ "\"package\" element seen, "
+ "but not in package verify mode\n");
+ exit(-1);
+ }
+
+ get_atts(atts, "name", &ref_name, "version", &ref_version, NULL);
+ if (!razor_package_iterator_next(ctx->package_iterator,
+ &package, &name, &version)) {
+ fprintf(stderr, "too many packages in set\n");
+ exit(-1);
+ }
+
+ if (strcmp(name, ref_name) != 0 || strcmp(version, ref_version) != 0) {
+ fprintf(stderr,
+ "package mismatch; expected %s-%s, got %s-%s\n",
+ ref_name, ref_version, name, version);
+ exit(-1);
+ }
+}
+
+static void
+verify_property(struct test_context *ctx,
+ enum razor_property_type ref_type, const char **atts)
+{
+ struct razor_property *property;
+ const char *name, *version, *ref_name, *ref_version;
+ enum razor_property_type type;
+ int same_version;
+
+ if (ctx->property_iterator == NULL) {
+ fprintf(stderr,
+ "\"requires/provides\" element seen, "
+ "but not in property verify mode\n");
+ exit(-1);
+ }
+
+ get_atts(atts, "name", &ref_name, "eq", &ref_version, NULL);
+ if (!razor_property_iterator_next(ctx->property_iterator, &property,
+ &name, &version, &type)) {
+ fprintf(stderr, "too many properties in set\n");
+ exit(-1);
+ }
+
+ if (version != NULL && ref_version != NULL)
+ same_version = strcmp(version, ref_version) == 0;
+ else if (version == NULL && ref_version == NULL)
+ same_version = 1;
+ else
+ same_version = 0;
+
+ if (strcmp(name, ref_name) != 0 || !same_version || type != ref_type) {
+ fprintf(stderr,
+ "property mismatch; expected %s-%s/%d, got %s-%s/%d\n",
+ ref_name, ref_version, ref_type,
+ name, version, type);
+ exit(-1);
+ }
+}
+
+static void
+start_test_element(void *data, const char *element, const char **atts)
+{
+ struct test_context *ctx = data;
+ struct razor_set *set;
+ const char *name;
+
+ if (strcmp(element, "import") == 0) {
+ get_atts(atts, "file", &name, NULL);
+ parse_xml_file(name, start_set_element, end_set_element, ctx);
+ } else if (strcmp(element, "update") == 0) {
+ /* run update to create new set */
+ } else if (strcmp(element, "verify") == 0) {
+ verify_begin(ctx, atts);
+ } else if (strcmp(element, "package") == 0) {
+ verify_package(ctx, atts);
+ } else if (strcmp(element, "requires") == 0) {
+ verify_property(ctx, RAZOR_PROPERTY_REQUIRES, atts);
+ } else if (strcmp(element, "provides") == 0) {
+ verify_property(ctx, RAZOR_PROPERTY_PROVIDES, atts);
+ } else if (strcmp(element, "conflicts") == 0) {
+ verify_property(ctx, RAZOR_PROPERTY_CONFLICTS, atts);
+ } else if (strcmp(element, "obsoletes") == 0) {
+ verify_property(ctx, RAZOR_PROPERTY_OBSOLETES, atts);
+ }
+}
+
+static void
+end_test_element (void *data, const char *element)
+{
+ struct test_context *ctx = data;
+
+ if (strcmp(element, "verify") == 0)
+ verify_end(ctx);
+}
+
int main(int argc, char *argv[])
{
struct test_context ctx;
struct test_set *set;
- if (argc != 3) {
- fprintf(stderr, "usage: %s SETS-FILE TESTS-FILE\n", argv[0]);
+ if (argc != 2) {
+ fprintf(stderr, "usage: %s TESTS-FILE\n", argv[0]);
exit(-1);
}
memset(&ctx, 0, sizeof ctx);
- parse_xml_file(argv[1],
- start_test_sets_element,
- end_test_sets_element,
- &ctx);
-
- for (set = ctx.sets; set != NULL; set = set->next)
- printf("set %s\n", set->name);
+ parse_xml_file(argv[1], start_test_element, end_test_element, &ctx);
return 0;
}