summaryrefslogtreecommitdiff
path: root/librazor/razor.c
diff options
context:
space:
mode:
Diffstat (limited to 'librazor/razor.c')
-rw-r--r--librazor/razor.c215
1 files changed, 123 insertions, 92 deletions
diff --git a/librazor/razor.c b/librazor/razor.c
index dffd755..67a2df2 100644
--- a/librazor/razor.c
+++ b/librazor/razor.c
@@ -70,10 +70,8 @@ struct razor_package {
};
struct razor_property {
- uint name : 24;
- uint flags : 6;
- enum razor_property_type type : 2;
- enum razor_version_relation relation : 32;
+ uint32_t name;
+ uint32_t flags;
uint32_t version;
struct list_head packages;
};
@@ -316,6 +314,7 @@ razor_importer_begin_package(struct razor_importer *importer,
array_init(&importer->properties);
}
+
void
razor_importer_finish_package(struct razor_importer *importer)
{
@@ -330,18 +329,15 @@ razor_importer_finish_package(struct razor_importer *importer)
void
razor_importer_add_property(struct razor_importer *importer,
const char *name,
- enum razor_version_relation relation,
- const char *version,
- enum razor_property_type type)
+ uint32_t flags,
+ const char *version)
{
struct razor_property *p;
uint32_t *r;
p = array_add(&importer->set->properties, sizeof *p);
p->name = hashtable_tokenize(&importer->table, name);
- p->flags = 0;
- p->type = type;
- p->relation = relation;
+ p->flags = flags;
p->version = hashtable_tokenize(&importer->table, version);
list_set_ptr(&p->packages, importer->package -
(struct razor_package *) importer->set->packages.data);
@@ -349,7 +345,8 @@ razor_importer_add_property(struct razor_importer *importer,
r = array_add(&importer->properties, sizeof *r);
*r = p - (struct razor_property *) importer->set->properties.data;
- if (type == RAZOR_PROPERTY_REQUIRES && *name == '/') {
+ if (((flags & RAZOR_PROPERTY_TYPE_MASK) == RAZOR_PROPERTY_REQUIRES) &&
+ *name == '/') {
r = array_add(&importer->file_requires, sizeof *r);
*r = p->name;
}
@@ -446,10 +443,8 @@ compare_properties(const void *p1, const void *p2, void *data)
if (prop1->name != prop2->name)
return strcmp(&pool[prop1->name], &pool[prop2->name]);
- else if (prop1->type != prop2->type)
- return prop1->type - prop2->type;
- else if (prop1->relation != prop2->relation)
- return prop1->relation - prop2->relation;
+ else if (prop1->flags != prop2->flags)
+ return prop1->flags - prop2->flags;
else
return versioncmp(&pool[prop1->version], &pool[prop2->version]);
}
@@ -474,13 +469,12 @@ uniqueify_properties(struct razor_set *set)
rmap = malloc(count * sizeof *map);
pkgs = zalloc(count * sizeof *pkgs);
for (rp = set->properties.data, up = rp, i = 0; rp < rp_end; rp++, i++) {
- if (rp->name != up->name || rp->type != up->type ||
- rp->relation != up->relation || rp->version != up->version) {
+ if (rp->name != up->name ||
+ rp->flags != up->flags ||
+ rp->version != up->version) {
up++;
up->name = rp->name;
- up->flags = 0;
- up->type = rp->type;
- up->relation = rp->relation;
+ up->flags = rp->flags;
up->version = rp->version;
}
@@ -718,8 +712,8 @@ find_file_provides(struct razor_importer *importer)
for (pkg = list_first(&entry->packages, &importer->set->package_pool); pkg; pkg = list_next(pkg)) {
prop = array_add(&importer->set->properties, sizeof *prop);
prop->name = *req;
- prop->type = RAZOR_PROPERTY_PROVIDES;
- prop->relation = RAZOR_VERSION_EQUAL;
+ prop->flags =
+ RAZOR_PROPERTY_PROVIDES | RAZOR_PROPERTY_EQUAL;
prop->version = hashtable_tokenize(&importer->table, "");
list_set_ptr(&prop->packages, pkg->data);
@@ -950,9 +944,8 @@ int
razor_property_iterator_next(struct razor_property_iterator *pi,
struct razor_property **property,
const char **name,
- enum razor_version_relation *relation,
- const char **version,
- enum razor_property_type *type)
+ uint32_t *flags,
+ const char **version)
{
char *pool;
int valid;
@@ -973,9 +966,8 @@ razor_property_iterator_next(struct razor_property_iterator *pi,
pool = pi->set->string_pool.data;
*property = p;
*name = &pool[p->name];
- *relation = p->relation;
+ *flags = p->flags;
*version = &pool[p->version];
- *type = p->type;
} else {
*property = NULL;
}
@@ -1242,16 +1234,13 @@ razor_merger_add_package(struct razor_merger *merger,
static uint32_t
add_property(struct razor_merger *merger,
- const char *name, enum razor_version_relation relation,
- const char *version, int type)
+ const char *name, uint32_t flags, const char *version)
{
struct razor_property *p;
p = array_add(&merger->set->properties, sizeof *p);
p->name = hashtable_tokenize(&merger->table, name);
- p->flags = 0;
- p->type = type;
- p->relation = relation;
+ p->flags = flags;
p->version = hashtable_tokenize(&merger->table, version);
return p - (struct razor_property *) merger->set->properties.data;
@@ -1296,30 +1285,26 @@ merge_properties(struct razor_merger *merger)
else
cmp = 1;
if (cmp == 0)
- cmp = p1->type - p2->type;
- if (cmp == 0)
- cmp = p1->relation - p2->relation;
+ cmp = p1->flags - p2->flags;
if (cmp == 0)
cmp = versioncmp(&pool1[p1->version],
&pool2[p2->version]);
if (cmp < 0) {
map1[i++] = add_property(merger,
&pool1[p1->name],
- p1->relation,
- &pool1[p1->version],
- p1->type);
+ p1->flags,
+ &pool1[p1->version]);
} else if (cmp > 0) {
map2[j++] = add_property(merger,
&pool2[p2->name],
- p2->relation,
- &pool2[p2->version],
- p2->type);
+ p2->flags,
+ &pool2[p2->version]);
} else {
- map1[i++] = map2[j++] = add_property(merger,
- &pool1[p1->name],
- p1->relation,
- &pool1[p1->version],
- p1->type);
+ map1[i++] = map2[j++] =
+ add_property(merger,
+ &pool1[p1->name],
+ p1->flags,
+ &pool1[p1->version]);
}
}
}
@@ -1709,7 +1694,7 @@ razor_set_diff(struct razor_set *set, struct razor_set *upstream,
static int
provider_satisfies_requirement(struct razor_property *provider,
const char *provider_strings,
- enum razor_version_relation relation,
+ uint32_t flags,
const char *required)
{
int cmp, len;
@@ -1718,24 +1703,24 @@ provider_satisfies_requirement(struct razor_property *provider,
if (!*required)
return 1;
if (!*provided) {
- if (relation >= RAZOR_VERSION_EQUAL)
- return 1;
- else
+ if (flags & RAZOR_PROPERTY_LESS)
return 0;
+ else
+ return 1;
}
cmp = versioncmp(provided, required);
- switch (relation) {
- case RAZOR_VERSION_LESS:
+ switch (flags & RAZOR_PROPERTY_RELATION_MASK) {
+ case RAZOR_PROPERTY_LESS:
return cmp < 0;
- case RAZOR_VERSION_LESS_OR_EQUAL:
+ case RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL:
if (cmp <= 0)
return 1;
/* fall through: FIXME, make sure this is correct */
- case RAZOR_VERSION_EQUAL:
+ case RAZOR_PROPERTY_EQUAL:
if (cmp == 0)
return 1;
@@ -1745,10 +1730,10 @@ provider_satisfies_requirement(struct razor_property *provider,
return 1;
return 0;
- case RAZOR_VERSION_GREATER_OR_EQUAL:
+ case RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL:
return cmp >= 0;
- case RAZOR_VERSION_GREATER:
+ case RAZOR_PROPERTY_GREATER:
return cmp > 0;
}
@@ -1903,12 +1888,11 @@ prop_iter_init(struct prop_iter *pi, struct transaction_set *ts)
}
static int
-prop_iter_next(struct prop_iter *pi,
- enum razor_property_type type, struct razor_property **p)
+prop_iter_next(struct prop_iter *pi, uint32_t flags, struct razor_property **p)
{
while (pi->p < pi->end) {
if ((pi->present[pi->p - pi->start] & ~TRANS_PROPERTY_SATISFIED) &&
- pi->p->type == type) {
+ (pi->p->flags & RAZOR_PROPERTY_TYPE_MASK) == flags) {
*p = pi->p++;
return 1;
}
@@ -1920,7 +1904,7 @@ prop_iter_next(struct prop_iter *pi,
static struct razor_property *
prop_iter_seek_to(struct prop_iter *pi,
- enum razor_property_type type, const char *match)
+ uint32_t flags, const char *match)
{
uint32_t name;
@@ -1933,7 +1917,7 @@ prop_iter_seek_to(struct prop_iter *pi,
name = pi->p->name;
while (pi->p < pi->end &&
pi->p->name == name &&
- pi->p->type != type)
+ (pi->p->flags & RAZOR_PROPERTY_TYPE_MASK) != flags)
pi->p++;
if (pi->p == pi->end || pi->p->name != name)
@@ -1948,7 +1932,7 @@ prop_iter_seek_to(struct prop_iter *pi,
static void
remove_matching_providers(struct razor_transaction *trans,
struct prop_iter *ppi,
- enum razor_version_relation relation,
+ uint32_t flags,
const char *version)
{
struct razor_property *p;
@@ -1956,6 +1940,7 @@ remove_matching_providers(struct razor_transaction *trans,
struct razor_package_iterator pkg_iter;
struct razor_set *set;
const char *n, *v, *a;
+ uint32_t type;
if (ppi->present == trans->system.properties)
set = trans->system.set;
@@ -1963,15 +1948,16 @@ remove_matching_providers(struct razor_transaction *trans,
set = trans->upstream.set;
pkgs = (struct razor_package *) set->packages.data;
+ type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
for (p = ppi->p;
p < ppi->end &&
p->name == ppi->p->name &&
- p->type == ppi->p->type;
+ (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
p++) {
if (!ppi->present[p - ppi->start])
continue;
if (!provider_satisfies_requirement(p, ppi->pool,
- relation, version))
+ flags, version))
continue;
razor_package_iterator_init_for_property(&pkg_iter, set, p);
@@ -1995,7 +1981,7 @@ flag_matching_providers(struct razor_transaction *trans,
struct razor_package_iterator pkg_iter;
struct razor_set *set;
const char *name, *version, *arch;
- uint32_t *flags;
+ uint32_t *flags, type;
if (ppi->present == trans->system.properties) {
set = trans->system.set;
@@ -2006,15 +1992,16 @@ flag_matching_providers(struct razor_transaction *trans,
}
pkgs = (struct razor_package *) set->packages.data;
+ type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
for (p = ppi->p;
p < ppi->end &&
p->name == ppi->p->name &&
- p->type == ppi->p->type;
+ (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
p++) {
if (!ppi->present[p - ppi->start])
continue;
if (!provider_satisfies_requirement(p, ppi->pool,
- r->relation,
+ r->flags,
&rpi->pool[r->version]))
continue;
@@ -2035,12 +2022,13 @@ flag_matching_providers(struct razor_transaction *trans,
static struct razor_package *
pick_matching_provider(struct razor_set *set,
struct prop_iter *ppi,
- enum razor_version_relation relation,
+ uint32_t flags,
const char *version)
{
struct razor_property *p;
struct razor_package *pkgs;
struct list *i;
+ uint32_t type;
/* This is where we decide which pkgs to pull in to satisfy a
* requirement. There may be several different providers
@@ -2049,14 +2037,15 @@ pick_matching_provider(struct razor_set *set,
* from the first provider that matches. */
pkgs = set->packages.data;
+ type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
for (p = ppi->p;
p < ppi->end &&
p->name == ppi->p->name &&
- p->type == ppi->p->type &&
+ (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type &&
ppi->present[p - ppi->start] == 0;
p++) {
if (!provider_satisfies_requirement(p, ppi->pool,
- relation, version))
+ flags, version))
continue;
i = list_first(&p->packages, &set->package_pool);
@@ -2082,26 +2071,28 @@ remove_obsoleted_packages(struct razor_transaction *trans)
if (!prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES,
&upi.pool[up->name]))
continue;
- remove_matching_providers(trans, &spi, up->relation,
+ remove_matching_providers(trans, &spi, up->flags,
&upi.pool[up->version]);
}
}
static int
any_provider_satisfies_requirement(struct prop_iter *ppi,
- enum razor_version_relation relation,
+ uint32_t flags,
const char *version)
{
struct razor_property *p;
+ uint32_t type;
+ type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
for (p = ppi->p;
p < ppi->end &&
p->name == ppi->p->name &&
- p->type == ppi->p->type;
+ (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
p++) {
if (ppi->present[p - ppi->start] > 0 &&
provider_satisfies_requirement(p, ppi->pool,
- relation, version))
+ flags, version))
return 1;
}
@@ -2125,7 +2116,46 @@ clear_requires_flags(struct transaction_set *ts)
}
}
-static const char *relation_string[] = { "<", "<=", "=", ">=", ">" };
+const char *
+razor_property_relation_to_string(struct razor_property *p)
+{
+ switch (p->flags & RAZOR_PROPERTY_RELATION_MASK) {
+ case RAZOR_PROPERTY_LESS:
+ return "<";
+
+ case RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL:
+ return "<=";
+
+ case RAZOR_PROPERTY_EQUAL:
+ return "=";
+
+ case RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL:
+ return ">=";
+
+ case RAZOR_PROPERTY_GREATER:
+ return ">";
+
+ default:
+ return "?";
+ }
+}
+
+const char *
+razor_property_type_to_string(struct razor_property *p)
+{
+ switch (p->flags & RAZOR_PROPERTY_TYPE_MASK) {
+ case RAZOR_PROPERTY_REQUIRES:
+ return "requires";
+ case RAZOR_PROPERTY_PROVIDES:
+ return "provides";
+ case RAZOR_PROPERTY_CONFLICTS:
+ return "conflicts";
+ case RAZOR_PROPERTY_OBSOLETES:
+ return "obsoletes";
+ default:
+ return NULL;
+ }
+}
static void
mark_satisfied_requires(struct razor_transaction *trans,
@@ -2143,7 +2173,7 @@ mark_satisfied_requires(struct razor_transaction *trans,
&rpi.pool[rp->name]))
continue;
- if (any_provider_satisfies_requirement(&ppi, rp->relation,
+ if (any_provider_satisfies_requirement(&ppi, rp->flags,
&rpi.pool[rp->version]))
rpi.present[rp - rpi.start] |= TRANS_PROPERTY_SATISFIED;
}
@@ -2184,7 +2214,7 @@ update_unsatisfied_packages(struct razor_transaction *trans)
fprintf(stderr, "updating %s because %s %s %s "
"isn't satisfied\n",
name, spi.pool + sp->name,
- relation_string[sp->relation],
+ razor_property_relation_to_string(sp),
spi.pool + sp->version);
trans->system.packages[pkg - spkgs] |=
TRANS_PACKAGE_UPDATE;
@@ -2221,7 +2251,7 @@ update_conflicted_packages(struct razor_transaction *trans)
&spi.pool[sp->name]))
continue;
- if (!any_provider_satisfies_requirement(&upi, sp->relation,
+ if (!any_provider_satisfies_requirement(&upi, sp->flags,
&spi.pool[sp->version]))
continue;
@@ -2267,7 +2297,7 @@ pull_in_requirements(struct razor_transaction *trans,
if (pp == NULL)
continue;
pkg = pick_matching_provider(trans->upstream.set,
- ppi, rp->relation,
+ ppi, rp->flags,
&rpi->pool[rp->version]);
if (pkg == NULL)
continue;
@@ -2278,10 +2308,10 @@ pull_in_requirements(struct razor_transaction *trans,
"to satisfy %s %s %s\n",
ppi->pool + pkg->name,
ppi->pool + pp->name,
- relation_string[pp->relation],
+ razor_property_relation_to_string(pp),
ppi->pool + pp->version,
&rpi->pool[rp->name],
- relation_string[rp->relation],
+ razor_property_relation_to_string(rp),
&rpi->pool[rp->version]);
trans->upstream.packages[pkg - upkgs] |= TRANS_PACKAGE_UPDATE;
@@ -2322,7 +2352,7 @@ flush_scheduled_system_updates(struct razor_transaction *trans)
continue;
pkg = pick_matching_provider(trans->upstream.set, &ppi,
- RAZOR_VERSION_GREATER, version);
+ RAZOR_PROPERTY_GREATER, version);
if (pkg == NULL)
continue;
@@ -2354,8 +2384,10 @@ flush_scheduled_upstream_updates(struct razor_transaction *trans)
continue;
if (prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES, name))
- remove_matching_providers(trans, &spi,
- RAZOR_VERSION_LESS, version);
+ remove_matching_providers(trans,
+ &spi,
+ RAZOR_PROPERTY_LESS,
+ version);
razor_transaction_install_package(trans, p);
fprintf(stderr, "installing %s-%s\n", name, version);
}
@@ -2404,7 +2436,7 @@ describe_unsatisfied(struct razor_set *set, struct razor_property *rp)
&name, &version, &arch))
fprintf(stderr, "%s %s %s is needed by %s-%s.%s\n",
&pool[rp->name],
- relation_string[rp->relation],
+ razor_property_relation_to_string(rp),
&pool[rp->version],
name, version, arch);
}
@@ -2444,17 +2476,16 @@ razor_transaction_describe(struct razor_transaction *trans)
int
razor_transaction_unsatisfied_property(struct razor_transaction *trans,
const char *name,
- enum razor_version_relation rel,
- const char *version,
- enum razor_property_type type)
+ uint32_t flags,
+ const char *version)
{
struct prop_iter pi;
struct razor_property *p;
prop_iter_init(&pi, &trans->system);
- while (prop_iter_next(&pi, type, &p)) {
+ while (prop_iter_next(&pi, flags, &p)) {
if (!(trans->system.properties[p - pi.start] & TRANS_PROPERTY_SATISFIED) &&
- p->relation == rel &&
+ p->flags == flags &&
strcmp(&pi.pool[p->name], name) == 0 &&
strcmp(&pi.pool[p->version], version) == 0)
@@ -2462,9 +2493,9 @@ razor_transaction_unsatisfied_property(struct razor_transaction *trans,
}
prop_iter_init(&pi, &trans->upstream);
- while (prop_iter_next(&pi, type, &p)) {
+ while (prop_iter_next(&pi, flags, &p)) {
if (!(trans->upstream.properties[p - pi.start] & TRANS_PROPERTY_SATISFIED) &&
- p->relation == rel &&
+ p->flags == flags &&
strcmp(&pi.pool[p->name], name) == 0 &&
strcmp(&pi.pool[p->version], version) == 0)