1.1 --- a/librazor/razor.c Mon Jun 16 22:35:09 2008 -0400
1.2 +++ b/librazor/razor.c Fri Jun 20 14:18:52 2008 -0400
1.3 @@ -70,10 +70,8 @@
1.4 };
1.5
1.6 struct razor_property {
1.7 - uint name : 24;
1.8 - uint flags : 6;
1.9 - enum razor_property_type type : 2;
1.10 - enum razor_version_relation relation : 32;
1.11 + uint32_t name;
1.12 + uint32_t flags;
1.13 uint32_t version;
1.14 struct list_head packages;
1.15 };
1.16 @@ -316,6 +314,7 @@
1.17 array_init(&importer->properties);
1.18 }
1.19
1.20 +
1.21 void
1.22 razor_importer_finish_package(struct razor_importer *importer)
1.23 {
1.24 @@ -330,18 +329,15 @@
1.25 void
1.26 razor_importer_add_property(struct razor_importer *importer,
1.27 const char *name,
1.28 - enum razor_version_relation relation,
1.29 - const char *version,
1.30 - enum razor_property_type type)
1.31 + uint32_t flags,
1.32 + const char *version)
1.33 {
1.34 struct razor_property *p;
1.35 uint32_t *r;
1.36
1.37 p = array_add(&importer->set->properties, sizeof *p);
1.38 p->name = hashtable_tokenize(&importer->table, name);
1.39 - p->flags = 0;
1.40 - p->type = type;
1.41 - p->relation = relation;
1.42 + p->flags = flags;
1.43 p->version = hashtable_tokenize(&importer->table, version);
1.44 list_set_ptr(&p->packages, importer->package -
1.45 (struct razor_package *) importer->set->packages.data);
1.46 @@ -349,7 +345,8 @@
1.47 r = array_add(&importer->properties, sizeof *r);
1.48 *r = p - (struct razor_property *) importer->set->properties.data;
1.49
1.50 - if (type == RAZOR_PROPERTY_REQUIRES && *name == '/') {
1.51 + if (((flags & RAZOR_PROPERTY_TYPE_MASK) == RAZOR_PROPERTY_REQUIRES) &&
1.52 + *name == '/') {
1.53 r = array_add(&importer->file_requires, sizeof *r);
1.54 *r = p->name;
1.55 }
1.56 @@ -446,10 +443,8 @@
1.57
1.58 if (prop1->name != prop2->name)
1.59 return strcmp(&pool[prop1->name], &pool[prop2->name]);
1.60 - else if (prop1->type != prop2->type)
1.61 - return prop1->type - prop2->type;
1.62 - else if (prop1->relation != prop2->relation)
1.63 - return prop1->relation - prop2->relation;
1.64 + else if (prop1->flags != prop2->flags)
1.65 + return prop1->flags - prop2->flags;
1.66 else
1.67 return versioncmp(&pool[prop1->version], &pool[prop2->version]);
1.68 }
1.69 @@ -474,13 +469,12 @@
1.70 rmap = malloc(count * sizeof *map);
1.71 pkgs = zalloc(count * sizeof *pkgs);
1.72 for (rp = set->properties.data, up = rp, i = 0; rp < rp_end; rp++, i++) {
1.73 - if (rp->name != up->name || rp->type != up->type ||
1.74 - rp->relation != up->relation || rp->version != up->version) {
1.75 + if (rp->name != up->name ||
1.76 + rp->flags != up->flags ||
1.77 + rp->version != up->version) {
1.78 up++;
1.79 up->name = rp->name;
1.80 - up->flags = 0;
1.81 - up->type = rp->type;
1.82 - up->relation = rp->relation;
1.83 + up->flags = rp->flags;
1.84 up->version = rp->version;
1.85 }
1.86
1.87 @@ -718,8 +712,8 @@
1.88 for (pkg = list_first(&entry->packages, &importer->set->package_pool); pkg; pkg = list_next(pkg)) {
1.89 prop = array_add(&importer->set->properties, sizeof *prop);
1.90 prop->name = *req;
1.91 - prop->type = RAZOR_PROPERTY_PROVIDES;
1.92 - prop->relation = RAZOR_VERSION_EQUAL;
1.93 + prop->flags =
1.94 + RAZOR_PROPERTY_PROVIDES | RAZOR_PROPERTY_EQUAL;
1.95 prop->version = hashtable_tokenize(&importer->table, "");
1.96 list_set_ptr(&prop->packages, pkg->data);
1.97
1.98 @@ -950,9 +944,8 @@
1.99 razor_property_iterator_next(struct razor_property_iterator *pi,
1.100 struct razor_property **property,
1.101 const char **name,
1.102 - enum razor_version_relation *relation,
1.103 - const char **version,
1.104 - enum razor_property_type *type)
1.105 + uint32_t *flags,
1.106 + const char **version)
1.107 {
1.108 char *pool;
1.109 int valid;
1.110 @@ -973,9 +966,8 @@
1.111 pool = pi->set->string_pool.data;
1.112 *property = p;
1.113 *name = &pool[p->name];
1.114 - *relation = p->relation;
1.115 + *flags = p->flags;
1.116 *version = &pool[p->version];
1.117 - *type = p->type;
1.118 } else {
1.119 *property = NULL;
1.120 }
1.121 @@ -1242,16 +1234,13 @@
1.122
1.123 static uint32_t
1.124 add_property(struct razor_merger *merger,
1.125 - const char *name, enum razor_version_relation relation,
1.126 - const char *version, int type)
1.127 + const char *name, uint32_t flags, const char *version)
1.128 {
1.129 struct razor_property *p;
1.130
1.131 p = array_add(&merger->set->properties, sizeof *p);
1.132 p->name = hashtable_tokenize(&merger->table, name);
1.133 - p->flags = 0;
1.134 - p->type = type;
1.135 - p->relation = relation;
1.136 + p->flags = flags;
1.137 p->version = hashtable_tokenize(&merger->table, version);
1.138
1.139 return p - (struct razor_property *) merger->set->properties.data;
1.140 @@ -1296,30 +1285,26 @@
1.141 else
1.142 cmp = 1;
1.143 if (cmp == 0)
1.144 - cmp = p1->type - p2->type;
1.145 - if (cmp == 0)
1.146 - cmp = p1->relation - p2->relation;
1.147 + cmp = p1->flags - p2->flags;
1.148 if (cmp == 0)
1.149 cmp = versioncmp(&pool1[p1->version],
1.150 &pool2[p2->version]);
1.151 if (cmp < 0) {
1.152 map1[i++] = add_property(merger,
1.153 &pool1[p1->name],
1.154 - p1->relation,
1.155 - &pool1[p1->version],
1.156 - p1->type);
1.157 + p1->flags,
1.158 + &pool1[p1->version]);
1.159 } else if (cmp > 0) {
1.160 map2[j++] = add_property(merger,
1.161 &pool2[p2->name],
1.162 - p2->relation,
1.163 - &pool2[p2->version],
1.164 - p2->type);
1.165 + p2->flags,
1.166 + &pool2[p2->version]);
1.167 } else {
1.168 - map1[i++] = map2[j++] = add_property(merger,
1.169 - &pool1[p1->name],
1.170 - p1->relation,
1.171 - &pool1[p1->version],
1.172 - p1->type);
1.173 + map1[i++] = map2[j++] =
1.174 + add_property(merger,
1.175 + &pool1[p1->name],
1.176 + p1->flags,
1.177 + &pool1[p1->version]);
1.178 }
1.179 }
1.180 }
1.181 @@ -1709,7 +1694,7 @@
1.182 static int
1.183 provider_satisfies_requirement(struct razor_property *provider,
1.184 const char *provider_strings,
1.185 - enum razor_version_relation relation,
1.186 + uint32_t flags,
1.187 const char *required)
1.188 {
1.189 int cmp, len;
1.190 @@ -1718,24 +1703,24 @@
1.191 if (!*required)
1.192 return 1;
1.193 if (!*provided) {
1.194 - if (relation >= RAZOR_VERSION_EQUAL)
1.195 + if (flags & RAZOR_PROPERTY_LESS)
1.196 + return 0;
1.197 + else
1.198 return 1;
1.199 - else
1.200 - return 0;
1.201 }
1.202
1.203 cmp = versioncmp(provided, required);
1.204
1.205 - switch (relation) {
1.206 - case RAZOR_VERSION_LESS:
1.207 + switch (flags & RAZOR_PROPERTY_RELATION_MASK) {
1.208 + case RAZOR_PROPERTY_LESS:
1.209 return cmp < 0;
1.210
1.211 - case RAZOR_VERSION_LESS_OR_EQUAL:
1.212 + case RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL:
1.213 if (cmp <= 0)
1.214 return 1;
1.215 /* fall through: FIXME, make sure this is correct */
1.216
1.217 - case RAZOR_VERSION_EQUAL:
1.218 + case RAZOR_PROPERTY_EQUAL:
1.219 if (cmp == 0)
1.220 return 1;
1.221
1.222 @@ -1745,10 +1730,10 @@
1.223 return 1;
1.224 return 0;
1.225
1.226 - case RAZOR_VERSION_GREATER_OR_EQUAL:
1.227 + case RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL:
1.228 return cmp >= 0;
1.229
1.230 - case RAZOR_VERSION_GREATER:
1.231 + case RAZOR_PROPERTY_GREATER:
1.232 return cmp > 0;
1.233 }
1.234
1.235 @@ -1903,12 +1888,11 @@
1.236 }
1.237
1.238 static int
1.239 -prop_iter_next(struct prop_iter *pi,
1.240 - enum razor_property_type type, struct razor_property **p)
1.241 +prop_iter_next(struct prop_iter *pi, uint32_t flags, struct razor_property **p)
1.242 {
1.243 while (pi->p < pi->end) {
1.244 if ((pi->present[pi->p - pi->start] & ~TRANS_PROPERTY_SATISFIED) &&
1.245 - pi->p->type == type) {
1.246 + (pi->p->flags & RAZOR_PROPERTY_TYPE_MASK) == flags) {
1.247 *p = pi->p++;
1.248 return 1;
1.249 }
1.250 @@ -1920,7 +1904,7 @@
1.251
1.252 static struct razor_property *
1.253 prop_iter_seek_to(struct prop_iter *pi,
1.254 - enum razor_property_type type, const char *match)
1.255 + uint32_t flags, const char *match)
1.256 {
1.257 uint32_t name;
1.258
1.259 @@ -1933,7 +1917,7 @@
1.260 name = pi->p->name;
1.261 while (pi->p < pi->end &&
1.262 pi->p->name == name &&
1.263 - pi->p->type != type)
1.264 + (pi->p->flags & RAZOR_PROPERTY_TYPE_MASK) != flags)
1.265 pi->p++;
1.266
1.267 if (pi->p == pi->end || pi->p->name != name)
1.268 @@ -1948,7 +1932,7 @@
1.269 static void
1.270 remove_matching_providers(struct razor_transaction *trans,
1.271 struct prop_iter *ppi,
1.272 - enum razor_version_relation relation,
1.273 + uint32_t flags,
1.274 const char *version)
1.275 {
1.276 struct razor_property *p;
1.277 @@ -1956,6 +1940,7 @@
1.278 struct razor_package_iterator pkg_iter;
1.279 struct razor_set *set;
1.280 const char *n, *v, *a;
1.281 + uint32_t type;
1.282
1.283 if (ppi->present == trans->system.properties)
1.284 set = trans->system.set;
1.285 @@ -1963,15 +1948,16 @@
1.286 set = trans->upstream.set;
1.287
1.288 pkgs = (struct razor_package *) set->packages.data;
1.289 + type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
1.290 for (p = ppi->p;
1.291 p < ppi->end &&
1.292 p->name == ppi->p->name &&
1.293 - p->type == ppi->p->type;
1.294 + (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
1.295 p++) {
1.296 if (!ppi->present[p - ppi->start])
1.297 continue;
1.298 if (!provider_satisfies_requirement(p, ppi->pool,
1.299 - relation, version))
1.300 + flags, version))
1.301 continue;
1.302
1.303 razor_package_iterator_init_for_property(&pkg_iter, set, p);
1.304 @@ -1995,7 +1981,7 @@
1.305 struct razor_package_iterator pkg_iter;
1.306 struct razor_set *set;
1.307 const char *name, *version, *arch;
1.308 - uint32_t *flags;
1.309 + uint32_t *flags, type;
1.310
1.311 if (ppi->present == trans->system.properties) {
1.312 set = trans->system.set;
1.313 @@ -2006,15 +1992,16 @@
1.314 }
1.315
1.316 pkgs = (struct razor_package *) set->packages.data;
1.317 + type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
1.318 for (p = ppi->p;
1.319 p < ppi->end &&
1.320 p->name == ppi->p->name &&
1.321 - p->type == ppi->p->type;
1.322 + (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
1.323 p++) {
1.324 if (!ppi->present[p - ppi->start])
1.325 continue;
1.326 if (!provider_satisfies_requirement(p, ppi->pool,
1.327 - r->relation,
1.328 + r->flags,
1.329 &rpi->pool[r->version]))
1.330 continue;
1.331
1.332 @@ -2035,12 +2022,13 @@
1.333 static struct razor_package *
1.334 pick_matching_provider(struct razor_set *set,
1.335 struct prop_iter *ppi,
1.336 - enum razor_version_relation relation,
1.337 + uint32_t flags,
1.338 const char *version)
1.339 {
1.340 struct razor_property *p;
1.341 struct razor_package *pkgs;
1.342 struct list *i;
1.343 + uint32_t type;
1.344
1.345 /* This is where we decide which pkgs to pull in to satisfy a
1.346 * requirement. There may be several different providers
1.347 @@ -2049,14 +2037,15 @@
1.348 * from the first provider that matches. */
1.349
1.350 pkgs = set->packages.data;
1.351 + type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
1.352 for (p = ppi->p;
1.353 p < ppi->end &&
1.354 p->name == ppi->p->name &&
1.355 - p->type == ppi->p->type &&
1.356 + (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type &&
1.357 ppi->present[p - ppi->start] == 0;
1.358 p++) {
1.359 if (!provider_satisfies_requirement(p, ppi->pool,
1.360 - relation, version))
1.361 + flags, version))
1.362 continue;
1.363
1.364 i = list_first(&p->packages, &set->package_pool);
1.365 @@ -2082,26 +2071,28 @@
1.366 if (!prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES,
1.367 &upi.pool[up->name]))
1.368 continue;
1.369 - remove_matching_providers(trans, &spi, up->relation,
1.370 + remove_matching_providers(trans, &spi, up->flags,
1.371 &upi.pool[up->version]);
1.372 }
1.373 }
1.374
1.375 static int
1.376 any_provider_satisfies_requirement(struct prop_iter *ppi,
1.377 - enum razor_version_relation relation,
1.378 + uint32_t flags,
1.379 const char *version)
1.380 {
1.381 struct razor_property *p;
1.382 -
1.383 + uint32_t type;
1.384 +
1.385 + type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
1.386 for (p = ppi->p;
1.387 p < ppi->end &&
1.388 p->name == ppi->p->name &&
1.389 - p->type == ppi->p->type;
1.390 + (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
1.391 p++) {
1.392 if (ppi->present[p - ppi->start] > 0 &&
1.393 provider_satisfies_requirement(p, ppi->pool,
1.394 - relation, version))
1.395 + flags, version))
1.396 return 1;
1.397 }
1.398
1.399 @@ -2125,7 +2116,46 @@
1.400 }
1.401 }
1.402
1.403 -static const char *relation_string[] = { "<", "<=", "=", ">=", ">" };
1.404 +const char *
1.405 +razor_property_relation_to_string(struct razor_property *p)
1.406 +{
1.407 + switch (p->flags & RAZOR_PROPERTY_RELATION_MASK) {
1.408 + case RAZOR_PROPERTY_LESS:
1.409 + return "<";
1.410 +
1.411 + case RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL:
1.412 + return "<=";
1.413 +
1.414 + case RAZOR_PROPERTY_EQUAL:
1.415 + return "=";
1.416 +
1.417 + case RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL:
1.418 + return ">=";
1.419 +
1.420 + case RAZOR_PROPERTY_GREATER:
1.421 + return ">";
1.422 +
1.423 + default:
1.424 + return "?";
1.425 + }
1.426 +}
1.427 +
1.428 +const char *
1.429 +razor_property_type_to_string(struct razor_property *p)
1.430 +{
1.431 + switch (p->flags & RAZOR_PROPERTY_TYPE_MASK) {
1.432 + case RAZOR_PROPERTY_REQUIRES:
1.433 + return "requires";
1.434 + case RAZOR_PROPERTY_PROVIDES:
1.435 + return "provides";
1.436 + case RAZOR_PROPERTY_CONFLICTS:
1.437 + return "conflicts";
1.438 + case RAZOR_PROPERTY_OBSOLETES:
1.439 + return "obsoletes";
1.440 + default:
1.441 + return NULL;
1.442 + }
1.443 +}
1.444
1.445 static void
1.446 mark_satisfied_requires(struct razor_transaction *trans,
1.447 @@ -2143,7 +2173,7 @@
1.448 &rpi.pool[rp->name]))
1.449 continue;
1.450
1.451 - if (any_provider_satisfies_requirement(&ppi, rp->relation,
1.452 + if (any_provider_satisfies_requirement(&ppi, rp->flags,
1.453 &rpi.pool[rp->version]))
1.454 rpi.present[rp - rpi.start] |= TRANS_PROPERTY_SATISFIED;
1.455 }
1.456 @@ -2184,7 +2214,7 @@
1.457 fprintf(stderr, "updating %s because %s %s %s "
1.458 "isn't satisfied\n",
1.459 name, spi.pool + sp->name,
1.460 - relation_string[sp->relation],
1.461 + razor_property_relation_to_string(sp),
1.462 spi.pool + sp->version);
1.463 trans->system.packages[pkg - spkgs] |=
1.464 TRANS_PACKAGE_UPDATE;
1.465 @@ -2221,7 +2251,7 @@
1.466 &spi.pool[sp->name]))
1.467 continue;
1.468
1.469 - if (!any_provider_satisfies_requirement(&upi, sp->relation,
1.470 + if (!any_provider_satisfies_requirement(&upi, sp->flags,
1.471 &spi.pool[sp->version]))
1.472 continue;
1.473
1.474 @@ -2267,7 +2297,7 @@
1.475 if (pp == NULL)
1.476 continue;
1.477 pkg = pick_matching_provider(trans->upstream.set,
1.478 - ppi, rp->relation,
1.479 + ppi, rp->flags,
1.480 &rpi->pool[rp->version]);
1.481 if (pkg == NULL)
1.482 continue;
1.483 @@ -2278,10 +2308,10 @@
1.484 "to satisfy %s %s %s\n",
1.485 ppi->pool + pkg->name,
1.486 ppi->pool + pp->name,
1.487 - relation_string[pp->relation],
1.488 + razor_property_relation_to_string(pp),
1.489 ppi->pool + pp->version,
1.490 &rpi->pool[rp->name],
1.491 - relation_string[rp->relation],
1.492 + razor_property_relation_to_string(rp),
1.493 &rpi->pool[rp->version]);
1.494
1.495 trans->upstream.packages[pkg - upkgs] |= TRANS_PACKAGE_UPDATE;
1.496 @@ -2322,7 +2352,7 @@
1.497 continue;
1.498
1.499 pkg = pick_matching_provider(trans->upstream.set, &ppi,
1.500 - RAZOR_VERSION_GREATER, version);
1.501 + RAZOR_PROPERTY_GREATER, version);
1.502 if (pkg == NULL)
1.503 continue;
1.504
1.505 @@ -2354,8 +2384,10 @@
1.506 continue;
1.507
1.508 if (prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES, name))
1.509 - remove_matching_providers(trans, &spi,
1.510 - RAZOR_VERSION_LESS, version);
1.511 + remove_matching_providers(trans,
1.512 + &spi,
1.513 + RAZOR_PROPERTY_LESS,
1.514 + version);
1.515 razor_transaction_install_package(trans, p);
1.516 fprintf(stderr, "installing %s-%s\n", name, version);
1.517 }
1.518 @@ -2404,7 +2436,7 @@
1.519 &name, &version, &arch))
1.520 fprintf(stderr, "%s %s %s is needed by %s-%s.%s\n",
1.521 &pool[rp->name],
1.522 - relation_string[rp->relation],
1.523 + razor_property_relation_to_string(rp),
1.524 &pool[rp->version],
1.525 name, version, arch);
1.526 }
1.527 @@ -2444,17 +2476,16 @@
1.528 int
1.529 razor_transaction_unsatisfied_property(struct razor_transaction *trans,
1.530 const char *name,
1.531 - enum razor_version_relation rel,
1.532 - const char *version,
1.533 - enum razor_property_type type)
1.534 + uint32_t flags,
1.535 + const char *version)
1.536 {
1.537 struct prop_iter pi;
1.538 struct razor_property *p;
1.539
1.540 prop_iter_init(&pi, &trans->system);
1.541 - while (prop_iter_next(&pi, type, &p)) {
1.542 + while (prop_iter_next(&pi, flags, &p)) {
1.543 if (!(trans->system.properties[p - pi.start] & TRANS_PROPERTY_SATISFIED) &&
1.544 - p->relation == rel &&
1.545 + p->flags == flags &&
1.546 strcmp(&pi.pool[p->name], name) == 0 &&
1.547 strcmp(&pi.pool[p->version], version) == 0)
1.548
1.549 @@ -2462,9 +2493,9 @@
1.550 }
1.551
1.552 prop_iter_init(&pi, &trans->upstream);
1.553 - while (prop_iter_next(&pi, type, &p)) {
1.554 + while (prop_iter_next(&pi, flags, &p)) {
1.555 if (!(trans->upstream.properties[p - pi.start] & TRANS_PROPERTY_SATISFIED) &&
1.556 - p->relation == rel &&
1.557 + p->flags == flags &&
1.558 strcmp(&pi.pool[p->name], name) == 0 &&
1.559 strcmp(&pi.pool[p->version], version) == 0)
1.560