upool = upstream->string_pool.data;
package_pool = &upstream->package_pool;
- for (u = unsatisfied->data; u < end; u++) {
+ u = unsatisfied->data;
+ while (u < end) {
r = requires + *u;
while (p < pend &&
while (p + 1 < pend && p->name == (p + 1)->name && p->type == (p + 1)->type)
p++;
- if (p == pend ||
- strcmp(&pool[r->name], &upool[p->name]) != 0 ||
- versioncmp(&pool[r->version], &upool[p->version]) > 0) {
- /* Do we need to track unsatisfiable requires
- * as we go, or should we just do a
- * razor_set_validate() at the end? */
- } else {
+ if (p != pend &&
+ p->type == RAZOR_PROPERTY_PROVIDES &&
+ strcmp(&pool[r->name], &upool[p->name]) == 0 &&
+ versioncmp(&pool[r->version], &upool[p->version]) <= 0) {
pkg = array_add(list, sizeof *pkg);
/* We just pull in the first package that provides */
*pkg = list_first(&p->packages, package_pool)->data;
+
+ /* Remove this from the unsatisfied list */
+ memmove (u, u + 1, end - (u + 1));
+ end--;
+ } else {
+ /* Leave this in the unsatisfied list */
+ u++;
}
- }
+ }
+ unsatisfied->size = (void *)end - unsatisfied->data;
}
static void
}
}
+/* FIXME: this is all wrong anyway; we should recompute the new_unsatisfied
+ * set as we add and remove packages...
+ */
+static void
+razor_set_revalidate(struct razor_set *orig_set,
+ struct array *orig_unsatisfied,
+ struct razor_set *new_set,
+ struct array *new_unsatisfied)
+{
+ uint32_t *nu, *nuend, *ou, *ouend;
+ struct razor_property *new_props, *orig_props;
+ char *new_pool, *orig_pool;
+
+ razor_set_validate(new_set, new_unsatisfied);
+
+ ouend = orig_unsatisfied->data + orig_unsatisfied->size;
+ nuend = new_unsatisfied->data + new_unsatisfied->size;
+ new_props = new_set->properties.data;
+ orig_props = orig_set->properties.data;
+ new_pool = new_set->string_pool.data;
+ orig_pool = orig_set->string_pool.data;
+
+ for (nu = new_unsatisfied->data; nu < nuend; nu++) {
+ for (ou = orig_unsatisfied->data; ou < ouend; ou++) {
+ if (!strcmp (&new_pool[new_props[*nu].name],
+ &orig_pool[orig_props[*ou].name]) &&
+ new_props[*nu].relation == orig_props[*ou].relation &&
+ !strcmp (&new_pool[new_props[*nu].version],
+ &orig_pool[orig_props[*ou].version])) {
+ *(nu--) = *(--nuend);
+ break;
+ }
+ }
+ }
+
+ new_unsatisfied->size = (void *)nuend - new_unsatisfied->data;
+}
+
struct razor_set *
razor_set_update(struct razor_set *set, struct razor_set *upstream,
int count, const char **packages)
{
struct razor_set *new;
- struct array list, unsatisfied;
+ struct array list, unsatisfied_before, unsatisfied;
array_init(&list);
if (count > 0)
else
find_all_packages(set, upstream, &list);
+ array_init(&unsatisfied_before);
+ razor_set_validate(set, &unsatisfied_before);
+
while (list.size > 0) {
new = razor_set_add(set, upstream, &list);
array_release(&list);
- razor_set_destroy(set);
- set = new;
array_init(&unsatisfied);
- razor_set_validate(new, &unsatisfied);
+ razor_set_revalidate(set, &unsatisfied_before,
+ new, &unsatisfied);
+
array_init(&list);
razor_set_satisfy(new, &unsatisfied, upstream, &list);
- array_release(&unsatisfied);
+
+ if (unsatisfied.size) {
+ /* FIXME: need to return this list */
+ array_release(&unsatisfied);
+ razor_set_destroy(new);
+ razor_set_destroy(set);
+ set = NULL;
+ break;
+ }
+
+ razor_set_destroy(set);
+ set = new;
}
array_release(&list);
+ array_release(&unsatisfied_before);
return set;
}
struct razor_package *pkgs;
int pkg_count, remove_count, p, r;
struct array unsatisfied_before;
- uint32_t *u, *uend, *ub, *ubend;
- struct razor_property *props, *propsb;
- char *pool, *poolb;
array_init(&unsatisfied_before);
razor_set_validate(set, &unsatisfied_before);
new = razor_merger_finish(merger);
- razor_set_validate(new, unsatisfied);
-
- ubend = unsatisfied_before.data + unsatisfied_before.size;
- uend = unsatisfied->data + unsatisfied->size;
- props = new->properties.data;
- propsb = set->properties.data;
- pool = new->string_pool.data;
- poolb = set->string_pool.data;
-
- for (u = unsatisfied->data; u < uend; u++) {
- for (ub = unsatisfied_before.data; ub < ubend; ub++) {
- if (!strcmp (&pool[props[*u].name],
- &poolb[propsb[*ub].name]) &&
- props[*u].relation == propsb[*ub].relation &&
- !strcmp (&pool[props[*u].version],
- &poolb[propsb[*ub].version])) {
- *(u--) = *(--uend);
- break;
- }
- }
- }
+ razor_set_revalidate(set, &unsatisfied_before,
+ new, unsatisfied);
+ array_release(&unsatisfied_before);
- unsatisfied->size = (void *)uend - unsatisfied->data;
return new;
}
int n_install_pkgs, n_remove_pkgs;
int in_result, result_errors;
+ int in_unsatisfiable;
};
static void
const char *name = NULL, *rel_str = NULL, *version = NULL;
enum razor_version_relation rel;
+ if (ctx->in_unsatisfiable)
+ return;
+
get_atts(atts, "name", &name, "rel", &rel_str, "version", &version, NULL);
if (name == NULL) {
fprintf(stderr, " no name specified for property\n");
static void
end_transaction(struct test_context *ctx)
{
- ctx->system_set = razor_set_update(ctx->system_set,
- ctx->repo_set,
- ctx->n_install_pkgs,
- (const char **)ctx->install_pkgs);
- ctx->system_set = razor_set_remove(ctx->system_set,
- ctx->n_remove_pkgs,
- (const char **)ctx->remove_pkgs);
+ if (ctx->n_install_pkgs) {
+ ctx->system_set = razor_set_update(ctx->system_set,
+ ctx->repo_set,
+ ctx->n_install_pkgs,
+ (const char **)ctx->install_pkgs);
+ }
+ if (ctx->n_remove_pkgs && ctx->system_set) {
+ ctx->system_set = razor_set_remove(ctx->system_set,
+ ctx->n_remove_pkgs,
+ (const char **)ctx->remove_pkgs);
+ }
while (ctx->n_install_pkgs--)
free(ctx->install_pkgs[ctx->n_install_pkgs]);
{
ctx->in_result = 0;
- if (ctx->system_set && ctx->result_set) {
+ if (ctx->result_set) {
+ if (!ctx->system_set)
+ ctx->system_set = razor_set_create();
ctx->result_errors = 0;
razor_set_diff(ctx->system_set, ctx->result_set,
diff_callback, ctx);
if (ctx->result_errors)
exit(1);
}
-
}
static void
-start_unsatisfied(struct test_context *ctx, const char **atts)
+start_unsatisfiable(struct test_context *ctx, const char **atts)
{
+ if (ctx->system_set) {
+ fprintf(stderr, "Expected to fail, but didn't\n");
+ exit(1);
+ }
+
/* FIXME */
- fprintf(stderr, "Can't handle <unsatisfied>\n");
- exit(1);
+ fprintf(stderr, " Not actually checking <unsatisfiable>\n");
+ ctx->in_unsatisfiable = 1;
}
static void
-end_unsatisfied(struct test_context *ctx)
+end_unsatisfiable(struct test_context *ctx)
{
+ ctx->in_unsatisfiable = 0;
}
static void
start_remove(ctx, atts);
} else if (strcmp(element, "result") == 0) {
start_result(ctx, atts);
- } else if (strcmp(element, "unsatisfied") == 0) {
- start_unsatisfied(ctx, atts);
+ } else if (strcmp(element, "unsatisfiable") == 0) {
+ start_unsatisfiable(ctx, atts);
} else if (strcmp(element, "package") == 0) {
start_package(ctx, atts);
} else if (strcmp(element, "requires") == 0) {
end_transaction(ctx);
} else if (strcmp(element, "result") == 0) {
end_result(ctx);
- } else if (strcmp(element, "unsatisfied") == 0) {
- end_unsatisfied(ctx);
+ } else if (strcmp(element, "unsatisfiable") == 0) {
+ end_unsatisfiable(ctx);
}
}