31
31
#include "dselect.h"
32
32
#include "pkglist.h"
34
static const int depdebug= 1;
37
35
packagelist::useavailable(pkginfo *pkg)
39
37
if (pkg->clientdata &&
40
38
pkg->clientdata->selected == pkginfo::want_install &&
41
informative(pkg,&pkg->available) &&
39
pkg_is_informative(pkg, &pkg->available) &&
42
40
(!(pkg->status == pkginfo::stat_installed ||
43
41
pkg->status == pkginfo::stat_triggersawaited ||
44
42
pkg->status == pkginfo::stat_triggerspending) ||
51
pkginfoperfile *packagelist::findinfo(pkginfo *pkg) {
50
packagelist::find_pkgbin(pkginfo *pkg)
53
53
r= useavailable(pkg) ? &pkg->available : &pkg->installed;
55
fprintf(debug,"packagelist[%p]::findinfo(%s) useavailable=%d\n",this,pkg->name,useavailable(pkg));
54
debug(dbg_general, "packagelist[%p]::find_pkgbin(%s) useavailable=%d",
55
this, pkg->name, useavailable(pkg));
60
60
int packagelist::checkdependers(pkginfo *pkg, int changemade) {
61
61
struct deppossi *possi;
63
63
for (possi = pkg->available.depended; possi; possi = possi->rev_next) {
64
64
if (!useavailable(possi->up->up))
78
78
// only change the `suggested' value if we also increase the `priority'
79
79
// Return 2 if we made a change due to a Recommended, Depends or Conficts,
80
80
// or 1 if we offered or made a change because of an Optional line.
82
fprintf(debug,"packagelist[%p]::resolvesuggest()\n",this);
81
debug(dbg_general, "packagelist[%p]::resolvesuggest()", this);
83
82
int changemade, maxchangemade;
88
87
for (index=0; index<nitems; index++) {
89
88
if (!table[index]->pkg->name) continue;
90
if (depdebug && debug)
91
fprintf(debug,"packagelist[%p]::resolvesuggest() loop[%i] %s / %d\n",
92
this, index, table[index]->pkg->name, changemade);
89
debug(dbg_depcon, "packagelist[%p]::resolvesuggest() loop[%i] %s / %d",
90
this, index, table[index]->pkg->name, changemade);
93
91
dependency *depends;
94
for (depends= findinfo(table[index]->pkg)->depends;
92
for (depends = find_pkgbin(table[index]->pkg)->depends;
96
94
depends= depends->next) {
97
95
changemade = max(changemade, resolvedepcon(depends));
99
97
changemade= checkdependers(table[index]->pkg,changemade);
100
for (depends= findinfo(table[index]->pkg)->depends;
98
for (depends = find_pkgbin(table[index]->pkg)->depends;
102
100
depends= depends->next) {
103
101
if (depends->type != dep_provides) continue;
104
102
changemade= checkdependers(depends->list->ed,changemade);
106
if (depdebug && debug)
107
fprintf(debug,"packagelist[%p]::resolvesuggest() loop[%i] %s / -> %d\n",
108
this, index, table[index]->pkg->name, changemade);
104
debug(dbg_depcon, "packagelist[%p]::resolvesuggest() loop[%i] %s / -> %d",
105
this, index, table[index]->pkg->name, changemade);
110
107
if (!changemade) break;
111
108
maxchangemade = max(maxchangemade, changemade);
114
fprintf(debug,"packagelist[%p]::resolvesuggest() done; maxchangemade=%d\n",
110
debug(dbg_general, "packagelist[%p]::resolvesuggest() done; maxchangemade=%d",
111
this, maxchangemade);
116
112
return maxchangemade;
119
115
static int dep_update_best_to_change_stop(perpackagestate *& best, pkginfo *trythis) {
120
116
// There's no point trying to select a pure virtual package.
121
117
if (!trythis->clientdata) return 0;
123
if (depdebug && debug)
124
fprintf(debug,"update_best_to_change(best=%s{%d}, test=%s{%d});\n",
125
best ? best->pkg->name : "", best ? (int)best->spriority : -1,
126
trythis->name, trythis->clientdata->spriority);
119
debug(dbg_depcon, "update_best_to_change(best=%s{%d}, test=%s{%d});",
120
best ? best->pkg->name : "", best ? (int)best->spriority : -1,
121
trythis->name, trythis->clientdata->spriority);
128
123
// If the problem is caused by us deselecting one of these packages
129
124
// we should not try to select another one instead.
133
128
if (!best) goto yes;
135
130
// If only one of the packages is available, use that one
136
if (!informative(trythis,&trythis->available) &&
137
informative(best->pkg,&best->pkg->available)) return 0;
138
if (informative(trythis,&trythis->available) &&
139
!informative(best->pkg,&best->pkg->available)) goto yes;
131
if (!pkg_is_informative(trythis, &trythis->available) &&
132
pkg_is_informative(best->pkg, &best->pkg->available))
134
if (pkg_is_informative(trythis, &trythis->available) &&
135
!pkg_is_informative(best->pkg, &best->pkg->available))
141
138
// Select the package with the lowest priority (ie, the one of whom
142
139
// we were least sure we wanted it deselected).
143
140
if (trythis->clientdata->spriority > best->spriority) return 0;
165
162
if (!er || !would_like_to_install(er->selected,per) ||
166
163
!ed || !would_like_to_install(ed->selected,ped)) return 0;
168
165
add(dep, dp_must);
170
167
er= per->clientdata; // these can be changed by add
171
168
ed= ped->clientdata;
173
if (depdebug && debug)
174
fprintf(debug,"packagelist[%p]::deselect_one_of(): er %s{%d} ed %s{%d} [%p]\n",
175
this, er->pkg->name, er->spriority, ed->pkg->name, ed->spriority, dep);
171
"packagelist[%p]::deselect_one_of(): er %s{%d} ed %s{%d} [%p]",
172
this, er->pkg->name, er->spriority, ed->pkg->name, ed->spriority, dep);
177
174
perpackagestate *best;
179
176
// Try not keep packages needing reinstallation.
191
188
else best= ed; // ... failing that, the second
193
if (depdebug && debug)
194
fprintf(debug,"packagelist[%p]::deselect_one_of(): best %s{%d}\n",
195
this, best->pkg->name, best->spriority);
190
debug(dbg_depcon, "packagelist[%p]::deselect_one_of(): best %s{%d}",
191
this, best->pkg->name, best->spriority);
197
193
if (best->spriority >= sp_deselecting) return 0;
209
205
deppossi *possi, *provider;
212
if (depdebug && debug) {
213
fprintf(debug,"packagelist[%p]::resolvedepcon([%p] %s --%s-->",
214
this, depends, depends->up->name, relatestrings[depends->type]);
215
for (possi=depends->list; possi; possi=possi->next)
216
fprintf(debug," %s",possi->ed->name);
217
fprintf(debug,"); (ing)->want=%s\n",
218
depends->up->clientdata
219
? wantstrings[depends->up->clientdata->suggested]
220
: "(no clientdata)");
208
if (debug_has_flag(dbg_depcon)) {
211
for (possi = depends->list; possi; possi = possi->next) {
213
pkg_names(possi->ed->name);
217
"packagelist[%p]::resolvedepcon([%p] %s --%s-->%s); (ing)->want=%s",
218
this, depends, depends->up->name, relatestrings[depends->type],
219
pkg_names.string(), depends->up->clientdata ?
220
wantstrings[depends->up->clientdata->suggested] : "(no clientdata)");
223
223
if (!depends->up->clientdata) return 0;
225
225
switch (depends->type) {
241
241
possi = depends->list;
242
242
while (possi && !deppossatisfied(possi, &fixbyupgrade))
243
243
possi = possi->next;
244
if (depdebug && debug)
245
fprintf(debug,"packagelist[%p]::resolvedepcon([%p]): depends found %s\n",
247
possi ? possi->ed->name : "[none]");
244
debug(dbg_depcon, "packagelist[%p]::resolvedepcon([%p]): depends found %s",
245
this, depends, possi ? possi->ed->name : "[none]");
248
246
if (possi) return 0;
250
248
// Ensures all in the recursive list; adds info strings; ups priorities
282
281
if (!foundany) addunavailable(possi);
285
if (depdebug && debug) fprintf(debug,"packagelist[%p]::resolvedepcon([%p]): "
286
"mustdeselect nobest\n", this,depends);
285
"packagelist[%p]::resolvedepcon([%p]): mustdeselect nobest",
290
if (depdebug && debug)
291
fprintf(debug,"packagelist[%p]::resolvedepcon([%p]): select best=%s{%d}\n",
292
this,depends, best->pkg->name, best->spriority);
291
"packagelist[%p]::resolvedepcon([%p]): select best=%s{%d}",
292
this, depends, best->pkg->name, best->spriority);
293
293
if (best->spriority >= sp_selecting) return r;
294
294
/* Always select depends. Only select recommends if we got here because
295
295
* of a manually-initiated install request. */
298
298
best->spriority= sp_selecting;
300
300
return r ? 2 : 0;
303
303
best= depends->up->clientdata;
304
if (depdebug && debug)
305
fprintf(debug,"packagelist[%p]::resolvedepcon([%p]): mustdeselect best=%s{%d}\n",
306
this,depends, best->pkg->name, best->spriority);
305
"packagelist[%p]::resolvedepcon([%p]): mustdeselect best=%s{%d}",
306
this, depends, best->pkg->name, best->spriority);
308
308
if (best->spriority >= sp_deselecting) return r;
309
309
/* Always remove depends, but never remove recommends. */
314
314
best->spriority= sp_deselecting;
316
316
return r ? 2 : 0;
318
318
case dep_conflicts:
320
debug(dbg_depcon, "packagelist[%p]::resolvedepcon([%p]): conflict",
321
if (depdebug && debug)
322
fprintf(debug,"packagelist[%p]::resolvedepcon([%p]): conflict\n",
325
323
if (would_like_to_install(depends->up->clientdata->selected,depends->up) == 0)
328
if (depdebug && debug)
329
fprintf(debug,"packagelist[%p]::resolvedepcon([%p]): conflict installing 1\n",
327
"packagelist[%p]::resolvedepcon([%p]): conflict installing 1",
332
330
if (!deppossatisfied(depends->list,0)) return 0;
334
if (depdebug && debug)
335
fprintf(debug,"packagelist[%p]::resolvedepcon([%p]): conflict satisfied - ouch\n",
333
"packagelist[%p]::resolvedepcon([%p]): conflict satisfied - ouch",
338
336
if (depends->up != depends->list->ed) {
339
337
r= deselect_one_of(depends->up, depends->list->ed, depends); if (r) return r;
345
343
if (provider->up->up == depends->up) continue; // conflicts & provides same thing
346
344
r= deselect_one_of(depends->up, provider->up->up, depends); if (r) return r;
348
if (depdebug && debug)
349
fprintf(debug,"packagelist[%p]::resolvedepcon([%p]): no desel\n", this,depends);
346
debug(dbg_depcon, "packagelist[%p]::resolvedepcon([%p]): no desel",
353
351
internerr("unknown deptype");
363
361
// restriction is violated ie that the target package is wanted
365
363
pkginfo::pkgwant want= pkginfo::want_purge;
367
365
if (possi->ed->clientdata) {
368
366
want= possi->ed->clientdata->selected;
369
367
would= would_like_to_install(want,possi->ed);
374
372
if ((possi->up->type == dep_conflicts || possi->up->type == dep_breaks)
375
373
? possi->up->up != possi->ed && would != 0