1.1 --- a/razor.c Wed Mar 05 19:01:51 2008 -0500
1.2 +++ b/razor.c Wed Mar 05 19:02:29 2008 -0500
1.3 @@ -1794,9 +1794,9 @@
1.4
1.5 if (packages[i].state == RAZOR_PACKAGE_REMOVE) {
1.6 if (sp < send && strcmp(packages[i].name, &spool[sp->name]) == 0) {
1.7 - packages[i].package = sp;
1.8 + packages[i].old_package = sp;
1.9 packages[i].name = &spool[sp->name];
1.10 - packages[i].version = &spool[sp->version];
1.11 + packages[i].old_version = &spool[sp->version];
1.12 bitarray_set(&trans->syspkgs, sp - spkgs, 0);
1.13 } else {
1.14 packages[i].name = strdup(packages[i].name);
1.15 @@ -1805,10 +1805,12 @@
1.16 }
1.17 } else {
1.18 if (up < uend && strcmp(packages[i].name, &upool[up->name]) == 0) {
1.19 - packages[i].package = up;
1.20 + packages[i].new_package = up;
1.21 packages[i].name = &upool[up->name];
1.22 - packages[i].version = &upool[up->version];
1.23 + packages[i].new_version = &upool[up->version];
1.24 if (sp < send && strcmp(packages[i].name, &spool[sp->name]) == 0) {
1.25 + packages[i].old_package = sp;
1.26 + packages[i].old_version = &spool[sp->version];
1.27 if (versioncmp(&spool[sp->version], &upool[up->version]) >= 0) {
1.28 packages[i].state = RAZOR_PACKAGE_UP_TO_DATE;
1.29 trans->errors++;
1.30 @@ -1846,8 +1848,11 @@
1.31 if (strcmp(&spool[sp->name], &upool[up->name]) == 0) {
1.32 tp = array_add(&trans->packages, sizeof *tp);
1.33 memset(tp, 0, sizeof *tp);
1.34 + tp->old_package = sp;
1.35 + tp->new_package = up;
1.36 tp->name = &upool[up->name];
1.37 - tp->version = &upool[up->version];
1.38 + tp->old_version = &spool[sp->version];
1.39 + tp->new_version = &upool[up->version];
1.40 tp->state = RAZOR_PACKAGE_INSTALL;
1.41 bitarray_set(&trans->uppkgs, up - upkgs, 1);
1.42 bitarray_set(&trans->syspkgs, sp - spkgs, 0);
1.43 @@ -2136,21 +2141,52 @@
1.44 return 0;
1.45 }
1.46
1.47 +static struct razor_transaction_package *
1.48 +find_transaction_package(struct razor_transaction_resolver *trans,
1.49 + const char *name)
1.50 +{
1.51 + struct razor_transaction_package *packages;
1.52 + int count, i;
1.53 +
1.54 + packages = trans->packages.data;
1.55 + count = trans->packages.size / sizeof *packages;
1.56 + for (i = 0; i < count; i++) {
1.57 + if (packages[i].name && !strcmp(packages[i].name, name))
1.58 + return &packages[i];
1.59 + }
1.60 + return NULL;
1.61 +}
1.62 +
1.63 static void
1.64 add_transaction_package(struct razor_transaction_resolver *trans,
1.65 - struct razor_package *package,
1.66 + struct razor_package *new_package,
1.67 + struct razor_package *old_package,
1.68 enum razor_transaction_package_state state,
1.69 const char *req_package,
1.70 struct razor_property *req_prop)
1.71 {
1.72 - struct razor_set *package_set, *req_set;
1.73 - struct bitarray *reqpkgbits;
1.74 - struct razor_transaction_package *tp, *packages;
1.75 + struct razor_set *new_package_set, *old_package_set, *req_set;
1.76 + struct bitarray *newpkgbits, *oldpkgbits, *reqpkgbits;
1.77 + struct razor_transaction_package *tp, *already;
1.78 const char *pool;
1.79 struct razor_package *pkgs;
1.80 struct list *pkg;
1.81 -
1.82 - package_set = package_in_set(package, trans->system) ? trans->system : trans->upstream;
1.83 + int contradiction = 0;
1.84 +
1.85 + if (package_in_set(new_package, trans->system)) {
1.86 + new_package_set = trans->system;
1.87 + newpkgbits = &trans->syspkgs;
1.88 + } else {
1.89 + new_package_set = trans->upstream;
1.90 + newpkgbits = &trans->uppkgs;
1.91 + }
1.92 + if (package_in_set(old_package, trans->system)) {
1.93 + old_package_set = trans->system;
1.94 + oldpkgbits = &trans->syspkgs;
1.95 + } else {
1.96 + old_package_set = trans->upstream;
1.97 + oldpkgbits = &trans->uppkgs;
1.98 + }
1.99 if (property_in_set(req_prop, trans->system)) {
1.100 req_set = trans->system;
1.101 reqpkgbits = &trans->syspkgs;
1.102 @@ -2159,48 +2195,67 @@
1.103 reqpkgbits = &trans->uppkgs;
1.104 }
1.105
1.106 + if (new_package) {
1.107 + pool = new_package_set->string_pool.data;
1.108 + already = find_transaction_package(trans, &pool[new_package->name]);
1.109 + if (already) {
1.110 + if (already->new_package == new_package) {
1.111 + /* Already taken care of */
1.112 + return;
1.113 + }
1.114 + /* Oops. We lose */
1.115 + if (state != RAZOR_PACKAGE_CONTRADICTION)
1.116 + contradiction = 1;
1.117 + }
1.118 + } else if (old_package) {
1.119 + pool = old_package_set->string_pool.data;
1.120 + already = find_transaction_package(trans, &pool[old_package->name]);
1.121 + if (already) {
1.122 + if (already->old_package == old_package) {
1.123 + /* Already taken care of */
1.124 + return;
1.125 + }
1.126 + /* Oops. We lose */
1.127 + if (state != RAZOR_PACKAGE_CONTRADICTION)
1.128 + contradiction = 1;
1.129 + }
1.130 + } else
1.131 + state = RAZOR_PACKAGE_UNSATISFIABLE;
1.132 +
1.133 tp = array_add(&trans->packages, sizeof *tp);
1.134 memset(tp, 0, sizeof *tp);
1.135
1.136 - if (package) {
1.137 - int i, count;
1.138 -
1.139 - /* Make sure we aren't already acting on this package */
1.140 - packages = trans->packages.data;
1.141 - count = trans->packages.size / sizeof *packages;
1.142 - pool = package_set->string_pool.data;
1.143 - for (i = 0; i < count; i++) {
1.144 - if (packages[i].name &&
1.145 - !strcmp(packages[i].name, &pool[package->name])) {
1.146 - if (state == packages[i].state) {
1.147 - /* Already taken care of */
1.148 - return;
1.149 - }
1.150 - /* Oops. We lose */
1.151 - if (state != RAZOR_PACKAGE_CONTRADICTION) {
1.152 - add_transaction_package(trans, package,
1.153 - RAZOR_PACKAGE_CONTRADICTION,
1.154 - NULL, NULL);
1.155 - }
1.156 - break;
1.157 - }
1.158 - }
1.159 -
1.160 - tp->package = package;
1.161 - tp->name = &pool[package->name];
1.162 - tp->version = &pool[package->version];
1.163 - tp->state = state;
1.164 -
1.165 - pkgs = package_set->packages.data;
1.166 - if (tp->state == RAZOR_PACKAGE_INSTALL)
1.167 - bitarray_set(&trans->uppkgs, package - pkgs, 1);
1.168 - else if (tp->state == RAZOR_PACKAGE_REMOVE)
1.169 - bitarray_set(&trans->syspkgs, package - pkgs, 0);
1.170 - else
1.171 - trans->errors++;
1.172 - } else {
1.173 - tp->state = RAZOR_PACKAGE_UNSATISFIABLE;
1.174 + if (new_package) {
1.175 + pool = new_package_set->string_pool.data;
1.176 + tp->new_package = new_package;
1.177 + tp->name = &pool[new_package->name];
1.178 + tp->new_version = &pool[new_package->version];
1.179 +
1.180 + pkgs = new_package_set->packages.data;
1.181 + bitarray_set(newpkgbits, new_package - pkgs, 1);
1.182 + }
1.183 + if (old_package) {
1.184 + pool = old_package_set->string_pool.data;
1.185 + tp->old_package = old_package;
1.186 + tp->name = &pool[old_package->name];
1.187 + tp->old_version = &pool[old_package->version];
1.188 +
1.189 + pkgs = old_package_set->packages.data;
1.190 + bitarray_set(oldpkgbits, old_package - pkgs, 0);
1.191 + }
1.192 +
1.193 + tp->state = state;
1.194 + if (state != RAZOR_PACKAGE_INSTALL &&
1.195 + state != RAZOR_PACKAGE_REMOVE)
1.196 trans->errors++;
1.197 +
1.198 + if (contradiction) {
1.199 + /* Do this now, after adding tp, so that it ends up
1.200 + * after both the INSTALL and the REMOVE in the array.
1.201 + */
1.202 + add_transaction_package(trans, new_package, old_package,
1.203 + RAZOR_PACKAGE_CONTRADICTION,
1.204 + NULL, NULL);
1.205 }
1.206
1.207 if (req_package)
1.208 @@ -2245,6 +2300,30 @@
1.209 bitarray_set(&trans->syspkgs, sp - spkgs, 0);
1.210 }
1.211
1.212 +/* FIXME: this too */
1.213 +static struct razor_package *
1.214 +find_old_version(struct razor_transaction_resolver *trans,
1.215 + struct razor_package *pkg)
1.216 +{
1.217 + struct razor_package *spkgs, *sp, *send;
1.218 + const char *spool, *upool;
1.219 +
1.220 + if (!package_in_set(pkg, trans->upstream))
1.221 + return NULL;
1.222 +
1.223 + sp = spkgs = trans->system->packages.data;
1.224 + send = trans->system->packages.data + trans->system->packages.size;
1.225 + spool = trans->system->string_pool.data;
1.226 + upool = trans->upstream->string_pool.data;
1.227 +
1.228 + while (sp < send &&
1.229 + strcmp(&spool[sp->name], &upool[pkg->name]) < 0)
1.230 + sp++;
1.231 + if (sp < send && strcmp(&spool[sp->name], &upool[pkg->name]) == 0)
1.232 + return sp;
1.233 + return NULL;
1.234 +}
1.235 +
1.236 static void
1.237 razor_transaction_satisfy_installs(struct razor_transaction_resolver *trans)
1.238 {
1.239 @@ -2296,7 +2375,7 @@
1.240 maybe_mark_upgraded(trans, pkg);
1.241 }
1.242 }
1.243 - add_transaction_package(trans, pkg,
1.244 + add_transaction_package(trans, pkg, find_old_version(trans, pkg),
1.245 RAZOR_PACKAGE_INSTALL,
1.246 NULL, up);
1.247 break;
1.248 @@ -2316,14 +2395,14 @@
1.249 upgrade = find_upgrade_for_installed_conflict(trans, pkg, up);
1.250 if (upgrade) {
1.251 bitarray_set(&trans->syspkgs, pkg - spkgs, 0);
1.252 - add_transaction_package(trans, upgrade,
1.253 + add_transaction_package(trans, upgrade, pkg,
1.254 RAZOR_PACKAGE_INSTALL,
1.255 &spool[pkg->name], sp);
1.256 }
1.257 break;
1.258 }
1.259
1.260 - add_transaction_package(trans, pkg,
1.261 + add_transaction_package(trans, NULL, pkg,
1.262 RAZOR_PACKAGE_OLD_CONFLICT,
1.263 NULL, up);
1.264 break;
1.265 @@ -2340,14 +2419,14 @@
1.266 upgrade = find_upgrade(trans, sp, up);
1.267 if (upgrade) {
1.268 bitarray_set(&trans->syspkgs, pkg - spkgs, 0);
1.269 - add_transaction_package(trans, upgrade,
1.270 + add_transaction_package(trans, upgrade, pkg,
1.271 RAZOR_PACKAGE_INSTALL,
1.272 NULL, up);
1.273 break;
1.274 }
1.275 }
1.276
1.277 - add_transaction_package(trans, pkg,
1.278 + add_transaction_package(trans, pkg, NULL,
1.279 RAZOR_PACKAGE_NEW_CONFLICT,
1.280 NULL, up);
1.281 break;
1.282 @@ -2358,7 +2437,7 @@
1.283 /* If pkg is to-be-installed, this
1.284 * will add a CONTRADICTION error as well.
1.285 */
1.286 - add_transaction_package(trans, pkg,
1.287 + add_transaction_package(trans, NULL, pkg,
1.288 RAZOR_PACKAGE_REMOVE,
1.289 NULL, up);
1.290 }
1.291 @@ -2426,7 +2505,7 @@
1.292 lost_package = &pkgs[list_first(lost_package_list, &trans->system->package_pool)->data];
1.293
1.294 for (p = list_first(&req->packages, &trans->system->package_pool); p; p = list_next(p)) {
1.295 - add_transaction_package(trans, &pkgs[p->data],
1.296 + add_transaction_package(trans, NULL, &pkgs[p->data],
1.297 RAZOR_PACKAGE_REMOVE,
1.298 &pool[lost_package->name], req);
1.299 }
1.300 @@ -2480,12 +2559,14 @@
1.301 array_init(&lost_files);
1.302 array_init(&lost_provides);
1.303 for (r = start; r < end; r++) {
1.304 - if (packages[r].state != RAZOR_PACKAGE_REMOVE)
1.305 + if (!packages[r].old_package ||
1.306 + (packages[r].state != RAZOR_PACKAGE_REMOVE &&
1.307 + packages[r].state != RAZOR_PACKAGE_INSTALL))
1.308 continue;
1.309
1.310 - gather_lost_provides(trans->system, packages[r].package,
1.311 + gather_lost_provides(trans->system, packages[r].old_package,
1.312 &lost_provides);
1.313 - gather_lost_files(trans->system, packages[r].package,
1.314 + gather_lost_files(trans->system, packages[r].old_package,
1.315 &lost_files);
1.316 }
1.317
1.318 @@ -2601,12 +2682,12 @@
1.319 if (errors_only)
1.320 break;
1.321
1.322 - printf("Installing %s %s", p->name, p->version);
1.323 + printf("Installing %s %s", p->name, p->new_version);
1.324 if (p->dep_package) {
1.325 if (p->dep_type == RAZOR_PROPERTY_CONFLICTS &&
1.326 !strcmp(p->dep_package, p->name)) {
1.327 - printf(" because installed %s conflicts with %s",
1.328 - p->name, p->dep_property);
1.329 + printf(" because %s %s conflicts with %s",
1.330 + p->name, p->old_version, p->dep_property);
1.331 if (*p->dep_version) {
1.332 printf(" %s %s",
1.333 razor_version_relations[p->dep_relation],
1.334 @@ -2633,7 +2714,7 @@
1.335 case RAZOR_PACKAGE_REMOVE:
1.336 if (errors_only)
1.337 break;
1.338 - printf("Removing %s %s", p->name, p->version);
1.339 + printf("Removing %s %s", p->name, p->old_version);
1.340 if (p->dep_package) {
1.341 if (p->dep_type == RAZOR_PROPERTY_OBSOLETES) {
1.342 printf(" which is obsoleted by %s",
1.343 @@ -2659,12 +2740,12 @@
1.344 break;
1.345
1.346 case RAZOR_PACKAGE_UP_TO_DATE:
1.347 - printf("Error: can't upgrade %s: no newer version is available", p->name);
1.348 + printf("Error: can't upgrade %s: %s is most recent version\n", p->name, p->old_version);
1.349 errors_only = 1;
1.350 break;
1.351
1.352 case RAZOR_PACKAGE_CONTRADICTION:
1.353 - printf("Error: package %s is marked for both installation and removal", p->name);
1.354 + printf("Error: package %s is marked for both installation and removal\n", p->name);
1.355 errors_only = 1;
1.356 break;
1.357
1.358 @@ -2734,11 +2815,13 @@
1.359 array_init(&install_packages);
1.360 array_init(&remove_packages);
1.361 for (p = 0; p < trans->package_count; p++) {
1.362 - if (trans->packages[p].state == RAZOR_PACKAGE_INSTALL)
1.363 + if (trans->packages[p].state == RAZOR_PACKAGE_INSTALL) {
1.364 pkg = array_add(&install_packages, sizeof *pkg);
1.365 - else
1.366 + *pkg = *trans->packages[p].new_package;
1.367 + } else {
1.368 pkg = array_add(&remove_packages, sizeof *pkg);
1.369 - *pkg = *trans->packages[p].package;
1.370 + *pkg = *trans->packages[p].old_package;
1.371 + }
1.372 }
1.373 map = qsort_with_data(install_packages.data,
1.374 install_packages.size / sizeof *pkg,