1 /* 2 * Copyright (c) 2008, Novell Inc. 3 * 4 * This program is licensed under the BSD license, read LICENSE.BSD 5 * for further information 6 */ 7 8 /* 9 * solverdebug.c 10 * 11 * debug functions for the SAT solver 12 */ 13 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <unistd.h> 17 #include <string.h> 18 #include <assert.h> 19 20 #include "solver.h" 21 #include "solver_private.h" 22 #include "solverdebug.h" 23 #include "bitmap.h" 24 #include "pool.h" 25 #include "poolarch.h" 26 #include "util.h" 27 #include "evr.h" 28 #include "policy.h" 29 30 31 /* 32 * create obsoletesmap from solver decisions 33 * 34 * for solvables in installed repo: 35 * 0 - not obsoleted 36 * p - one of the packages that obsolete us 37 * for all others: 38 * n - number of packages this package obsoletes 39 * 40 */ 41 42 /* OBSOLETE: use transaction code instead! */ 43 44 Id * 45 solver_create_decisions_obsoletesmap(Solver *solv) 46 { 47 Pool *pool = solv->pool; 48 Repo *installed = solv->installed; 49 Id p, *obsoletesmap = NULL; 50 int i; 51 Solvable *s; 52 53 obsoletesmap = (Id *)solv_calloc(pool->nsolvables, sizeof(Id)); 54 if (installed) 55 { 56 for (i = 0; i < solv->decisionq.count; i++) 57 { 58 Id pp, n; 59 int multi; 60 61 n = solv->decisionq.elements[i]; 62 if (n < 0) 63 continue; 64 if (n == SYSTEMSOLVABLE) 65 continue; 66 s = pool->solvables + n; 67 if (s->repo == installed) /* obsoletes don't count for already installed packages */ 68 continue; 69 multi = solv->multiversion.size && MAPTST(&solv->multiversion, n); 70 FOR_PROVIDES(p, pp, s->name) 71 { 72 Solvable *ps = pool->solvables + p; 73 if (multi && (s->name != ps->name || s->evr != ps->evr || s->arch != ps->arch)) 74 continue; 75 if (!pool->implicitobsoleteusesprovides && s->name != ps->name) 76 continue; 77 if (pool->obsoleteusescolors && !pool_colormatch(pool, s, ps)) 78 continue; 79 if (ps->repo == installed && !obsoletesmap[p]) 80 { 81 obsoletesmap[p] = n; 82 obsoletesmap[n]++; 83 } 84 } 85 } 86 for (i = 0; i < solv->decisionq.count; i++) 87 { 88 Id obs, *obsp; 89 Id pp, n; 90 91 n = solv->decisionq.elements[i]; 92 if (n < 0) 93 continue; 94 if (n == SYSTEMSOLVABLE) 95 continue; 96 s = pool->solvables + n; 97 if (s->repo == installed) /* obsoletes don't count for already installed packages */ 98 continue; 99 if (!s->obsoletes) 100 continue; 101 if (solv->multiversion.size && MAPTST(&solv->multiversion, n)) 102 continue; 103 obsp = s->repo->idarraydata + s->obsoletes; 104 while ((obs = *obsp++) != 0) 105 { 106 FOR_PROVIDES(p, pp, obs) 107 { 108 Solvable *ps = pool->solvables + p; 109 if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, ps, obs)) 110 continue; 111 if (pool->obsoleteusescolors && !pool_colormatch(pool, s, ps)) 112 continue; 113 if (pool->solvables[p].repo == installed && !obsoletesmap[p]) 114 { 115 obsoletesmap[p] = n; 116 obsoletesmap[n]++; 117 } 118 } 119 } 120 } 121 } 122 return obsoletesmap; 123 } 124 125 void 126 solver_printruleelement(Solver *solv, int type, Rule *r, Id v) 127 { 128 Pool *pool = solv->pool; 129 Solvable *s; 130 if (v < 0) 131 { 132 s = pool->solvables + -v; 133 POOL_DEBUG(type, " !%s [%d]", pool_solvable2str(pool, s), -v); 134 } 135 else 136 { 137 s = pool->solvables + v; 138 POOL_DEBUG(type, " %s [%d]", pool_solvable2str(pool, s), v); 139 } 140 if (pool->installed && s->repo == pool->installed) 141 POOL_DEBUG(type, "I"); 142 if (r) 143 { 144 if (r->w1 == v) 145 POOL_DEBUG(type, " (w1)"); 146 if (r->w2 == v) 147 POOL_DEBUG(type, " (w2)"); 148 } 149 if (solv->decisionmap[s - pool->solvables] > 0) 150 POOL_DEBUG(type, " Install.level%d", solv->decisionmap[s - pool->solvables]); 151 if (solv->decisionmap[s - pool->solvables] < 0) 152 POOL_DEBUG(type, " Conflict.level%d", -solv->decisionmap[s - pool->solvables]); 153 POOL_DEBUG(type, "\n"); 154 } 155 156 157 /* 158 * print rule 159 */ 160 161 void 162 solver_printrule(Solver *solv, int type, Rule *r) 163 { 164 Pool *pool = solv->pool; 165 int i; 166 Id d, v; 167 168 if (r >= solv->rules && r < solv->rules + solv->nrules) /* r is a solver rule */ 169 POOL_DEBUG(type, "Rule #%d:", (int)(r - solv->rules)); 170 else 171 POOL_DEBUG(type, "Rule:"); /* r is any rule */ 172 if (r && r->d < 0) 173 POOL_DEBUG(type, " (disabled)"); 174 POOL_DEBUG(type, "\n"); 175 d = r->d < 0 ? -r->d - 1 : r->d; 176 for (i = 0; ; i++) 177 { 178 if (i == 0) 179 /* print direct literal */ 180 v = r->p; 181 else if (!d) 182 { 183 if (i == 2) 184 break; 185 /* binary rule --> print w2 as second literal */ 186 v = r->w2; 187 } 188 else 189 /* every other which is in d */ 190 v = solv->pool->whatprovidesdata[d + i - 1]; 191 if (v == ID_NULL) 192 break; 193 solver_printruleelement(solv, type, r, v); 194 } 195 POOL_DEBUG(type, " next rules: %d %d\n", r->n1, r->n2); 196 } 197 198 void 199 solver_printruleclass(Solver *solv, int type, Rule *r) 200 { 201 Pool *pool = solv->pool; 202 Id p = r - solv->rules; 203 assert(p >= 0); 204 if (p < solv->learntrules) 205 if (MAPTST(&solv->weakrulemap, p)) 206 POOL_DEBUG(type, "WEAK "); 207 if (solv->learntrules && p >= solv->learntrules) 208 POOL_DEBUG(type, "LEARNT "); 209 else if (p >= solv->bestrules && p < solv->bestrules_end) 210 POOL_DEBUG(type, "BEST "); 211 else if (p >= solv->choicerules && p < solv->choicerules_end) 212 POOL_DEBUG(type, "CHOICE "); 213 else if (p >= solv->infarchrules && p < solv->infarchrules_end) 214 POOL_DEBUG(type, "INFARCH "); 215 else if (p >= solv->duprules && p < solv->duprules_end) 216 POOL_DEBUG(type, "DUP "); 217 else if (p >= solv->jobrules && p < solv->jobrules_end) 218 POOL_DEBUG(type, "JOB "); 219 else if (p >= solv->updaterules && p < solv->updaterules_end) 220 POOL_DEBUG(type, "UPDATE "); 221 else if (p >= solv->featurerules && p < solv->featurerules_end) 222 POOL_DEBUG(type, "FEATURE "); 223 solver_printrule(solv, type, r); 224 } 225 226 void 227 solver_printproblem(Solver *solv, Id v) 228 { 229 Pool *pool = solv->pool; 230 int i; 231 Rule *r; 232 Id *jp; 233 234 if (v > 0) 235 solver_printruleclass(solv, SOLV_DEBUG_SOLUTIONS, solv->rules + v); 236 else 237 { 238 v = -(v + 1); 239 POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "JOB %d\n", v); 240 jp = solv->ruletojob.elements; 241 for (i = solv->jobrules, r = solv->rules + i; i < solv->jobrules_end; i++, r++, jp++) 242 if (*jp == v) 243 { 244 POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "- "); 245 solver_printrule(solv, SOLV_DEBUG_SOLUTIONS, r); 246 } 247 POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "ENDJOB\n"); 248 } 249 } 250 251 void 252 solver_printwatches(Solver *solv, int type) 253 { 254 Pool *pool = solv->pool; 255 int counter; 256 257 POOL_DEBUG(type, "Watches: \n"); 258 for (counter = -(pool->nsolvables - 1); counter < pool->nsolvables; counter++) 259 POOL_DEBUG(type, " solvable [%d] -- rule [%d]\n", counter, solv->watches[counter + pool->nsolvables]); 260 } 261 262 void 263 solver_printdecisionq(Solver *solv, int type) 264 { 265 Pool *pool = solv->pool; 266 int i; 267 Id p, why; 268 269 POOL_DEBUG(type, "Decisions:\n"); 270 for (i = 0; i < solv->decisionq.count; i++) 271 { 272 p = solv->decisionq.elements[i]; 273 if (p > 0) 274 POOL_DEBUG(type, "%d %d install %s, ", i, solv->decisionmap[p], pool_solvid2str(pool, p)); 275 else 276 POOL_DEBUG(type, "%d %d conflict %s, ", i, -solv->decisionmap[-p], pool_solvid2str(pool, -p)); 277 why = solv->decisionq_why.elements[i]; 278 if (why > 0) 279 { 280 POOL_DEBUG(type, "forced by "); 281 solver_printruleclass(solv, type, solv->rules + why); 282 } 283 else if (why < 0) 284 { 285 POOL_DEBUG(type, "chosen from "); 286 solver_printruleclass(solv, type, solv->rules - why); 287 } 288 else 289 POOL_DEBUG(type, "picked for some unknown reason.\n"); 290 } 291 } 292 293 /* 294 * printdecisions 295 */ 296 297 void 298 solver_printdecisions(Solver *solv) 299 { 300 Pool *pool = solv->pool; 301 Repo *installed = solv->installed; 302 Transaction *trans = solver_create_transaction(solv); 303 Id p, type; 304 int i, j; 305 Solvable *s; 306 Queue iq; 307 Queue recommendations; 308 Queue suggestions; 309 Queue orphaned; 310 311 POOL_DEBUG(SOLV_DEBUG_RESULT, "\n"); 312 POOL_DEBUG(SOLV_DEBUG_RESULT, "transaction:\n"); 313 314 queue_init(&iq); 315 for (i = 0; i < trans->steps.count; i++) 316 { 317 p = trans->steps.elements[i]; 318 s = pool->solvables + p; 319 type = transaction_type(trans, p, SOLVER_TRANSACTION_SHOW_ACTIVE|SOLVER_TRANSACTION_SHOW_ALL|SOLVER_TRANSACTION_SHOW_OBSOLETES|SOLVER_TRANSACTION_SHOW_MULTIINSTALL); 320 switch(type) 321 { 322 case SOLVER_TRANSACTION_MULTIINSTALL: 323 POOL_DEBUG(SOLV_DEBUG_RESULT, " multi install %s", pool_solvable2str(pool, s)); 324 break; 325 case SOLVER_TRANSACTION_MULTIREINSTALL: 326 POOL_DEBUG(SOLV_DEBUG_RESULT, " multi reinstall %s", pool_solvable2str(pool, s)); 327 break; 328 case SOLVER_TRANSACTION_INSTALL: 329 POOL_DEBUG(SOLV_DEBUG_RESULT, " install %s", pool_solvable2str(pool, s)); 330 break; 331 case SOLVER_TRANSACTION_REINSTALL: 332 POOL_DEBUG(SOLV_DEBUG_RESULT, " reinstall %s", pool_solvable2str(pool, s)); 333 break; 334 case SOLVER_TRANSACTION_DOWNGRADE: 335 POOL_DEBUG(SOLV_DEBUG_RESULT, " downgrade %s", pool_solvable2str(pool, s)); 336 break; 337 case SOLVER_TRANSACTION_CHANGE: 338 POOL_DEBUG(SOLV_DEBUG_RESULT, " change %s", pool_solvable2str(pool, s)); 339 break; 340 case SOLVER_TRANSACTION_UPGRADE: 341 case SOLVER_TRANSACTION_OBSOLETES: 342 POOL_DEBUG(SOLV_DEBUG_RESULT, " upgrade %s", pool_solvable2str(pool, s)); 343 break; 344 case SOLVER_TRANSACTION_ERASE: 345 POOL_DEBUG(SOLV_DEBUG_RESULT, " erase %s", pool_solvable2str(pool, s)); 346 break; 347 default: 348 break; 349 } 350 switch(type) 351 { 352 case SOLVER_TRANSACTION_INSTALL: 353 case SOLVER_TRANSACTION_ERASE: 354 case SOLVER_TRANSACTION_MULTIINSTALL: 355 case SOLVER_TRANSACTION_MULTIREINSTALL: 356 POOL_DEBUG(SOLV_DEBUG_RESULT, "\n"); 357 break; 358 case SOLVER_TRANSACTION_REINSTALL: 359 case SOLVER_TRANSACTION_DOWNGRADE: 360 case SOLVER_TRANSACTION_CHANGE: 361 case SOLVER_TRANSACTION_UPGRADE: 362 case SOLVER_TRANSACTION_OBSOLETES: 363 transaction_all_obs_pkgs(trans, p, &iq); 364 if (iq.count) 365 { 366 POOL_DEBUG(SOLV_DEBUG_RESULT, " (obsoletes"); 367 for (j = 0; j < iq.count; j++) 368 POOL_DEBUG(SOLV_DEBUG_RESULT, " %s", pool_solvid2str(pool, iq.elements[j])); 369 POOL_DEBUG(SOLV_DEBUG_RESULT, ")"); 370 } 371 POOL_DEBUG(SOLV_DEBUG_RESULT, "\n"); 372 break; 373 default: 374 break; 375 } 376 } 377 queue_free(&iq); 378 379 POOL_DEBUG(SOLV_DEBUG_RESULT, "\n"); 380 381 queue_init(&recommendations); 382 queue_init(&suggestions); 383 queue_init(&orphaned); 384 solver_get_recommendations(solv, &recommendations, &suggestions, 0); 385 if (recommendations.count) 386 { 387 POOL_DEBUG(SOLV_DEBUG_RESULT, "recommended packages:\n"); 388 for (i = 0; i < recommendations.count; i++) 389 { 390 s = pool->solvables + recommendations.elements[i]; 391 if (solv->decisionmap[recommendations.elements[i]] > 0) 392 { 393 if (installed && s->repo == installed) 394 POOL_DEBUG(SOLV_DEBUG_RESULT, " %s (installed)\n", pool_solvable2str(pool, s)); 395 else 396 POOL_DEBUG(SOLV_DEBUG_RESULT, " %s (selected)\n", pool_solvable2str(pool, s)); 397 } 398 else 399 POOL_DEBUG(SOLV_DEBUG_RESULT, " %s\n", pool_solvable2str(pool, s)); 400 } 401 POOL_DEBUG(SOLV_DEBUG_RESULT, "\n"); 402 } 403 404 if (suggestions.count) 405 { 406 POOL_DEBUG(SOLV_DEBUG_RESULT, "suggested packages:\n"); 407 for (i = 0; i < suggestions.count; i++) 408 { 409 s = pool->solvables + suggestions.elements[i]; 410 if (solv->decisionmap[suggestions.elements[i]] > 0) 411 { 412 if (installed && s->repo == installed) 413 POOL_DEBUG(SOLV_DEBUG_RESULT, " %s (installed)\n", pool_solvable2str(pool, s)); 414 else 415 POOL_DEBUG(SOLV_DEBUG_RESULT, " %s (selected)\n", pool_solvable2str(pool, s)); 416 } 417 else 418 POOL_DEBUG(SOLV_DEBUG_RESULT, " %s\n", pool_solvable2str(pool, s)); 419 } 420 POOL_DEBUG(SOLV_DEBUG_RESULT, "\n"); 421 } 422 if (orphaned.count) 423 { 424 POOL_DEBUG(SOLV_DEBUG_RESULT, "orphaned packages:\n"); 425 for (i = 0; i < orphaned.count; i++) 426 { 427 s = pool->solvables + orphaned.elements[i]; 428 if (solv->decisionmap[solv->orphaned.elements[i]] > 0) 429 POOL_DEBUG(SOLV_DEBUG_RESULT, " %s (kept)\n", pool_solvable2str(pool, s)); 430 else 431 POOL_DEBUG(SOLV_DEBUG_RESULT, " %s (erased)\n", pool_solvable2str(pool, s)); 432 } 433 POOL_DEBUG(SOLV_DEBUG_RESULT, "\n"); 434 } 435 queue_free(&recommendations); 436 queue_free(&suggestions); 437 queue_free(&orphaned); 438 transaction_free(trans); 439 } 440 441 static inline 442 const char *id2strnone(Pool *pool, Id id) 443 { 444 return !id || id == 1 ? "(none)" : pool_id2str(pool, id); 445 } 446 447 void 448 transaction_print(Transaction *trans) 449 { 450 Pool *pool = trans->pool; 451 Queue classes, pkgs; 452 int i, j, mode, l, linel; 453 char line[76]; 454 const char *n; 455 456 queue_init(&classes); 457 queue_init(&pkgs); 458 mode = 0; 459 transaction_classify(trans, mode, &classes); 460 for (i = 0; i < classes.count; i += 4) 461 { 462 Id class = classes.elements[i]; 463 Id cnt = classes.elements[i + 1]; 464 switch(class) 465 { 466 case SOLVER_TRANSACTION_ERASE: 467 POOL_DEBUG(SOLV_DEBUG_RESULT, "%d erased packages:\n", cnt); 468 break; 469 case SOLVER_TRANSACTION_INSTALL: 470 POOL_DEBUG(SOLV_DEBUG_RESULT, "%d installed packages:\n", cnt); 471 break; 472 case SOLVER_TRANSACTION_REINSTALLED: 473 POOL_DEBUG(SOLV_DEBUG_RESULT, "%d reinstalled packages:\n", cnt); 474 break; 475 case SOLVER_TRANSACTION_DOWNGRADED: 476 POOL_DEBUG(SOLV_DEBUG_RESULT, "%d downgraded packages:\n", cnt); 477 break; 478 case SOLVER_TRANSACTION_CHANGED: 479 POOL_DEBUG(SOLV_DEBUG_RESULT, "%d changed packages:\n", cnt); 480 break; 481 case SOLVER_TRANSACTION_UPGRADED: 482 POOL_DEBUG(SOLV_DEBUG_RESULT, "%d upgraded packages:\n", cnt); 483 break; 484 case SOLVER_TRANSACTION_VENDORCHANGE: 485 POOL_DEBUG(SOLV_DEBUG_RESULT, "%d vendor changes from '%s' to '%s':\n", cnt, id2strnone(pool, classes.elements[i + 2]), id2strnone(pool, classes.elements[i + 3])); 486 break; 487 case SOLVER_TRANSACTION_ARCHCHANGE: 488 POOL_DEBUG(SOLV_DEBUG_RESULT, "%d arch changes from %s to %s:\n", cnt, pool_id2str(pool, classes.elements[i + 2]), pool_id2str(pool, classes.elements[i + 3])); 489 break; 490 default: 491 class = SOLVER_TRANSACTION_IGNORE; 492 break; 493 } 494 if (class == SOLVER_TRANSACTION_IGNORE) 495 continue; 496 transaction_classify_pkgs(trans, mode, class, classes.elements[i + 2], classes.elements[i + 3], &pkgs); 497 *line = 0; 498 linel = 0; 499 for (j = 0; j < pkgs.count; j++) 500 { 501 Id p = pkgs.elements[j]; 502 Solvable *s = pool->solvables + p; 503 Solvable *s2; 504 505 switch(class) 506 { 507 case SOLVER_TRANSACTION_DOWNGRADED: 508 case SOLVER_TRANSACTION_UPGRADED: 509 s2 = pool->solvables + transaction_obs_pkg(trans, p); 510 POOL_DEBUG(SOLV_DEBUG_RESULT, " - %s -> %s\n", pool_solvable2str(pool, s), pool_solvable2str(pool, s2)); 511 break; 512 case SOLVER_TRANSACTION_VENDORCHANGE: 513 case SOLVER_TRANSACTION_ARCHCHANGE: 514 n = pool_id2str(pool, s->name); 515 l = strlen(n); 516 if (l + linel > sizeof(line) - 3) 517 { 518 if (*line) 519 POOL_DEBUG(SOLV_DEBUG_RESULT, " %s\n", line); 520 *line = 0; 521 linel = 0; 522 } 523 if (l + linel > sizeof(line) - 3) 524 POOL_DEBUG(SOLV_DEBUG_RESULT, " %s\n", n); 525 else 526 { 527 if (*line) 528 { 529 strcpy(line + linel, ", "); 530 linel += 2; 531 } 532 strcpy(line + linel, n); 533 linel += l; 534 } 535 break; 536 default: 537 POOL_DEBUG(SOLV_DEBUG_RESULT, " - %s\n", pool_solvable2str(pool, s)); 538 break; 539 } 540 } 541 if (*line) 542 POOL_DEBUG(SOLV_DEBUG_RESULT, " %s\n", line); 543 POOL_DEBUG(SOLV_DEBUG_RESULT, "\n"); 544 } 545 queue_free(&classes); 546 queue_free(&pkgs); 547 } 548 549 void 550 solver_printproblemruleinfo(Solver *solv, Id probr) 551 { 552 Pool *pool = solv->pool; 553 Id dep, source, target; 554 555 switch (solver_ruleinfo(solv, probr, &source, &target, &dep)) 556 { 557 case SOLVER_RULE_DISTUPGRADE: 558 POOL_DEBUG(SOLV_DEBUG_RESULT, "%s does not belong to a distupgrade repository\n", pool_solvid2str(pool, source)); 559 return; 560 case SOLVER_RULE_INFARCH: 561 POOL_DEBUG(SOLV_DEBUG_RESULT, "%s has inferior architecture\n", pool_solvid2str(pool, source)); 562 return; 563 case SOLVER_RULE_UPDATE: 564 POOL_DEBUG(SOLV_DEBUG_RESULT, "problem with installed package %s\n", pool_solvid2str(pool, source)); 565 return; 566 case SOLVER_RULE_JOB: 567 POOL_DEBUG(SOLV_DEBUG_RESULT, "conflicting requests\n"); 568 return; 569 case SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP: 570 POOL_DEBUG(SOLV_DEBUG_RESULT, "nothing provides requested %s\n", pool_dep2str(pool, dep)); 571 return; 572 case SOLVER_RULE_JOB_PROVIDED_BY_SYSTEM: 573 POOL_DEBUG(SOLV_DEBUG_RESULT, "%s is provided by the system\n", pool_dep2str(pool, dep)); 574 return; 575 case SOLVER_RULE_RPM: 576 POOL_DEBUG(SOLV_DEBUG_RESULT, "some dependency problem\n"); 577 return; 578 case SOLVER_RULE_RPM_NOT_INSTALLABLE: 579 POOL_DEBUG(SOLV_DEBUG_RESULT, "package %s is not installable\n", pool_solvid2str(pool, source)); 580 return; 581 case SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP: 582 POOL_DEBUG(SOLV_DEBUG_RESULT, "nothing provides %s needed by %s\n", pool_dep2str(pool, dep), pool_solvid2str(pool, source)); 583 return; 584 case SOLVER_RULE_RPM_SAME_NAME: 585 POOL_DEBUG(SOLV_DEBUG_RESULT, "cannot install both %s and %s\n", pool_solvid2str(pool, source), pool_solvid2str(pool, target)); 586 return; 587 case SOLVER_RULE_RPM_PACKAGE_CONFLICT: 588 POOL_DEBUG(SOLV_DEBUG_RESULT, "package %s conflicts with %s provided by %s\n", pool_solvid2str(pool, source), pool_dep2str(pool, dep), pool_solvid2str(pool, target)); 589 return; 590 case SOLVER_RULE_RPM_PACKAGE_OBSOLETES: 591 POOL_DEBUG(SOLV_DEBUG_RESULT, "package %s obsoletes %s provided by %s\n", pool_solvid2str(pool, source), pool_dep2str(pool, dep), pool_solvid2str(pool, target)); 592 return; 593 case SOLVER_RULE_RPM_INSTALLEDPKG_OBSOLETES: 594 POOL_DEBUG(SOLV_DEBUG_RESULT, "installed package %s obsoletes %s provided by %s\n", pool_solvid2str(pool, source), pool_dep2str(pool, dep), pool_solvid2str(pool, target)); 595 return; 596 case SOLVER_RULE_RPM_IMPLICIT_OBSOLETES: 597 POOL_DEBUG(SOLV_DEBUG_RESULT, "package %s implicitly obsoletes %s provided by %s\n", pool_solvid2str(pool, source), pool_dep2str(pool, dep), pool_solvid2str(pool, target)); 598 return; 599 case SOLVER_RULE_RPM_PACKAGE_REQUIRES: 600 POOL_DEBUG(SOLV_DEBUG_RESULT, "package %s requires %s, but none of the providers can be installed\n", pool_solvid2str(pool, source), pool_dep2str(pool, dep)); 601 return; 602 case SOLVER_RULE_RPM_SELF_CONFLICT: 603 POOL_DEBUG(SOLV_DEBUG_RESULT, "package %s conflicts with %s provided by itself\n", pool_solvid2str(pool, source), pool_dep2str(pool, dep)); 604 return; 605 case SOLVER_RULE_UNKNOWN: 606 case SOLVER_RULE_FEATURE: 607 case SOLVER_RULE_LEARNT: 608 case SOLVER_RULE_CHOICE: 609 case SOLVER_RULE_BEST: 610 POOL_DEBUG(SOLV_DEBUG_RESULT, "bad rule type\n"); 611 return; 612 } 613 } 614 615 void 616 solver_printprobleminfo(Solver *solv, Id problem) 617 { 618 solver_printproblemruleinfo(solv, solver_findproblemrule(solv, problem)); 619 } 620 621 void 622 solver_printcompleteprobleminfo(Solver *solv, Id problem) 623 { 624 Queue q; 625 Id probr; 626 int i, nobad = 0; 627 628 queue_init(&q); 629 solver_findallproblemrules(solv, problem, &q); 630 for (i = 0; i < q.count; i++) 631 { 632 probr = q.elements[i]; 633 if (!(probr >= solv->updaterules && probr < solv->updaterules_end) && !(probr >= solv->jobrules && probr < solv->jobrules_end)) 634 { 635 nobad = 1; 636 break; 637 } 638 } 639 for (i = 0; i < q.count; i++) 640 { 641 probr = q.elements[i]; 642 if (nobad && ((probr >= solv->updaterules && probr < solv->updaterules_end) || (probr >= solv->jobrules && probr < solv->jobrules_end))) 643 continue; 644 solver_printproblemruleinfo(solv, probr); 645 } 646 queue_free(&q); 647 } 648 649 void 650 solver_printsolution(Solver *solv, Id problem, Id solution) 651 { 652 Pool *pool = solv->pool; 653 Id p, rp, element, how, what, select; 654 Solvable *s, *sd; 655 656 element = 0; 657 while ((element = solver_next_solutionelement(solv, problem, solution, element, &p, &rp)) != 0) 658 { 659 if (p == SOLVER_SOLUTION_JOB || p == SOLVER_SOLUTION_POOLJOB) 660 { 661 /* job, rp is index into job queue */ 662 if (p == SOLVER_SOLUTION_JOB) 663 rp += solv->pooljobcnt; 664 how = solv->job.elements[rp - 1]; 665 what = solv->job.elements[rp]; 666 select = how & SOLVER_SELECTMASK; 667 switch (how & SOLVER_JOBMASK) 668 { 669 case SOLVER_INSTALL: 670 if (select == SOLVER_SOLVABLE && solv->installed && pool->solvables[what].repo == solv->installed) 671 POOL_DEBUG(SOLV_DEBUG_RESULT, " - do not keep %s installed\n", pool_solvid2str(pool, what)); 672 else if (select == SOLVER_SOLVABLE_PROVIDES) 673 POOL_DEBUG(SOLV_DEBUG_RESULT, " - do not install a solvable %s\n", solver_select2str(pool, select, what)); 674 else 675 POOL_DEBUG(SOLV_DEBUG_RESULT, " - do not install %s\n", solver_select2str(pool, select, what)); 676 break; 677 case SOLVER_ERASE: 678 if (select == SOLVER_SOLVABLE && !(solv->installed && pool->solvables[what].repo == solv->installed)) 679 POOL_DEBUG(SOLV_DEBUG_RESULT, " - do not forbid installation of %s\n", pool_solvid2str(pool, what)); 680 else if (select == SOLVER_SOLVABLE_PROVIDES) 681 POOL_DEBUG(SOLV_DEBUG_RESULT, " - do not deinstall all solvables %s\n", solver_select2str(pool, select, what)); 682 else 683 POOL_DEBUG(SOLV_DEBUG_RESULT, " - do not deinstall %s\n", solver_select2str(pool, select, what)); 684 break; 685 case SOLVER_UPDATE: 686 POOL_DEBUG(SOLV_DEBUG_RESULT, " - do not install most recent version of %s\n", solver_select2str(pool, select, what)); 687 break; 688 case SOLVER_LOCK: 689 POOL_DEBUG(SOLV_DEBUG_RESULT, " - do not lock %s\n", solver_select2str(pool, select, what)); 690 break; 691 default: 692 POOL_DEBUG(SOLV_DEBUG_RESULT, " - do something different\n"); 693 break; 694 } 695 } 696 else if (p == SOLVER_SOLUTION_INFARCH) 697 { 698 s = pool->solvables + rp; 699 if (solv->installed && s->repo == solv->installed) 700 POOL_DEBUG(SOLV_DEBUG_RESULT, " - keep %s despite the inferior architecture\n", pool_solvable2str(pool, s)); 701 else 702 POOL_DEBUG(SOLV_DEBUG_RESULT, " - install %s despite the inferior architecture\n", pool_solvable2str(pool, s)); 703 } 704 else if (p == SOLVER_SOLUTION_DISTUPGRADE) 705 { 706 s = pool->solvables + rp; 707 if (solv->installed && s->repo == solv->installed) 708 POOL_DEBUG(SOLV_DEBUG_RESULT, " - keep obsolete %s\n", pool_solvable2str(pool, s)); 709 else 710 POOL_DEBUG(SOLV_DEBUG_RESULT, " - install %s from excluded repository\n", pool_solvable2str(pool, s)); 711 } 712 else if (p == SOLVER_SOLUTION_BEST) 713 { 714 s = pool->solvables + rp; 715 if (solv->installed && s->repo == solv->installed) 716 POOL_DEBUG(SOLV_DEBUG_RESULT, " - keep old %s\n", pool_solvable2str(pool, s)); 717 else 718 POOL_DEBUG(SOLV_DEBUG_RESULT, " - install %s despite the old version\n", pool_solvable2str(pool, s)); 719 } 720 else 721 { 722 /* policy, replace p with rp */ 723 s = pool->solvables + p; 724 sd = rp ? pool->solvables + rp : 0; 725 if (sd) 726 { 727 int illegal = policy_is_illegal(solv, s, sd, 0); 728 if ((illegal & POLICY_ILLEGAL_DOWNGRADE) != 0) 729 POOL_DEBUG(SOLV_DEBUG_RESULT, " - allow downgrade of %s to %s\n", pool_solvable2str(pool, s), pool_solvable2str(pool, sd)); 730 if ((illegal & POLICY_ILLEGAL_NAMECHANGE) != 0) 731 POOL_DEBUG(SOLV_DEBUG_RESULT, " - allow name change of %s to %s\n", pool_solvable2str(pool, s), pool_solvable2str(pool, sd)); 732 if ((illegal & POLICY_ILLEGAL_ARCHCHANGE) != 0) 733 POOL_DEBUG(SOLV_DEBUG_RESULT, " - allow architecture change of %s to %s\n", pool_solvable2str(pool, s), pool_solvable2str(pool, sd)); 734 if ((illegal & POLICY_ILLEGAL_VENDORCHANGE) != 0) 735 { 736 if (sd->vendor) 737 POOL_DEBUG(SOLV_DEBUG_RESULT, " - allow vendor change from '%s' (%s) to '%s' (%s)\n", pool_id2str(pool, s->vendor), pool_solvable2str(pool, s), pool_id2str(pool, sd->vendor), pool_solvable2str(pool, sd)); 738 else 739 POOL_DEBUG(SOLV_DEBUG_RESULT, " - allow vendor change from '%s' (%s) to no vendor (%s)\n", pool_id2str(pool, s->vendor), pool_solvable2str(pool, s), pool_solvable2str(pool, sd)); 740 } 741 if (!illegal) 742 POOL_DEBUG(SOLV_DEBUG_RESULT, " - allow replacement of %s with %s\n", pool_solvable2str(pool, s), pool_solvable2str(pool, sd)); 743 } 744 else 745 { 746 POOL_DEBUG(SOLV_DEBUG_RESULT, " - allow deinstallation of %s\n", pool_solvable2str(pool, s)); 747 } 748 } 749 } 750 } 751 752 void 753 solver_printallsolutions(Solver *solv) 754 { 755 Pool *pool = solv->pool; 756 int pcnt; 757 Id problem, solution; 758 759 POOL_DEBUG(SOLV_DEBUG_RESULT, "Encountered problems! Here are the solutions:\n\n"); 760 pcnt = 0; 761 problem = 0; 762 while ((problem = solver_next_problem(solv, problem)) != 0) 763 { 764 pcnt++; 765 POOL_DEBUG(SOLV_DEBUG_RESULT, "Problem %d:\n", pcnt); 766 POOL_DEBUG(SOLV_DEBUG_RESULT, "====================================\n"); 767 #if 1 768 solver_printprobleminfo(solv, problem); 769 #else 770 solver_printcompleteprobleminfo(solv, problem); 771 #endif 772 POOL_DEBUG(SOLV_DEBUG_RESULT, "\n"); 773 solution = 0; 774 while ((solution = solver_next_solution(solv, problem, solution)) != 0) 775 { 776 solver_printsolution(solv, problem, solution); 777 POOL_DEBUG(SOLV_DEBUG_RESULT, "\n"); 778 } 779 } 780 } 781 782 void 783 solver_printtrivial(Solver *solv) 784 { 785 Pool *pool = solv->pool; 786 Queue in, out; 787 Id p; 788 const char *n; 789 Solvable *s; 790 int i; 791 792 queue_init(&in); 793 for (p = 1, s = pool->solvables + p; p < solv->pool->nsolvables; p++, s++) 794 { 795 n = pool_id2str(pool, s->name); 796 if (strncmp(n, "patch:", 6) != 0 && strncmp(n, "pattern:", 8) != 0) 797 continue; 798 queue_push(&in, p); 799 } 800 if (!in.count) 801 { 802 queue_free(&in); 803 return; 804 } 805 queue_init(&out); 806 solver_trivial_installable(solv, &in, &out); 807 POOL_DEBUG(SOLV_DEBUG_RESULT, "trivial installable status:\n"); 808 for (i = 0; i < in.count; i++) 809 POOL_DEBUG(SOLV_DEBUG_RESULT, " %s: %d\n", pool_solvid2str(pool, in.elements[i]), out.elements[i]); 810 POOL_DEBUG(SOLV_DEBUG_RESULT, "\n"); 811 queue_free(&in); 812 queue_free(&out); 813 } 814 815 const char * 816 solver_select2str(Pool *pool, Id select, Id what) 817 { 818 const char *s; 819 char *b; 820 select &= SOLVER_SELECTMASK; 821 if (select == SOLVER_SOLVABLE) 822 return pool_solvid2str(pool, what); 823 if (select == SOLVER_SOLVABLE_NAME) 824 return pool_dep2str(pool, what); 825 if (select == SOLVER_SOLVABLE_PROVIDES) 826 { 827 s = pool_dep2str(pool, what); 828 b = pool_alloctmpspace(pool, 11 + strlen(s)); 829 sprintf(b, "providing %s", s); 830 return b; 831 } 832 if (select == SOLVER_SOLVABLE_ONE_OF) 833 { 834 Id p; 835 b = 0; 836 while ((p = pool->whatprovidesdata[what++]) != 0) 837 { 838 s = pool_solvid2str(pool, p); 839 if (b) 840 b = pool_tmpappend(pool, b, ", ", s); 841 else 842 b = pool_tmpjoin(pool, s, 0, 0); 843 pool_freetmpspace(pool, s); 844 } 845 return b ? b : "nothing"; 846 } 847 if (select == SOLVER_SOLVABLE_REPO) 848 { 849 b = pool_alloctmpspace(pool, 20); 850 sprintf(b, "repo #%d", what); 851 return b; 852 } 853 if (select == SOLVER_SOLVABLE_ALL) 854 return "all packages"; 855 return "unknown job select"; 856 } 857 858 const char * 859 pool_job2str(Pool *pool, Id how, Id what, Id flagmask) 860 { 861 Id select = how & SOLVER_SELECTMASK; 862 const char *strstart = 0, *strend = 0; 863 char *s; 864 int o; 865 866 switch (how & SOLVER_JOBMASK) 867 { 868 case SOLVER_NOOP: 869 return "do nothing"; 870 case SOLVER_INSTALL: 871 if (select == SOLVER_SOLVABLE && pool->installed && pool->solvables[what].repo == pool->installed) 872 strstart = "keep ", strend = "installed"; 873 else if (select == SOLVER_SOLVABLE || select == SOLVER_SOLVABLE_NAME) 874 strstart = "install "; 875 else if (select == SOLVER_SOLVABLE_PROVIDES) 876 strstart = "install a package "; 877 else 878 strstart = "install one of "; 879 break; 880 case SOLVER_ERASE: 881 if (select == SOLVER_SOLVABLE && !(pool->installed && pool->solvables[what].repo == pool->installed)) 882 strstart = "keep ", strend = "unstalled"; 883 else if (select == SOLVER_SOLVABLE_PROVIDES) 884 strstart = "deinstall all packages "; 885 else 886 strstart = "deinstall "; 887 break; 888 case SOLVER_UPDATE: 889 strstart = "update "; 890 break; 891 case SOLVER_WEAKENDEPS: 892 strstart = "weaken deps of "; 893 break; 894 case SOLVER_MULTIVERSION: 895 strstart = "multi version "; 896 break; 897 case SOLVER_LOCK: 898 strstart = "update "; 899 break; 900 case SOLVER_DISTUPGRADE: 901 strstart = "dist upgrade "; 902 break; 903 case SOLVER_VERIFY: 904 strstart = "verify "; 905 break; 906 case SOLVER_DROP_ORPHANED: 907 strstart = "deinstall ", strend = "if orphaned"; 908 break; 909 case SOLVER_USERINSTALLED: 910 strstart = "regard ", strend = "as userinstalled"; 911 break; 912 default: 913 strstart = "unknown job "; 914 break; 915 } 916 s = pool_tmpjoin(pool, strstart, solver_select2str(pool, select, what), strend); 917 how &= flagmask; 918 if ((how & ~(SOLVER_SELECTMASK|SOLVER_JOBMASK)) == 0) 919 return s; 920 o = strlen(s); 921 s = pool_tmpappend(pool, s, " ", 0); 922 if (how & SOLVER_WEAK) 923 s = pool_tmpappend(pool, s, ",weak", 0); 924 if (how & SOLVER_ESSENTIAL) 925 s = pool_tmpappend(pool, s, ",essential", 0); 926 if (how & SOLVER_CLEANDEPS) 927 s = pool_tmpappend(pool, s, ",cleandeps", 0); 928 if (how & SOLVER_SETEV) 929 s = pool_tmpappend(pool, s, ",setev", 0); 930 if (how & SOLVER_SETEVR) 931 s = pool_tmpappend(pool, s, ",setevr", 0); 932 if (how & SOLVER_SETARCH) 933 s = pool_tmpappend(pool, s, ",setarch", 0); 934 if (how & SOLVER_SETVENDOR) 935 s = pool_tmpappend(pool, s, ",setvendor", 0); 936 if (how & SOLVER_SETREPO) 937 s = pool_tmpappend(pool, s, ",setrepo", 0); 938 if (how & SOLVER_NOAUTOSET) 939 s = pool_tmpappend(pool, s, ",noautoset", 0); 940 if (s[o + 1] != ',') 941 s = pool_tmpappend(pool, s, ",?", 0); 942 s[o + 1] = '['; 943 return pool_tmpappend(pool, s, "]", 0); 944 } 945 946 const char * 947 pool_selection2str(Pool *pool, Queue *selection, Id flagmask) 948 { 949 char *s; 950 const char *s2; 951 int i; 952 s = pool_tmpjoin(pool, 0, 0, 0); 953 for (i = 0; i < selection->count; i += 2) 954 { 955 Id how = selection->elements[i]; 956 if (*s) 957 s = pool_tmpappend(pool, s, " + ", 0); 958 s2 = solver_select2str(pool, how & SOLVER_SELECTMASK, selection->elements[i + 1]); 959 s = pool_tmpappend(pool, s, s2, 0); 960 pool_freetmpspace(pool, s2); 961 how &= flagmask & SOLVER_SETMASK; 962 if (how) 963 { 964 int o = strlen(s); 965 s = pool_tmpappend(pool, s, " ", 0); 966 if (how & SOLVER_SETEV) 967 s = pool_tmpappend(pool, s, ",setev", 0); 968 if (how & SOLVER_SETEVR) 969 s = pool_tmpappend(pool, s, ",setevr", 0); 970 if (how & SOLVER_SETARCH) 971 s = pool_tmpappend(pool, s, ",setarch", 0); 972 if (how & SOLVER_SETVENDOR) 973 s = pool_tmpappend(pool, s, ",setvendor", 0); 974 if (how & SOLVER_SETREPO) 975 s = pool_tmpappend(pool, s, ",setrepo", 0); 976 if (how & SOLVER_NOAUTOSET) 977 s = pool_tmpappend(pool, s, ",noautoset", 0); 978 if (s[o + 1] != ',') 979 s = pool_tmpappend(pool, s, ",?", 0); 980 s[o + 1] = '['; 981 s = pool_tmpappend(pool, s, "]", 0); 982 } 983 } 984 return s; 985 } 986 987 const char * 988 solver_problemruleinfo2str(Solver *solv, SolverRuleinfo type, Id source, Id target, Id dep) 989 { 990 Pool *pool = solv->pool; 991 char *s; 992 switch (type) 993 { 994 case SOLVER_RULE_DISTUPGRADE: 995 return pool_tmpjoin(pool, pool_solvid2str(pool, source), " does not belong to a distupgrade repository", 0); 996 case SOLVER_RULE_INFARCH: 997 return pool_tmpjoin(pool, pool_solvid2str(pool, source), " has inferior architecture", 0); 998 case SOLVER_RULE_UPDATE: 999 return pool_tmpjoin(pool, "problem with installed package ", pool_solvid2str(pool, source), 0); 1000 case SOLVER_RULE_JOB: 1001 return "conflicting requests"; 1002 case SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP: 1003 return pool_tmpjoin(pool, "nothing provides requested ", pool_dep2str(pool, dep), 0); 1004 case SOLVER_RULE_JOB_PROVIDED_BY_SYSTEM: 1005 return pool_tmpjoin(pool, pool_dep2str(pool, dep), " is provided by the system", 0); 1006 case SOLVER_RULE_RPM: 1007 return "some dependency problem"; 1008 case SOLVER_RULE_RPM_NOT_INSTALLABLE: 1009 return pool_tmpjoin(pool, "package ", pool_solvid2str(pool, source), " is not installable"); 1010 case SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP: 1011 s = pool_tmpjoin(pool, "nothing provides ", pool_dep2str(pool, dep), 0); 1012 return pool_tmpappend(pool, s, " needed by ", pool_solvid2str(pool, source)); 1013 case SOLVER_RULE_RPM_SAME_NAME: 1014 s = pool_tmpjoin(pool, "cannot install both ", pool_solvid2str(pool, source), 0); 1015 return pool_tmpappend(pool, s, " and ", pool_solvid2str(pool, target)); 1016 case SOLVER_RULE_RPM_PACKAGE_CONFLICT: 1017 s = pool_tmpjoin(pool, "package ", pool_solvid2str(pool, source), 0); 1018 s = pool_tmpappend(pool, s, " conflicts with ", pool_dep2str(pool, dep)); 1019 return pool_tmpappend(pool, s, " provided by ", pool_solvid2str(pool, target)); 1020 case SOLVER_RULE_RPM_PACKAGE_OBSOLETES: 1021 s = pool_tmpjoin(pool, "package ", pool_solvid2str(pool, source), 0); 1022 s = pool_tmpappend(pool, s, " obsoletes ", pool_dep2str(pool, dep)); 1023 return pool_tmpappend(pool, s, " provided by ", pool_solvid2str(pool, target)); 1024 case SOLVER_RULE_RPM_INSTALLEDPKG_OBSOLETES: 1025 s = pool_tmpjoin(pool, "installed package ", pool_solvid2str(pool, source), 0); 1026 s = pool_tmpappend(pool, s, " obsoletes ", pool_dep2str(pool, dep)); 1027 return pool_tmpappend(pool, s, " provided by ", pool_solvid2str(pool, target)); 1028 case SOLVER_RULE_RPM_IMPLICIT_OBSOLETES: 1029 s = pool_tmpjoin(pool, "package ", pool_solvid2str(pool, source), 0); 1030 s = pool_tmpappend(pool, s, " implicitly obsoletes ", pool_dep2str(pool, dep)); 1031 return pool_tmpappend(pool, s, " provided by ", pool_solvid2str(pool, target)); 1032 case SOLVER_RULE_RPM_PACKAGE_REQUIRES: 1033 s = pool_tmpjoin(pool, "package ", pool_solvid2str(pool, source), " requires "); 1034 return pool_tmpappend(pool, s, pool_dep2str(pool, dep), ", but none of the providers can be installed"); 1035 case SOLVER_RULE_RPM_SELF_CONFLICT: 1036 s = pool_tmpjoin(pool, "package ", pool_solvid2str(pool, source), " conflicts with "); 1037 return pool_tmpappend(pool, s, pool_dep2str(pool, dep), " provided by itself"); 1038 default: 1039 return "bad problem rule type"; 1040 } 1041 } 1042 1043 const char * 1044 solver_solutionelement2str(Solver *solv, Id p, Id rp) 1045 { 1046 Pool *pool = solv->pool; 1047 if (p == SOLVER_SOLUTION_JOB || p == SOLVER_SOLUTION_POOLJOB) 1048 { 1049 Id how, what; 1050 if (p == SOLVER_SOLUTION_JOB) 1051 rp += solv->pooljobcnt; 1052 how = solv->job.elements[rp - 1]; 1053 what = solv->job.elements[rp]; 1054 return pool_tmpjoin(pool, "do not ask to ", pool_job2str(pool, how, what, 0), 0); 1055 } 1056 else if (p == SOLVER_SOLUTION_INFARCH) 1057 { 1058 Solvable *s = pool->solvables + rp; 1059 if (solv->installed && s->repo == solv->installed) 1060 return pool_tmpjoin(pool, "keep ", pool_solvable2str(pool, s), " despite the inferior architecture"); 1061 else 1062 return pool_tmpjoin(pool, "install ", pool_solvable2str(pool, s), " despite the inferior architecture"); 1063 } 1064 else if (p == SOLVER_SOLUTION_DISTUPGRADE) 1065 { 1066 Solvable *s = pool->solvables + rp; 1067 if (solv->installed && s->repo == solv->installed) 1068 return pool_tmpjoin(pool, "keep obsolete ", pool_solvable2str(pool, s), 0); 1069 else 1070 return pool_tmpjoin(pool, "install ", pool_solvable2str(pool, s), " from excluded repository"); 1071 } 1072 else if (p == SOLVER_SOLUTION_BEST) 1073 { 1074 Solvable *s = pool->solvables + rp; 1075 if (solv->installed && s->repo == solv->installed) 1076 return pool_tmpjoin(pool, "keep old ", pool_solvable2str(pool, s), 0); 1077 else 1078 return pool_tmpjoin(pool, "install ", pool_solvable2str(pool, s), " despite the old version"); 1079 } 1080 else if (p > 0 && rp == 0) 1081 return pool_tmpjoin(pool, "allow deinstallation of ", pool_solvid2str(pool, p), 0); 1082 else if (p > 0 && rp > 0) 1083 { 1084 const char *sp = pool_solvid2str(pool, p); 1085 const char *srp = pool_solvid2str(pool, rp); 1086 const char *str = pool_tmpjoin(pool, "allow replacement of ", sp, 0); 1087 return pool_tmpappend(pool, str, " with ", srp); 1088 } 1089 else 1090 return "bad solution element"; 1091 } 1092 1093 const char * 1094 policy_illegal2str(Solver *solv, int illegal, Solvable *s, Solvable *rs) 1095 { 1096 Pool *pool = solv->pool; 1097 const char *str; 1098 if (illegal == POLICY_ILLEGAL_DOWNGRADE) 1099 { 1100 str = pool_tmpjoin(pool, "downgrade of ", pool_solvable2str(pool, s), 0); 1101 return pool_tmpappend(pool, str, " to ", pool_solvable2str(pool, rs)); 1102 } 1103 if (illegal == POLICY_ILLEGAL_NAMECHANGE) 1104 { 1105 str = pool_tmpjoin(pool, "name change of ", pool_solvable2str(pool, s), 0); 1106 return pool_tmpappend(pool, str, " to ", pool_solvable2str(pool, rs)); 1107 } 1108 if (illegal == POLICY_ILLEGAL_ARCHCHANGE) 1109 { 1110 str = pool_tmpjoin(pool, "architecture change of ", pool_solvable2str(pool, s), 0); 1111 return pool_tmpappend(pool, str, " to ", pool_solvable2str(pool, rs)); 1112 } 1113 if (illegal == POLICY_ILLEGAL_VENDORCHANGE) 1114 { 1115 str = pool_tmpjoin(pool, "vendor change from '", pool_id2str(pool, s->vendor), "' ("); 1116 if (rs->vendor) 1117 { 1118 str = pool_tmpappend(pool, str, pool_solvable2str(pool, s), ") to '"); 1119 str = pool_tmpappend(pool, str, pool_id2str(pool, rs->vendor), "' ("); 1120 } 1121 else 1122 str = pool_tmpappend(pool, str, pool_solvable2str(pool, s), ") to no vendor ("); 1123 return pool_tmpappend(pool, str, pool_solvable2str(pool, rs), ")"); 1124 } 1125 return "unknown illegal change"; 1126 } 1127