1.1 --- a/razor.c Tue Mar 04 10:55:01 2008 -0500
1.2 +++ b/razor.c Tue Mar 04 19:07:14 2008 -0500
1.3 @@ -1682,105 +1682,135 @@
1.4 int errors;
1.5 };
1.6
1.7 +static int
1.8 +package_in_set(void *package, struct razor_set *set)
1.9 +{
1.10 + return package >= set->packages.data &&
1.11 + package < set->packages.data + set->packages.size;
1.12 +}
1.13 +
1.14 +static int
1.15 +property_in_set(void *property, struct razor_set *set)
1.16 +{
1.17 + return property >= set->properties.data &&
1.18 + property < set->properties.data + set->properties.size;
1.19 +}
1.20 +
1.21 +static int
1.22 +compare_transaction_packages(const void *one, const void *two)
1.23 +{
1.24 + const struct razor_transaction_package *tp1 = one;
1.25 + const struct razor_transaction_package *tp2 = two;
1.26 +
1.27 + return strcmp(tp1->name, tp2->name);
1.28 +}
1.29 +
1.30 static void
1.31 find_packages(struct razor_transaction_resolver *trans,
1.32 - int count, const char **package_names,
1.33 - enum razor_transaction_package_state state)
1.34 + int update_count, const char **update_packages,
1.35 + int remove_count, const char **remove_packages)
1.36 {
1.37 - struct razor_set *set;
1.38 - struct bitarray *pkgbits;
1.39 - struct razor_package_iterator *pi;
1.40 - struct razor_package *p, *packages;
1.41 - const char *name, *version;
1.42 - struct razor_transaction_package *tp;
1.43 - int i, *found;
1.44 -
1.45 - if (state == RAZOR_PACKAGE_INSTALL) {
1.46 - set = trans->upstream;
1.47 - pkgbits = &trans->uppkgs;
1.48 - } else {
1.49 - set = trans->system;
1.50 - pkgbits = &trans->syspkgs;
1.51 + struct razor_package *sp, *spkgs, *up, *upkgs, *send, *uend;
1.52 + struct razor_transaction_package *packages, *tp;
1.53 + const char *spool, *upool;
1.54 + int i;
1.55 +
1.56 + spkgs = trans->system->packages.data;
1.57 + send = trans->system->packages.data + trans->system->packages.size;
1.58 + spool = trans->system->string_pool.data;
1.59 + upkgs = trans->upstream->packages.data;
1.60 + uend = trans->upstream->packages.data + trans->upstream->packages.size;
1.61 + upool = trans->upstream->string_pool.data;
1.62 +
1.63 + for (i = 0; i < update_count; i++) {
1.64 + tp = array_add(&trans->packages, sizeof *tp);
1.65 + memset(tp, 0, sizeof *tp);
1.66 + tp->name = update_packages[i];
1.67 + tp->state = RAZOR_PACKAGE_INSTALL;
1.68 }
1.69 -
1.70 - packages = (struct razor_package *) set->packages.data;
1.71 - pi = razor_package_iterator_create(set);
1.72 - found = zalloc(count * sizeof (int));
1.73 -
1.74 - while (razor_package_iterator_next(pi, &p, &name, &version)) {
1.75 - for (i = 0; i < count; i++) {
1.76 - if (strcmp(name, package_names[i]) == 0) {
1.77 - found[i] = 1;
1.78 - tp = array_add(&trans->packages, sizeof *tp);
1.79 - memset(tp, 0, sizeof *tp);
1.80 - tp->package = p;
1.81 - tp->name = name;
1.82 - tp->version = version;
1.83 - tp->state = state;
1.84 - bitarray_set(pkgbits, p - packages,
1.85 - state == RAZOR_PACKAGE_INSTALL);
1.86 - break;
1.87 + for (i = 0; i < remove_count; i++) {
1.88 + tp = array_add(&trans->packages, sizeof *tp);
1.89 + memset(tp, 0, sizeof *tp);
1.90 + tp->name = remove_packages[i];
1.91 + tp->state = RAZOR_PACKAGE_REMOVE;
1.92 + }
1.93 + qsort(trans->packages.data, update_count + remove_count,
1.94 + sizeof *tp, compare_transaction_packages);
1.95 + packages = trans->packages.data;
1.96 +
1.97 + sp = spkgs;
1.98 + up = upkgs;
1.99 + for (i = 0; i < update_count + remove_count; i++) {
1.100 + while (sp < send && strcmp(&spool[sp->name], packages[i].name) < 0)
1.101 + sp++;
1.102 + while (up < uend && strcmp(&upool[up->name], packages[i].name) < 0)
1.103 + up++;
1.104 +
1.105 + if (packages[i].state == RAZOR_PACKAGE_REMOVE) {
1.106 + if (sp < send && strcmp(packages[i].name, &spool[sp->name]) == 0) {
1.107 + packages[i].package = sp;
1.108 + packages[i].name = &spool[sp->name];
1.109 + packages[i].version = &spool[sp->version];
1.110 + bitarray_set(&trans->syspkgs, sp - spkgs, 0);
1.111 + } else {
1.112 + packages[i].name = strdup(packages[i].name);
1.113 + packages[i].state |= RAZOR_PACKAGE_UNAVAILABLE;
1.114 + trans->errors++;
1.115 + }
1.116 + } else {
1.117 + if (up < uend && strcmp(packages[i].name, &upool[up->name]) == 0) {
1.118 + if (sp < send && strcmp(packages[i].name, &spool[sp->name]) == 0) {
1.119 + if (versioncmp(&spool[sp->version], &upool[up->version]) >= 0) {
1.120 + /* FIXME: need a distinct error */
1.121 + packages[i].name = strdup(packages[i].name);
1.122 + packages[i].state |= RAZOR_PACKAGE_UNAVAILABLE;
1.123 + trans->errors++;
1.124 + continue;
1.125 + }
1.126 + bitarray_set(&trans->syspkgs, sp - spkgs, 0);
1.127 + }
1.128 + packages[i].package = up;
1.129 + packages[i].name = &upool[up->name];
1.130 + packages[i].version = &upool[up->version];
1.131 + bitarray_set(&trans->uppkgs, up - upkgs, 1);
1.132 + } else {
1.133 + packages[i].name = strdup(packages[i].name);
1.134 + packages[i].state |= RAZOR_PACKAGE_UNAVAILABLE;
1.135 + trans->errors++;
1.136 }
1.137 }
1.138 }
1.139 -
1.140 - for (i = 0; i < count; i++) {
1.141 - if (!found[i]) {
1.142 - tp = array_add(&trans->packages, sizeof *tp);
1.143 - memset(tp, 0, sizeof *tp);
1.144 - tp->name = strdup(package_names[i]);
1.145 - tp->state = state | RAZOR_PACKAGE_UNAVAILABLE;
1.146 - trans->errors++;
1.147 - }
1.148 - }
1.149 -
1.150 - razor_package_iterator_destroy(pi);
1.151 - free(found);
1.152 }
1.153
1.154 static void
1.155 find_all_packages(struct razor_transaction_resolver *trans)
1.156 {
1.157 struct razor_transaction_package *tp;
1.158 - struct razor_package *p, *packages, *u, *pend, *uend;
1.159 - char *pool, *upool;
1.160 -
1.161 - packages = trans->system->packages.data;
1.162 - pend = trans->system->packages.data + trans->system->packages.size;
1.163 - pool = trans->system->string_pool.data;
1.164 - u = trans->upstream->packages.data;
1.165 + struct razor_package *sp, *spkgs, *send, *up, *upkgs, *uend;
1.166 + const char *spool, *upool;
1.167 +
1.168 + spkgs = trans->system->packages.data;
1.169 + send = trans->system->packages.data + trans->system->packages.size;
1.170 + spool = trans->system->string_pool.data;
1.171 + up = upkgs = trans->upstream->packages.data;
1.172 uend = trans->upstream->packages.data + trans->upstream->packages.size;
1.173 upool = trans->upstream->string_pool.data;
1.174
1.175 - for (p = packages; p < pend; p++) {
1.176 - while (u < uend && strcmp(&pool[p->name], &upool[u->name]) > 0)
1.177 - u++;
1.178 - if (strcmp(&pool[p->name], &upool[u->name]) == 0) {
1.179 + for (sp = spkgs; sp < send; sp++) {
1.180 + while (up < uend && strcmp(&spool[sp->name], &upool[up->name]) > 0)
1.181 + up++;
1.182 + if (strcmp(&spool[sp->name], &upool[up->name]) == 0) {
1.183 tp = array_add(&trans->packages, sizeof *tp);
1.184 memset(tp, 0, sizeof *tp);
1.185 - tp->name = &upool[u->name];
1.186 - tp->version = &upool[u->version];
1.187 + tp->name = &upool[up->name];
1.188 + tp->version = &upool[up->version];
1.189 tp->state = RAZOR_PACKAGE_INSTALL;
1.190 - bitarray_set(&trans->uppkgs, p - packages, 1);
1.191 + bitarray_set(&trans->uppkgs, up - upkgs, 1);
1.192 + bitarray_set(&trans->syspkgs, sp - spkgs, 0);
1.193 }
1.194 }
1.195 }
1.196
1.197 -/* FIXME: wrong, need to compare names, not razor_package* */
1.198 -static int
1.199 -find_transaction_package(struct array *package_array,
1.200 - struct razor_package *package)
1.201 -{
1.202 - struct razor_transaction_package *tps = package_array->data;
1.203 - int i, tpcount = package_array->size / sizeof *tps;
1.204 -
1.205 - for (i = 0; i < tpcount; i++) {
1.206 - if (tps[i].package == package)
1.207 - return i;
1.208 - }
1.209 - return -1;
1.210 -}
1.211 -
1.212 static int
1.213 provider_satisfies_requirement(struct razor_property *provider,
1.214 const char *provider_strings,
1.215 @@ -1827,8 +1857,8 @@
1.216 }
1.217
1.218 static struct razor_package *
1.219 -find_file(struct razor_set *set, struct bitarray *pkgbits,
1.220 - const char *filename, int installed)
1.221 +find_package_for_file(struct razor_set *set, struct bitarray *pkgbits,
1.222 + const char *filename, int installed)
1.223 {
1.224 struct razor_package *pkgs = set->packages.data;
1.225 struct razor_entry *entry;
1.226 @@ -1849,179 +1879,278 @@
1.227 }
1.228
1.229 static struct razor_package *
1.230 -find_system_file(struct razor_transaction_resolver *trans,
1.231 - const char *filename, int installed)
1.232 +find_installed_package_for_file(struct razor_transaction_resolver *trans,
1.233 + const char *filename)
1.234 {
1.235 - return find_file(trans->system, &trans->syspkgs, filename, installed);
1.236 + struct razor_package *pkg;
1.237 +
1.238 + pkg = find_package_for_file(trans->system, &trans->syspkgs,
1.239 + filename, 1);
1.240 + if (!pkg)
1.241 + pkg = find_package_for_file(trans->upstream, &trans->uppkgs,
1.242 + filename, 1);
1.243 + return pkg;
1.244 }
1.245
1.246 static struct razor_package *
1.247 -find_upstream_file(struct razor_transaction_resolver *trans,
1.248 - const char *filename, int installed)
1.249 +find_uninstalled_package_for_file(struct razor_transaction_resolver *trans,
1.250 + const char *filename)
1.251 {
1.252 - return find_file(trans->upstream, &trans->uppkgs, filename, installed);
1.253 + struct razor_package *pkg;
1.254 +
1.255 + pkg = find_package_for_file(trans->upstream, &trans->uppkgs,
1.256 + filename, 0);
1.257 + if (!pkg)
1.258 + pkg = find_package_for_file(trans->system, &trans->syspkgs,
1.259 + filename, 0);
1.260 + return pkg;
1.261 }
1.262
1.263 static struct razor_package *
1.264 -find_system_provider(struct razor_transaction_resolver *trans,
1.265 - int installed, int match_name,
1.266 - struct razor_property *req, int *sp)
1.267 +find_package_matching(struct razor_transaction_resolver *trans, int installed,
1.268 + struct razor_property **start_prop,
1.269 + struct razor_property *req,
1.270 + struct razor_set *req_set)
1.271 {
1.272 - struct razor_package *spkgs = trans->system->packages.data;
1.273 - struct razor_property *sprops = trans->system->properties.data;
1.274 - const char *spool = trans->system->string_pool.data;
1.275 - const char *upool = trans->upstream->string_pool.data;
1.276 - int scount = trans->system->properties.size / sizeof *sprops;
1.277 -
1.278 - /* Skip ahead to first matching PROVIDES */
1.279 - while (*sp < scount &&
1.280 - strcmp(&spool[sprops[*sp].name], &upool[req->name]) < 0)
1.281 - (*sp)++;
1.282 - while (*sp < scount &&
1.283 - sprops[*sp].type != RAZOR_PROPERTY_PROVIDES &&
1.284 - strcmp(&spool[sprops[*sp].name], &upool[req->name]) == 0)
1.285 - (*sp)++;
1.286 -
1.287 - /* Scan matching PROVIDES */
1.288 - while (*sp < scount &&
1.289 - sprops[*sp].type == RAZOR_PROPERTY_PROVIDES &&
1.290 - strcmp(&spool[sprops[*sp].name],
1.291 - &upool[req->name]) == 0) {
1.292 - if (provider_satisfies_requirement(&sprops[*sp], spool,
1.293 - req, upool)) {
1.294 + struct razor_set *set;
1.295 + struct bitarray *pkgbits;
1.296 + struct razor_package *pkgs;
1.297 + struct razor_property *prop, *props, *prop_end;
1.298 + enum razor_property_type match_type;
1.299 + const char *pool;
1.300 + const char *rpool = req_set->string_pool.data;
1.301 + int match_name = (req->type == RAZOR_PROPERTY_OBSOLETES ||
1.302 + req->type == RAZOR_PROPERTY_CONFLICTS);
1.303 + int match;
1.304 +
1.305 + prop = *start_prop;
1.306 + if (property_in_set(prop, trans->system)) {
1.307 + set = trans->system;
1.308 + pkgbits = &trans->syspkgs;
1.309 + } else if (property_in_set(prop, trans->upstream)) {
1.310 + set = trans->upstream;
1.311 + pkgbits = &trans->uppkgs;
1.312 + } else
1.313 + return NULL;
1.314 +
1.315 + if (req->type == RAZOR_PROPERTY_PROVIDES)
1.316 + match_type = RAZOR_PROPERTY_CONFLICTS;
1.317 + else
1.318 + match_type = RAZOR_PROPERTY_PROVIDES;
1.319 +
1.320 + pkgs = set->packages.data;
1.321 + props = set->properties.data;
1.322 + prop_end = set->properties.data + set->properties.size;
1.323 + pool = set->string_pool.data;
1.324 +
1.325 + /* Find first matching property */
1.326 + while (prop < prop_end &&
1.327 + strcmp(&pool[prop->name], &rpool[req->name]) < 0)
1.328 + prop++;
1.329 + *start_prop = prop;
1.330 + if (prop == prop_end ||
1.331 + strcmp(&pool[prop->name], &rpool[req->name]) > 0)
1.332 + return NULL;
1.333 +
1.334 + if (prop->type < match_type) {
1.335 + while (prop < prop_end && prop->type != match_type)
1.336 + prop++;
1.337 + } else {
1.338 + while (prop >= props && prop->type != match_type)
1.339 + prop--;
1.340 + while (prop > props + 1 && (prop - 1)->type == match_type)
1.341 + prop--;
1.342 + }
1.343 +
1.344 + /* Scan matching proeprties */
1.345 + while (prop < prop_end && prop->type == match_type &&
1.346 + strcmp(&pool[prop->name], &rpool[req->name]) == 0) {
1.347 + if (match_type == RAZOR_PROPERTY_PROVIDES)
1.348 + match = provider_satisfies_requirement(prop, pool, req, rpool);
1.349 + else
1.350 + match = provider_satisfies_requirement(req, rpool, prop, pool);
1.351 + if (match) {
1.352 struct list *pkg;
1.353
1.354 - for (pkg = list_first(&sprops[*sp].packages, &trans->system->package_pool); pkg; pkg = list_next(pkg)) {
1.355 - if (bitarray_get(&trans->syspkgs, pkg->data) != installed)
1.356 + for (pkg = list_first(&prop->packages, &set->package_pool); pkg; pkg = list_next(pkg)) {
1.357 + if (bitarray_get(pkgbits, pkg->data) != installed)
1.358 continue;
1.359 if (!match_name ||
1.360 - strcmp(&spool[spkgs[pkg->data].name],
1.361 - &upool[req->name]) == 0)
1.362 - return &spkgs[pkg->data];
1.363 + strcmp(&pool[pkgs[pkg->data].name],
1.364 + &rpool[req->name]) == 0)
1.365 + return &pkgs[pkg->data];
1.366 }
1.367 }
1.368 - (*sp)++;
1.369 + prop++;
1.370 }
1.371
1.372 return NULL;
1.373 }
1.374
1.375 static struct razor_package *
1.376 -find_upstream_provider(struct razor_transaction_resolver *trans,
1.377 - int installed, int match_name,
1.378 - struct razor_property *req, int up)
1.379 +find_installed_package_for_property(struct razor_transaction_resolver *trans,
1.380 + struct razor_property **sys_sp,
1.381 + struct razor_property *req)
1.382 {
1.383 - struct razor_package *upkgs = trans->upstream->packages.data;
1.384 - struct razor_property *uprops = trans->upstream->properties.data;
1.385 - const char *upool = trans->upstream->string_pool.data;
1.386 - int ucount = trans->upstream->properties.size / sizeof *uprops;
1.387 -
1.388 - /* Skip to first matching provide */
1.389 - if (req->type < RAZOR_PROPERTY_PROVIDES) {
1.390 - while (up < ucount &&
1.391 - uprops[up].type != RAZOR_PROPERTY_PROVIDES)
1.392 - up++;
1.393 - } else {
1.394 - while (up >= 0 &&
1.395 - uprops[up].type != RAZOR_PROPERTY_PROVIDES)
1.396 - up--;
1.397 - while (up > 0 &&
1.398 - uprops[up - 1].type == RAZOR_PROPERTY_PROVIDES)
1.399 - up--;
1.400 - if (up < 0)
1.401 - return NULL;
1.402 - }
1.403 -
1.404 - /* Scan matching PROVIDES */
1.405 - while (up < ucount &&
1.406 - uprops[up].type == RAZOR_PROPERTY_PROVIDES &&
1.407 - uprops[up].name == req->name) {
1.408 - if (provider_satisfies_requirement(&uprops[up], upool,
1.409 - req, upool)) {
1.410 - struct list *pkg;
1.411 -
1.412 - for (pkg = list_first(&uprops[up].packages, &trans->upstream->package_pool); pkg; pkg = list_next(pkg)) {
1.413 - if (bitarray_get(&trans->uppkgs, pkg->data) != installed)
1.414 - continue;
1.415 - if (!match_name ||
1.416 - strcmp(&upool[upkgs[pkg->data].name],
1.417 - &upool[req->name]) == 0)
1.418 - return &upkgs[pkg->data];
1.419 - }
1.420 - }
1.421 - up++;
1.422 - }
1.423 - return NULL;
1.424 + struct razor_package *pkg;
1.425 +
1.426 + pkg = find_package_matching(trans, 1, sys_sp, req, trans->upstream);
1.427 + if (!pkg)
1.428 + pkg = find_package_matching(trans, 1, &req, req, trans->upstream);
1.429 + return pkg;
1.430 +}
1.431 +
1.432 +static struct razor_package *
1.433 +find_uninstalled_package_for_property(struct razor_transaction_resolver *trans,
1.434 + struct razor_property **sys_sp,
1.435 + struct razor_property *req)
1.436 +{
1.437 + struct razor_package *pkg;
1.438 +
1.439 + pkg = find_package_matching(trans, 0, sys_sp, req, trans->upstream);
1.440 + if (!pkg)
1.441 + pkg = find_package_matching(trans, 0, &req, req, trans->upstream);
1.442 + return pkg;
1.443 }
1.444
1.445 static struct razor_package *
1.446 find_upgrade(struct razor_transaction_resolver *trans,
1.447 - struct razor_property *obsolete, int up)
1.448 + struct razor_property *sp, struct razor_property *up)
1.449 {
1.450 - struct razor_property *uprops = trans->upstream->properties.data;
1.451 - const char *upool = trans->upstream->string_pool.data;
1.452 - struct razor_property req;
1.453 -
1.454 - if (uprops[up].relation > RAZOR_VERSION_EQUAL ||
1.455 - !upool[uprops[up].version])
1.456 + struct razor_property *conflict, req;
1.457 + struct razor_set *set;
1.458 + const char *pool;
1.459 +
1.460 + if (sp->type == RAZOR_PROPERTY_CONFLICTS) {
1.461 + conflict = sp;
1.462 + set = trans->system;
1.463 + } else {
1.464 + conflict = up;
1.465 + set = trans->upstream;
1.466 + }
1.467 + pool = set->string_pool.data;
1.468 +
1.469 + if (conflict->relation > RAZOR_VERSION_EQUAL ||
1.470 + !pool[conflict->version])
1.471 return NULL;
1.472
1.473 - memcpy(&req, obsolete, sizeof req);
1.474 + memcpy(&req, conflict, sizeof req);
1.475 req.type = RAZOR_PROPERTY_REQUIRES;
1.476 - if (uprops[up].relation == RAZOR_VERSION_LESS)
1.477 + if (conflict->relation == RAZOR_VERSION_LESS)
1.478 req.relation = RAZOR_VERSION_GREATER_OR_EQUAL;
1.479 else
1.480 req.relation = RAZOR_VERSION_GREATER;
1.481
1.482 - /* We need to rewind up, since OBSOLETES > PROVIDES, so we've
1.483 - * already gone past the possible upgrades.
1.484 - */
1.485 - while (up >= 0 &&
1.486 - uprops[up].type != RAZOR_PROPERTY_PROVIDES)
1.487 - up--;
1.488 - while (up > 0 &&
1.489 - uprops[up - 1].type == RAZOR_PROPERTY_PROVIDES)
1.490 - up--;
1.491 - if (up < 0)
1.492 + return find_package_matching(trans, 0, &up, &req, set);
1.493 +}
1.494 +
1.495 +/* FIXME */
1.496 +static struct razor_package *
1.497 +find_upgrade_for_installed_conflict(struct razor_transaction_resolver *trans,
1.498 + struct razor_package *conflicting_pkg,
1.499 + struct razor_property *provider)
1.500 +{
1.501 + struct razor_package *upkgs, *up, *uend;
1.502 + struct razor_property *uprops;
1.503 + const char *spool, *upool;
1.504 + struct list *prop;
1.505 +
1.506 + if (!package_in_set(conflicting_pkg, trans->system))
1.507 return NULL;
1.508
1.509 - return find_upstream_provider(trans, 0, 1, &req, up);
1.510 + up = upkgs = trans->upstream->packages.data;
1.511 + uend = trans->upstream->packages.data + trans->upstream->packages.size;
1.512 + upool = trans->upstream->string_pool.data;
1.513 + uprops = trans->upstream->properties.data;
1.514 + spool = trans->system->string_pool.data;
1.515 +
1.516 + while (up < uend &&
1.517 + strcmp(&upool[up->name], &spool[conflicting_pkg->name]) < 0)
1.518 + up++;
1.519 + if (up == uend || strcmp(&upool[up->name], &spool[conflicting_pkg->name]) != 0)
1.520 + return NULL;
1.521 +
1.522 + for (prop = list_first(&up->properties, &trans->system->property_pool); prop; prop = list_next(prop)) {
1.523 + if (uprops[prop->data].type == RAZOR_PROPERTY_CONFLICTS &&
1.524 + provider_satisfies_requirement(provider, upool, &uprops[prop->data], upool))
1.525 + return NULL;
1.526 + }
1.527 + return up;
1.528 +}
1.529 +
1.530 +/* FIXME */
1.531 +static int
1.532 +prop_is_being_installed(struct razor_transaction_resolver *trans,
1.533 + struct razor_property *prop)
1.534 +{
1.535 + struct list *pkg;
1.536 +
1.537 + for (pkg = list_first(&prop->packages, &trans->upstream->package_pool); pkg; pkg = list_next(pkg)) {
1.538 + if (bitarray_get(&trans->uppkgs, pkg->data))
1.539 + return 1;
1.540 + }
1.541 + return 0;
1.542 }
1.543
1.544 static void
1.545 add_transaction_package(struct razor_transaction_resolver *trans,
1.546 struct razor_package *package,
1.547 - struct razor_set *package_set,
1.548 enum razor_transaction_package_state state,
1.549 - struct razor_property *req_prop,
1.550 - struct razor_set *req_set)
1.551 + const char *req_package,
1.552 + struct razor_property *req_prop)
1.553 {
1.554 - struct razor_transaction_package *tp;
1.555 + struct razor_set *package_set;
1.556 + struct razor_transaction_package *tp, *packages;
1.557 const char *pool;
1.558 struct razor_package *pkgs;
1.559 struct list *pkg;
1.560
1.561 + package_set = package_in_set(package, trans->system) ? trans->system : trans->upstream;
1.562 +
1.563 tp = array_add(&trans->packages, sizeof *tp);
1.564 memset(tp, 0, sizeof *tp);
1.565
1.566 if (package) {
1.567 + int i, count;
1.568 +
1.569 + /* Make sure we aren't already acting on this package */
1.570 + packages = trans->packages.data;
1.571 + count = trans->packages.size / sizeof *packages;
1.572 + pool = package_set->string_pool.data;
1.573 + for (i = 0; i < count; i++) {
1.574 + if (packages[i].name &&
1.575 + !strcmp(packages[i].name, &pool[package->name])) {
1.576 + if (state == packages[i].state) {
1.577 + /* Already taken care of */
1.578 + return;
1.579 + }
1.580 + /* Oops. We lose */
1.581 + state |= RAZOR_PACKAGE_BLOCKED;
1.582 + break;
1.583 + }
1.584 + }
1.585 +
1.586 tp->package = package;
1.587 - pool = package_set->string_pool.data;
1.588 tp->name = &pool[package->name];
1.589 tp->version = &pool[package->version];
1.590 tp->state = state;
1.591 } else
1.592 tp->state = state | RAZOR_PACKAGE_UNSATISFIABLE;
1.593
1.594 - for (pkg = list_first(&req_prop->packages, &req_set->package_pool); pkg; pkg = list_next(pkg)) {
1.595 - if (bitarray_get(&trans->uppkgs, pkg->data))
1.596 - break;
1.597 + if (req_package)
1.598 + tp->req_package = req_package;
1.599 + else {
1.600 + for (pkg = list_first(&req_prop->packages, &trans->upstream->package_pool); pkg; pkg = list_next(pkg)) {
1.601 + if (bitarray_get(&trans->uppkgs, pkg->data))
1.602 + break;
1.603 + }
1.604 + if (pkg) {
1.605 + pool = trans->upstream->string_pool.data;
1.606 + pkgs = trans->upstream->packages.data;
1.607 + tp->req_package = &pool[pkgs[pkg->data].name];
1.608 + }
1.609 }
1.610 - if (pkg) {
1.611 - pool = req_set->string_pool.data;
1.612 - pkgs = req_set->packages.data;
1.613 - tp->req_package = &pool[pkgs[pkg->data].name];
1.614 - }
1.615 +
1.616 tp->req_type = req_prop->type;
1.617 tp->req_property = &pool[req_prop->name];
1.618 tp->req_relation = req_prop->relation;
1.619 @@ -2036,57 +2165,61 @@
1.620 trans->errors++;
1.621 }
1.622
1.623 -/* FIXME */
1.624 -static int
1.625 -prop_is_being_installed(struct razor_transaction_resolver *trans,
1.626 - struct razor_property *prop)
1.627 +/* FIXME: make this more efficient */
1.628 +static void
1.629 +maybe_mark_upgraded(struct razor_transaction_resolver *trans,
1.630 + struct razor_package *pkg)
1.631 {
1.632 - struct list *pkg;
1.633 -
1.634 - for (pkg = list_first(&prop->packages, &trans->upstream->package_pool); pkg; pkg = list_next(pkg)) {
1.635 - if (bitarray_get(&trans->uppkgs, pkg->data))
1.636 - return 1;
1.637 - }
1.638 - return 0;
1.639 + struct razor_package *spkgs, *sp, *send;
1.640 + const char *spool, *upool;
1.641 +
1.642 + sp = spkgs = trans->system->packages.data;
1.643 + send = trans->system->packages.data + trans->system->packages.size;
1.644 + spool = trans->system->string_pool.data;
1.645 + upool = trans->upstream->string_pool.data;
1.646 +
1.647 + while (sp < send &&
1.648 + strcmp(&spool[sp->name], &upool[pkg->name]) < 0)
1.649 + sp++;
1.650 + if (sp < send && strcmp(&spool[sp->name], &upool[pkg->name]) == 0)
1.651 + bitarray_set(&trans->syspkgs, sp - spkgs, 0);
1.652 }
1.653
1.654 static void
1.655 razor_transaction_satisfy_installs(struct razor_transaction_resolver *trans)
1.656 {
1.657 - struct razor_package *spkgs, *upkgs, *pkg;
1.658 - struct razor_property *prop, *sprops, *uprops;
1.659 - int sp, up, ucount;
1.660 + struct razor_package *spkgs, *upkgs, *pkg, *upgrade;
1.661 + struct razor_property *sp, *sprops, *sprop_end;
1.662 + struct razor_property *up, *uprops, *uprop_end;
1.663 const char *upool;
1.664
1.665 spkgs = trans->system->packages.data;
1.666 sprops = trans->system->properties.data;
1.667 + sprop_end = trans->system->properties.data + trans->system->properties.size;
1.668 upkgs = trans->upstream->packages.data;
1.669 uprops = trans->upstream->properties.data;
1.670 - ucount = trans->upstream->properties.size / sizeof *uprops;
1.671 + uprop_end = trans->upstream->properties.data + trans->upstream->properties.size;
1.672 upool = trans->upstream->string_pool.data;
1.673
1.674 - sp = up = 0;
1.675 - while (up < ucount) {
1.676 + sp = sprops;
1.677 + up = uprops;
1.678 + while (up < uprop_end) {
1.679 /* Skip 'up' ahead to a property of a package which is
1.680 * to-be-installed.
1.681 */
1.682 - while (up < ucount &&
1.683 - (uprops[up].type == RAZOR_PROPERTY_PROVIDES ||
1.684 - !prop_is_being_installed(trans, &uprops[up])))
1.685 + while (up < uprop_end &&
1.686 + !prop_is_being_installed(trans, up))
1.687 up++;
1.688 - if (up == ucount)
1.689 + if (up == uprop_end)
1.690 break;
1.691
1.692 - prop = &uprops[up];
1.693 - switch (prop->type) {
1.694 + switch (up->type) {
1.695 case RAZOR_PROPERTY_REQUIRES:
1.696 - if (!strncmp(&upool[prop->name], "rpmlib(", 7))
1.697 + if (!strncmp(&upool[up->name], "rpmlib(", 7))
1.698 break;
1.699
1.700 - if (find_system_provider(trans, 1, 0, prop, &sp) ||
1.701 - find_upstream_provider(trans, 1, 0, prop, up) ||
1.702 - find_system_file(trans, &upool[prop->name], 1) ||
1.703 - find_upstream_file(trans, &upool[prop->name], 1)) {
1.704 + if (find_installed_package_for_property(trans, &sp, up) ||
1.705 + find_installed_package_for_file(trans, &upool[up->name])) {
1.706 /* Requires something that is either installed
1.707 * or to-be-installed.
1.708 */
1.709 @@ -2094,56 +2227,87 @@
1.710 }
1.711
1.712 /* See if we can install a new upstream provider */
1.713 - pkg = find_upstream_provider(trans, 0, 0, prop, up);
1.714 + pkg = find_uninstalled_package_for_property(trans, &sp, up);
1.715 + if (!pkg) {
1.716 + pkg = find_uninstalled_package_for_file(trans, &upool[up->name]);
1.717 + if (pkg) {
1.718 + /* FIXME: find a way to do this more efficiently */
1.719 + maybe_mark_upgraded(trans, pkg);
1.720 + }
1.721 + }
1.722 + add_transaction_package(trans, pkg,
1.723 + RAZOR_PACKAGE_INSTALL,
1.724 + NULL, up);
1.725 + break;
1.726 +
1.727 + case RAZOR_PROPERTY_PROVIDES:
1.728 + /* find_installed_package_for_property works backwards
1.729 + * here, finding a *conflicting* installed package.
1.730 + */
1.731 + pkg = find_installed_package_for_property(trans, &sp, up);
1.732 if (!pkg)
1.733 - pkg = find_upstream_file(trans, &upool[prop->name], 0);
1.734 - add_transaction_package(trans, pkg, trans->upstream,
1.735 - RAZOR_PACKAGE_INSTALL,
1.736 - prop, trans->upstream);
1.737 + break;
1.738 +
1.739 + /* pkg CONFLICTS with what 'up' PROVIDES. Try
1.740 + * finding an upgrade
1.741 + */
1.742 + upgrade = find_upgrade_for_installed_conflict(trans, pkg, up);
1.743 + if (upgrade) {
1.744 + bitarray_set(&trans->syspkgs, pkg - spkgs, 0);
1.745 + add_transaction_package(trans, upgrade,
1.746 + RAZOR_PACKAGE_INSTALL,
1.747 + NULL, up);
1.748 + } else {
1.749 + add_transaction_package(trans, pkg,
1.750 + /* FIXME? */
1.751 + RAZOR_PACKAGE_REMOVE_CONFLICT,
1.752 + NULL, up);
1.753 + }
1.754 break;
1.755
1.756 case RAZOR_PROPERTY_CONFLICTS:
1.757 - if ((pkg = find_system_provider(trans, 1, 1, prop, &sp))) {
1.758 - struct razor_package *upgrade;
1.759 -
1.760 + pkg = find_installed_package_for_property(trans, &sp, up);
1.761 + if (!pkg)
1.762 + break;
1.763 +
1.764 + if (package_in_set(pkg, trans->system)) {
1.765 /* Conflicts with something already installed.
1.766 * Try to upgrade out.
1.767 */
1.768 - upgrade = find_upgrade(trans, prop, up);
1.769 + upgrade = find_upgrade(trans, sp, up);
1.770 if (upgrade) {
1.771 bitarray_set(&trans->syspkgs, pkg - spkgs, 0);
1.772 add_transaction_package(trans, upgrade,
1.773 - trans->upstream,
1.774 RAZOR_PACKAGE_INSTALL,
1.775 - prop, trans->upstream);
1.776 + NULL, up);
1.777 } else {
1.778 add_transaction_package(trans, pkg,
1.779 - trans->system,
1.780 RAZOR_PACKAGE_INSTALL_CONFLICT,
1.781 - prop, trans->upstream);
1.782 + NULL, up);
1.783 }
1.784 - } else if ((pkg = find_upstream_provider(trans, 1, 1, prop, up))) {
1.785 + } else {
1.786 /* Conflicts with something already to-be-installed */
1.787 add_transaction_package(trans, pkg,
1.788 - trans->upstream,
1.789 RAZOR_PACKAGE_INSTALL_CONFLICT,
1.790 - prop, trans->upstream);
1.791 + NULL, up);
1.792 }
1.793 break;
1.794
1.795 case RAZOR_PROPERTY_OBSOLETES:
1.796 - if ((pkg = find_system_provider(trans, 1, 1, prop, &sp))) {
1.797 + pkg = find_installed_package_for_property(trans, &sp, up);
1.798 + if (!pkg)
1.799 + break;
1.800 +
1.801 + if (package_in_set(pkg, trans->system)) {
1.802 /* Obsoletes something installed */
1.803 add_transaction_package(trans, pkg,
1.804 - trans->system,
1.805 RAZOR_PACKAGE_REMOVE,
1.806 - prop, trans->upstream);
1.807 - } else if ((pkg = find_upstream_provider(trans, 1, 1, prop, up))) {
1.808 + NULL, up);
1.809 + } else {
1.810 /* Obsoletes something that was to-be-installed */
1.811 add_transaction_package(trans, pkg,
1.812 - trans->upstream,
1.813 RAZOR_PACKAGE_REMOVE_CONFLICT,
1.814 - prop, trans->upstream);
1.815 + NULL, up);
1.816 }
1.817 break;
1.818
1.819 @@ -2204,36 +2368,14 @@
1.820 struct razor_package *pkgs, *lost_package;
1.821 char *pool = trans->system->string_pool.data;
1.822 struct list *p;
1.823 - struct razor_transaction_package *tp, *packages;;
1.824 - int already;
1.825
1.826 pkgs = trans->system->packages.data;
1.827 lost_package = &pkgs[list_first(lost_package_list, &trans->system->package_pool)->data];
1.828
1.829 for (p = list_first(&req->packages, &trans->system->package_pool); p; p = list_next(p)) {
1.830 - packages = trans->packages.data;
1.831 - already = find_transaction_package(&trans->packages, &pkgs[p->data]);
1.832 - if (already != -1 &&
1.833 - (packages[already].state & RAZOR_PACKAGE_REMOVE))
1.834 - continue;
1.835 -
1.836 - tp = array_add(&trans->packages, sizeof *tp);
1.837 - memset(tp, 0, sizeof *tp);
1.838 - tp->package = &pkgs[p->data];
1.839 - tp->name = &pool[tp->package->name];
1.840 - tp->version = &pool[tp->package->version];
1.841 - tp->req_package = &pool[lost_package->name];
1.842 - tp->req_type = req->type;
1.843 - tp->req_property = &pool[req->name];
1.844 - tp->req_relation = req->relation;
1.845 - tp->req_version = &pool[req->version];
1.846 - if (already != -1) {
1.847 - tp->state = RAZOR_PACKAGE_REMOVE_BLOCKED;
1.848 - trans->errors++;
1.849 - } else {
1.850 - tp->state = RAZOR_PACKAGE_REMOVE;
1.851 - bitarray_set(&trans->syspkgs, p->data, 0);
1.852 - }
1.853 + add_transaction_package(trans, &pkgs[p->data],
1.854 + RAZOR_PACKAGE_REMOVE,
1.855 + &pool[lost_package->name], req);
1.856 }
1.857 }
1.858
1.859 @@ -2280,11 +2422,11 @@
1.860 props = trans->system->properties.data;
1.861 prop_end = trans->system->properties.data + trans->system->properties.size;
1.862 pool = trans->system->string_pool.data;
1.863 + packages = trans->packages.data;
1.864
1.865 array_init(&lost_files);
1.866 array_init(&lost_provides);
1.867 for (r = start; r < end; r++) {
1.868 - packages = trans->packages.data;
1.869 if (packages[r].state != RAZOR_PACKAGE_REMOVE)
1.870 continue;
1.871
1.872 @@ -2401,19 +2543,13 @@
1.873 bitarray_init(&trans.uppkgs, trans.upstream->packages.size / sizeof (struct razor_package), 0);
1.874 trans.errors = 0;
1.875
1.876 - /* Find initial upstream packages to be installed */
1.877 - if (update_count > 0) {
1.878 - find_packages(&trans, update_count, update_packages,
1.879 - RAZOR_PACKAGE_INSTALL);
1.880 - } else if (remove_count == 0)
1.881 + if (update_count > 0 || remove_count > 0) {
1.882 + find_packages(&trans,
1.883 + update_count, update_packages,
1.884 + remove_count, remove_packages);
1.885 + } else
1.886 find_all_packages(&trans);
1.887
1.888 - /* Find initial installed packages to remove. */
1.889 - if (remove_count > 0) {
1.890 - find_packages(&trans, remove_count, remove_packages,
1.891 - RAZOR_PACKAGE_REMOVE);
1.892 - }
1.893 -
1.894 start = 0;
1.895 end = trans.packages.size / sizeof (struct razor_transaction_package);
1.896
1.897 @@ -2483,24 +2619,26 @@
1.898 break;
1.899
1.900 case RAZOR_PACKAGE_INSTALL_UNAVAILABLE:
1.901 - if (*p->req_version && strcmp(p->req_property, p->name) == 0) {
1.902 - printf ("Can't find %s %s %s, which is required by %s",
1.903 - p->name,
1.904 - razor_version_relations[p->req_relation],
1.905 - p->req_version,
1.906 - p->req_package);
1.907 - } else {
1.908 - printf ("Can't find %s", p->name);
1.909 - if (*p->version)
1.910 - printf (" %s", p->version);
1.911 -
1.912 - if (p->req_package) {
1.913 - printf (" which is required by %s",
1.914 + printf ("Can't find %s", p->name);
1.915 + if (p->req_package) {
1.916 + if (*p->req_version && strcmp(p->req_property, p->name) == 0) {
1.917 + printf ("%s %s, which is required by %s",
1.918 + razor_version_relations[p->req_relation],
1.919 + p->req_version,
1.920 p->req_package);
1.921 - if (strcmp(p->req_property, p->name) != 0)
1.922 - printf (" for %s", p->req_property);
1.923 + } else {
1.924 + if (*p->version)
1.925 + printf (" %s", p->version);
1.926 +
1.927 + if (p->req_package) {
1.928 + printf (" which is required by %s",
1.929 + p->req_package);
1.930 + if (strcmp(p->req_property, p->name) != 0)
1.931 + printf (" for %s", p->req_property);
1.932 + }
1.933 }
1.934 - }
1.935 + } else if (p->version && *p->version)
1.936 + printf (" %s", p->version);
1.937 printf("\n");
1.938 errors_only = 1;
1.939 break;