~ubuntu-branches/debian/stretch/aptitude/stretch

« back to all changes in this revision

Viewing changes to .pc/aptitude-0.6.8.2-1.1/src/generic/apt/aptitude_resolver_universe.cc

  • Committer: Package Import Robot
  • Author(s): Andreas Barth
  • Date: 2013-08-16 13:19:40 UTC
  • Revision ID: package-import@ubuntu.com-20130816131940-qpv81q44y1ss5ger
Tags: 0.6.8.2-1.1
* cherrypick from git:
  + 794b91 fix FTBFS with g++-4.8
  + c142a7 task_list is not extern
* re-upload to unstable to have again a working package on mips*.
  Closes: #708812, #714186

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// aptitude_resolver_universe.cc                       -*-c++-*-
 
2
 
 
3
#include "aptitude_resolver_universe.h"
 
4
 
 
5
#include "config_signal.h"
 
6
 
 
7
#include <generic/problemresolver/problemresolver.h>
 
8
#include <generic/problemresolver/solution.h>
 
9
 
 
10
#include <algorithm>
 
11
#include <sstream>
 
12
 
 
13
#include <apt-pkg/error.h>
 
14
 
 
15
#include <cwidget/generic/util/ssprintf.h>
 
16
 
 
17
#include <aptitude.h>
 
18
#include <loggers.h>
 
19
 
 
20
using namespace std;
 
21
using aptitude::Loggers;
 
22
using cwidget::util::ssprintf;
 
23
 
 
24
static inline
 
25
bool ver_disappeared(const pkgCache::VerIterator ver)
 
26
{
 
27
  return
 
28
    !ver.Downloadable() &&
 
29
    (ver != ver.ParentPkg().CurrentVer() ||
 
30
     ver.ParentPkg()->CurrentState == pkgCache::State::ConfigFiles);
 
31
}
 
32
 
 
33
/** Detects dependencies that (provides ignored) are conflicts that
 
34
 *  can't be triggered ever.
 
35
 *
 
36
 *  We want to eliminate these dependencies because they are an
 
37
 *  inconsistency (albiet spurious) in aptitude's model: they don't
 
38
 *  appear as reverse dependencies since there is no package that they
 
39
 *  would be followed backwards from.
 
40
 *
 
41
 *  Ignoring provides is safe since conflicts as seen in the model are
 
42
 *  specific to a particular provides link, and
 
43
 *  conflicts-through-provides can't be empty (true?  maybe not: what
 
44
 *  about disappeared providers?).
 
45
 */
 
46
static bool empty_conflict(const pkgCache::DepIterator &dep,
 
47
                           const pkgCache::PrvIterator &prv)
 
48
{
 
49
  if(!is_conflict(dep->Type))
 
50
    return false;
 
51
 
 
52
  if(prv.end())
 
53
    {
 
54
      bool found = false;
 
55
      for(pkgCache::VerIterator ver =
 
56
            const_cast<pkgCache::DepIterator &>(dep).TargetPkg().VersionList();
 
57
          !ver.end() && !found; ++ver)
 
58
        {
 
59
          if(!ver_disappeared(ver) &&
 
60
             (dep.TargetVer() == NULL ||
 
61
              _system->VS->CheckDep(ver.VerStr(),
 
62
                                    dep->CompareOp,
 
63
                                    dep.TargetVer())))
 
64
            found = true;
 
65
        }
 
66
 
 
67
      // If we found no matching non-disappeared version, then this
 
68
      // conflict is irrelevant.
 
69
      return !found;
 
70
    }
 
71
  else
 
72
    {
 
73
      if(ver_disappeared(const_cast<pkgCache::PrvIterator &>(prv).OwnerVer()))
 
74
        return true;
 
75
 
 
76
      // If the provider doesn't match the dependency, then this is an
 
77
      // irrelevant conflict.
 
78
      return !_system->VS->CheckDep(prv.ProvideVersion(),
 
79
                                    dep->CompareOp, dep.TargetVer());
 
80
    }
 
81
}
 
82
 
 
83
string aptitude_resolver_version::get_name() const
 
84
{
 
85
  pkgCache::VerIterator ver(get_ver());
 
86
  pkgCache::PkgIterator pkg(get_pkg());
 
87
  if(!ver.end())
 
88
    {
 
89
      // If there are two distinct package files with the same
 
90
      // Version, apt will give them the same VerStr.  Detect and
 
91
      // compensate for this.
 
92
      int count=0;
 
93
      int idx=-1;
 
94
 
 
95
      for(pkgCache::VerIterator i=pkg.VersionList(); !i.end(); ++i)
 
96
        {
 
97
          if(i==ver)
 
98
            {
 
99
              idx=count;
 
100
              ++count;
 
101
            }
 
102
          else if(!strcmp(i.VerStr(), ver.VerStr()))
 
103
            ++count;
 
104
        }
 
105
 
 
106
      // if not, we have a "version" of this package that's not in
 
107
      // its list of versions!
 
108
      eassert(idx>=0);
 
109
 
 
110
      if(count>1)
 
111
        {
 
112
          ostringstream s;
 
113
          s << ver.VerStr() << "<" << idx+1 << ">";
 
114
          return s.str();
 
115
        }
 
116
      else
 
117
        return ver.VerStr();
 
118
    }
 
119
  else
 
120
    // Note that this is an invalid version string for apt, so we
 
121
    // can't clash with real versions.
 
122
    return "[UNINST]";
 
123
}
 
124
 
 
125
bool aptitude_resolver_version::revdep_iterator::applicable() const
 
126
{
 
127
  if(!is_interesting_dep(dep_lst, cache))
 
128
    return false;
 
129
 
 
130
  // Screen out self-conflicts from the reverse dependency list.  Note
 
131
  // that we can screen out *any* conflict on a version of the same
 
132
  // package: if a version conflicts with itself it's ignored, and if
 
133
  // a version conflicts with a different version of the same package,
 
134
  // that's just a redundant expression of the rule that no two
 
135
  // versions of the same package can be simultaneously installed.
 
136
  //
 
137
  // As a bonus, this lets us match what gets generated for forward
 
138
  // deps.
 
139
  if(is_conflict(dep_lst->Type) &&
 
140
     !prv_lst.end() &&
 
141
     const_cast<pkgCache::PrvIterator &>(prv_lst).OwnerPkg() == const_cast<pkgCache::DepIterator &>(dep_lst).ParentPkg())
 
142
    return false;
 
143
  // Self-deps are always irrelevant regardless of whether we're in a
 
144
  // Provides: or not.
 
145
  if(prv_lst.end() &&
 
146
     const_cast<pkgCache::DepIterator &>(dep_lst).ParentPkg() == const_cast<pkgCache::DepIterator &>(dep_lst).TargetPkg())
 
147
    return false;
 
148
 
 
149
  // Drop irrelevant conflicts; that is, conflicts that are never
 
150
  // satisfied.  This improves the connection consistency of the
 
151
  // abstract model.
 
152
  if(empty_conflict(dep_lst, prv_lst))
 
153
    return false;
 
154
 
 
155
 
 
156
  // Unversioned deps always apply unless they are self-deps or
 
157
  // empty conflicts.
 
158
  if(!dep_lst.TargetVer())
 
159
    return true;
 
160
 
 
161
  if(provides_open)
 
162
    return _system->VS->CheckDep(prv_lst.ProvideVersion(),
 
163
                                 dep_lst->CompareOp, dep_lst.TargetVer());
 
164
  else
 
165
    return _system->VS->CheckDep(ver.VerStr(),
 
166
                                 dep_lst->CompareOp, dep_lst.TargetVer());
 
167
}
 
168
 
 
169
void aptitude_resolver_version::revdep_iterator::normalize()
 
170
{
 
171
  while(!dep_lst.end() && !applicable())
 
172
    ++dep_lst;
 
173
 
 
174
  if(dep_lst.end() && !provides_open)
 
175
    {
 
176
      eassert(prv_lst.end());
 
177
      prv_lst=ver.ProvidesList();
 
178
      provides_open=true;
 
179
      if(!prv_lst.end())
 
180
        {
 
181
          dep_lst=prv_lst.ParentPkg().RevDependsList();
 
182
          while(!dep_lst.end() && !applicable())
 
183
            ++dep_lst;
 
184
        }
 
185
    }
 
186
 
 
187
  // When we've run out of provides, give up..
 
188
  while(dep_lst.end() && !prv_lst.end())
 
189
    {
 
190
      eassert(provides_open);
 
191
      ++prv_lst;
 
192
 
 
193
      if(!prv_lst.end())
 
194
        {
 
195
          eassert(!prv_lst.ParentPkg().end());
 
196
          dep_lst=prv_lst.ParentPkg().RevDependsList();
 
197
 
 
198
          while(!dep_lst.end() && !applicable())
 
199
            ++dep_lst;
 
200
        }
 
201
    }
 
202
}
 
203
 
 
204
inline void aptitude_resolver_version::dep_iterator::advance()
 
205
{
 
206
  bool move_to_next_dep = true;
 
207
 
 
208
  eassert(prv_open == !prv.end());
 
209
 
 
210
  // If the Provides list is nonempty, advance it.
 
211
  if(!prv.end())
 
212
    {
 
213
      eassert(prv_open);
 
214
 
 
215
      ++prv;
 
216
      if(prv.end())
 
217
        prv_open = false;
 
218
      else
 
219
        move_to_next_dep = false;
 
220
    }
 
221
  // If we weren't trying to iterate over a Provides list *and* the
 
222
  // current dep is a non-versioned Conflicts, start such an
 
223
  // iteration.
 
224
  else if(!prv_open && is_conflict(dep->Type) &&
 
225
          !dep.TargetVer())
 
226
    {
 
227
      prv = dep.TargetPkg().ProvidesList();
 
228
      if(!prv.end()) // otherwise we should advance to the next dep.
 
229
        {
 
230
          prv_open = true;
 
231
          move_to_next_dep = false;
 
232
        }
 
233
    }
 
234
 
 
235
  eassert(prv_open == !prv.end());
 
236
 
 
237
  if(move_to_next_dep)
 
238
    {
 
239
      if(!dep.end() && is_conflict(dep->Type))
 
240
        ++dep;
 
241
      else
 
242
        {
 
243
          // If it's not a conflict, skip a whole OR group.
 
244
          while(!dep.end() && (dep->CompareOp & pkgCache::Dep::Or))
 
245
            ++dep;
 
246
 
 
247
          // Now we're on the last element of the OR group, push
 
248
          // forward.
 
249
          if(!dep.end())
 
250
            ++dep;
 
251
        }
 
252
    }
 
253
}
 
254
 
 
255
inline bool
 
256
aptitude_resolver_version::dep_iterator::applicable(const pkgCache::DepIterator &dep,
 
257
                                                    const pkgCache::PrvIterator &prv,
 
258
                                                    bool prv_open,
 
259
                                                    pkgDepCache *cache)
 
260
{
 
261
  if(prv_open)
 
262
    {
 
263
      eassert(!dep.end());
 
264
      eassert(!prv.end());
 
265
      eassert(is_conflict(dep->Type));
 
266
 
 
267
      // NB: inlined pkgCache::DepIterator::IsIgnorable
 
268
      // if(dep.IsIgnorable(prv) == true)
 
269
      //   return false;
 
270
      const pkgCache::PkgIterator pkg = dep.ParentPkg();
 
271
      if(prv.OwnerPkg()->Group == pkg->Group)
 
272
        return false;
 
273
      if(pkg->Group == dep.TargetPkg()->Group && prv.OwnerPkg()->Group != pkg->Group)
 
274
        return false;
 
275
    }
 
276
  else
 
277
    if(dep.ParentPkg() == dep.TargetPkg())
 
278
      return false;
 
279
 
 
280
  if(!is_interesting_dep(dep, cache))
 
281
    return false;
 
282
  if(empty_conflict(dep, prv))
 
283
    return false;
 
284
 
 
285
  return true;
 
286
}
 
287
 
 
288
bool aptitude_resolver_version::dep_iterator::applicable()
 
289
{
 
290
  if(is_conflict(dep->Type))
 
291
    // In this case the current dependency is represented completely
 
292
    // by the depends and provides iterators; no need to step.
 
293
    return applicable(dep, prv, prv_open, cache);
 
294
  else
 
295
    {
 
296
      // We need to check everything in the current OR block.
 
297
      pkgCache::DepIterator tmpdep = dep;
 
298
 
 
299
      if(!tmpdep.end() && applicable(tmpdep, prv, prv_open, cache))
 
300
        return true;
 
301
      while(!tmpdep.end() && (tmpdep->CompareOp & pkgCache::Dep::Or))
 
302
        {
 
303
          ++tmpdep;
 
304
          if(!tmpdep.end() && applicable(tmpdep, prv, prv_open, cache))
 
305
            return true;
 
306
        }
 
307
    }
 
308
 
 
309
  return false;
 
310
}
 
311
 
 
312
void aptitude_resolver_version::dep_iterator::normalize()
 
313
{
 
314
  while(!dep.end() && !applicable())
 
315
    advance();
 
316
  // If we ran out of deps, we're done!
 
317
}
 
318
 
 
319
void aptitude_resolver_dep::solver_iterator::normalize()
 
320
{
 
321
  if(!is_conflict(dep_lst->Type))
 
322
    {
 
323
      while(!end())
 
324
        {
 
325
          for(; ver_lst.end() == false; ++ver_lst)
 
326
            {
 
327
              if(dep_lst.IsIgnorable(ver_lst.ParentPkg()) == true)
 
328
                continue;
 
329
 
 
330
              if(_system->VS->CheckDep(ver_lst.VerStr(),
 
331
                                       dep_lst->CompareOp,
 
332
                                       dep_lst.TargetVer()) == false)
 
333
                continue;
 
334
 
 
335
              if(ver_disappeared(ver_lst) == false)
 
336
                return;
 
337
            }
 
338
 
 
339
          // If we ran out of versions, try provides instead.
 
340
          for(; prv_lst.end() == false; ++prv_lst)
 
341
            {
 
342
              if(dep_lst.IsIgnorable(prv_lst) == true)
 
343
                continue;
 
344
 
 
345
              if(_system->VS->CheckDep(prv_lst.ProvideVersion(),
 
346
                                       dep_lst->CompareOp,
 
347
                                       dep_lst.TargetVer()) == false)
 
348
                continue;
 
349
 
 
350
              if(ver_disappeared(prv_lst.OwnerVer()) == false)
 
351
                return;
 
352
            }
 
353
 
 
354
          // No more target versions or providers of the target;
 
355
          // increment the dependency list if we aren't yet at the
 
356
          // end of the OR group.
 
357
 
 
358
          if(!(dep_lst->CompareOp & pkgCache::Dep::Or))
 
359
            finished=true;
 
360
          else
 
361
            {
 
362
              ++dep_lst;
 
363
              // Since we aren't finished, dep_lst should still be
 
364
              // valid.
 
365
              eassert(!dep_lst.end());
 
366
              ver_lst=dep_lst.TargetPkg().VersionList();
 
367
 
 
368
              // Only set the prv_lst to non-end if there is no target
 
369
              // version.
 
370
              prv_lst=dep_lst.TargetPkg().ProvidesList();
 
371
            }
 
372
        }
 
373
    }
 
374
  else
 
375
    {
 
376
      // For Conflicts/Breaks, we're iterating over all the versions of
 
377
      // *one* package for *one* dep, either the owner of the
 
378
      // dep or a provided package.  (prv_lst is mostly
 
379
      // unnecessary, but it makes it simple to remember whether
 
380
      // we have a provides).  Note that the efficiency of this
 
381
      // stanza is based on the *assumption* that most packages
 
382
      // only Provide a few things.
 
383
 
 
384
      // For provided packages, return exactly those packages
 
385
      // that *don't* have a matching Provides.
 
386
      if(!prv_lst.end())
 
387
        {
 
388
          while(!ver_lst.end())
 
389
            {
 
390
              if(ver_lst != prv_lst.OwnerVer() &&
 
391
                 !ver_disappeared(ver_lst))
 
392
                return;
 
393
 
 
394
              ++ver_lst;
 
395
            }
 
396
          // Important point: end version iterators always match
 
397
          // a Conflicts/Breaks! (i.e., those can always be resolved
 
398
          // by removing the conflicted package)
 
399
          return;
 
400
        }
 
401
      else
 
402
        {
 
403
          while(!ver_lst.end())
 
404
            {
 
405
              bool ver_matches=(!dep_lst.TargetVer()) ||
 
406
                (ver_lst.VerStr() &&
 
407
                 _system->VS->CheckDep(ver_lst.VerStr(),
 
408
                                       dep_lst->CompareOp,
 
409
                                       dep_lst.TargetVer()));
 
410
 
 
411
              if(!ver_matches && !ver_disappeared(ver_lst))
 
412
                // This version resolves the conflict.
 
413
                return;
 
414
              else
 
415
                ++ver_lst;
 
416
            }
 
417
 
 
418
          // Ignore provides; as above, end versions are A-OK.
 
419
          return;
 
420
        }
 
421
    }
 
422
}
 
423
 
 
424
bool aptitude_resolver_dep::solved_by(const aptitude_resolver_version &v) const
 
425
{
 
426
  pkgCache::DepIterator start_iter(cache->GetCache(), const_cast<pkgCache::Dependency *>(start));
 
427
 
 
428
  // First check for moving the source.
 
429
  if(v.get_pkg() == start_iter.ParentPkg() && v.get_ver() != start_iter.ParentVer())
 
430
    return true;
 
431
 
 
432
  // Now check each of the members of the OR group.
 
433
  pkgCache::DepIterator d = start_iter;
 
434
 
 
435
  if(!is_conflict(start->Type))
 
436
    {
 
437
      // Of course, installing an end version never fixes a
 
438
      // non-conflict unless it removes the source (tested for above).
 
439
      if(v.get_ver().end())
 
440
        return false;
 
441
 
 
442
      while(1)
 
443
        {
 
444
          if(d.IsIgnorable(v.get_pkg()) == false
 
445
             && _system->VS->CheckDep(v.get_ver().VerStr(),
 
446
                                      d->CompareOp,
 
447
                                      d.TargetVer()) == true)
 
448
            return true;
 
449
 
 
450
          // Check for a resolution via Provides.
 
451
          for(pkgCache::PrvIterator p2 = v.get_ver().ProvidesList();
 
452
              p2.end() == false; ++p2)
 
453
            {
 
454
              if(d.IsIgnorable(p2) == true)
 
455
                continue;
 
456
 
 
457
              if(p2.ParentPkg() != d.TargetPkg())
 
458
                continue;
 
459
 
 
460
              if(_system->VS->CheckDep(p2.ProvideVersion(),
 
461
                                       d->CompareOp,
 
462
                                       d.TargetVer()) == true)
 
463
                return true;
 
464
            }
 
465
 
 
466
          if((d->CompareOp & pkgCache::Dep::Or) != 0)
 
467
            ++d;
 
468
          else
 
469
            return false;
 
470
        }
 
471
    }
 
472
  else if(prv == NULL)
 
473
    {
 
474
      if(d.TargetPkg() != v.get_pkg())
 
475
        return false;
 
476
 
 
477
      if(v.get_ver().end())
 
478
        return true;
 
479
 
 
480
      // Check the non-virtual part of the conflict: the package is
 
481
      // the same and the version **doesn't** match.
 
482
      return !(!d.TargetVer() || _system->VS->CheckDep(v.get_ver().VerStr(),
 
483
                                                       d->CompareOp,
 
484
                                                       d.TargetVer()));
 
485
    }
 
486
  else
 
487
    {
 
488
      pkgCache::PrvIterator prv_iter(cache->GetCache(), const_cast<pkgCache::Provides *>(prv),
 
489
                                     (pkgCache::Package *)0);
 
490
 
 
491
      // Only other versions of the provider can solve this.
 
492
      if(v.get_pkg() != prv_iter.OwnerPkg())
 
493
        return false;
 
494
      else
 
495
        return v.get_ver() != prv_iter.OwnerVer();
 
496
    }
 
497
}
 
498
 
 
499
aptitude_resolver_dep::solver_iterator &aptitude_resolver_dep::solver_iterator::operator++()
 
500
{
 
501
  eassert(!end());
 
502
 
 
503
  // Advance whatever needs to be advanced next in the
 
504
  // sub-list.
 
505
 
 
506
  if(!ver_lst.end())
 
507
    ++ver_lst;
 
508
  else if(!is_conflict(dep_lst->Type))
 
509
    {
 
510
      if(!prv_lst.end())
 
511
        ++prv_lst;
 
512
    }
 
513
  else
 
514
    finished=true;
 
515
 
 
516
  normalize();
 
517
 
 
518
  return *this;
 
519
}
 
520
 
 
521
aptitude_resolver_version::dep_iterator &aptitude_resolver_version::dep_iterator::operator++()
 
522
{
 
523
  eassert(!dep.end());
 
524
 
 
525
  advance();
 
526
  normalize();
 
527
 
 
528
  return *this;
 
529
}
 
530
 
 
531
aptitude_resolver_version aptitude_resolver_dep::solver_iterator::operator*() const
 
532
{
 
533
  eassert(!end());
 
534
 
 
535
  if(!ver_lst.end())
 
536
    return aptitude_resolver_version::make_install(ver_lst, cache);
 
537
  else // In this case we're trying to remove some package or other.
 
538
    {
 
539
      if(!is_conflict(dep_lst->Type))
 
540
        {
 
541
          // Assume this because otherwise end() should be true.
 
542
          eassert(!prv_lst.end());
 
543
 
 
544
          return aptitude_resolver_version::make_install(const_cast<pkgCache::PrvIterator &>(prv_lst).OwnerVer(), cache);
 
545
        }
 
546
      else if(!prv_lst.end())
 
547
        return aptitude_resolver_version::make_removal(const_cast<pkgCache::PrvIterator &>(prv_lst).OwnerPkg(), cache);
 
548
      else
 
549
        return aptitude_resolver_version::make_removal(const_cast<pkgCache::DepIterator &>(dep_lst).TargetPkg(), cache);
 
550
    }
 
551
}
 
552
 
 
553
void aptitude_universe::dep_iterator::normalize()
 
554
{
 
555
  while(dep.end() && !pkg.end())
 
556
    {
 
557
      while(dep.end() && !ver.end())
 
558
        {
 
559
          ++ver;
 
560
          if(!ver.end())
 
561
            dep=aptitude_resolver_version::dep_iterator(ver, cache);
 
562
        }
 
563
 
 
564
      if(dep.end())
 
565
        {
 
566
          ++pkg;
 
567
          if(!pkg.end())
 
568
            {
 
569
              ver=pkg.VersionList();
 
570
              if(!ver.end())
 
571
                dep=aptitude_resolver_version::dep_iterator(ver, cache);
 
572
            }
 
573
        }
 
574
    }
 
575
}
 
576
 
 
577
bool aptitude_universe::broken_dep_iterator::dep_is_inst_broken(const pkgCache::DepIterator &d) const
 
578
{
 
579
  pkgCache::DepIterator d2=d;
 
580
 
 
581
  while(d2->CompareOp & pkgCache::Dep::Or)
 
582
    ++d2;
 
583
 
 
584
  return ((*cache)[d2] & pkgDepCache::DepGInstall)==0;
 
585
}
 
586
 
 
587
struct DummyEmptySolution
 
588
{
 
589
  aptitude_resolver_version version_of(const aptitude_resolver_package &p) const
 
590
  {
 
591
    return p.current_version();
 
592
  }
 
593
};
 
594
 
 
595
void dumpDep(std::ostream &out, pkgCache::DepIterator &dep,
 
596
             pkgDepCache *cache)
 
597
{
 
598
  out << dep.ParentPkg().FullName(false) << " ("
 
599
      << dep.ParentVer().VerStr() << ") "
 
600
      << dep.DepType()
 
601
      << " "
 
602
      << dep.TargetPkg().FullName(false);
 
603
  if(dep.TargetVer() != NULL)
 
604
    {
 
605
      out << " (" << dep.CompType() << " " << dep.TargetVer() << ")";
 
606
    }
 
607
  std::vector<std::string> flags;
 
608
  if(dep->Type & pkgCache::Dep::Or)
 
609
    flags.push_back("OR");
 
610
 
 
611
  unsigned char dep_state = (*cache)[dep];
 
612
  if(dep_state & pkgDepCache::DepNow)
 
613
    flags.push_back("DEPNOW");
 
614
  if(dep_state & pkgDepCache::DepInstall)
 
615
    flags.push_back("DEPINSTALL");
 
616
  if(dep_state & pkgDepCache::DepCVer)
 
617
    flags.push_back("DEPCVER");
 
618
  if(dep_state & pkgDepCache::DepGNow)
 
619
    flags.push_back("DEPGNOW");
 
620
  if(dep_state & pkgDepCache::DepGInstall)
 
621
    flags.push_back("DEPGINSTALL");
 
622
  if(dep_state & pkgDepCache::DepGCVer)
 
623
    flags.push_back("DEPGCVER");
 
624
 
 
625
  out << "[";
 
626
  bool first = true;
 
627
  for(std::vector<std::string>::const_iterator it =
 
628
        flags.begin(); it != flags.end(); ++it)
 
629
    {
 
630
      if(first)
 
631
        first = false;
 
632
      else
 
633
        out << " ";
 
634
 
 
635
      out << *it;
 
636
    }
 
637
  out << "]";
 
638
}
 
639
 
 
640
void aptitude_universe::broken_dep_iterator::normalize()
 
641
{
 
642
  while(!the_dep.end() &&
 
643
        !(is_interesting_dep(the_dep, cache) &&
 
644
          dep_is_inst_broken(the_dep)))
 
645
    ++the_dep;
 
646
 
 
647
  while(the_dep.end() && !pkg.end())
 
648
    {
 
649
      // Make sure we move at least one package forward!
 
650
      // Otherwise we just spin on the same package over and over,
 
651
      // since it's still broken..
 
652
      ++pkg;
 
653
 
 
654
      if(!pkg.end())
 
655
        {
 
656
          // Examine just the InstVer of the package.
 
657
          pkgCache::VerIterator ver=(*cache)[pkg].InstVerIter(*cache);
 
658
 
 
659
          if(!ver.end())
 
660
            the_dep=ver.DependsList();
 
661
 
 
662
          while(!the_dep.end() &&
 
663
                !(is_interesting_dep(the_dep, cache) &&
 
664
                  dep_is_inst_broken(the_dep)))
 
665
            ++the_dep;
 
666
 
 
667
          if(the_dep.end())
 
668
            ++ver;
 
669
        }
 
670
    }
 
671
 
 
672
  eassert(the_dep.end() || is_interesting_dep(the_dep, cache));
 
673
 
 
674
  // Now dep is a broken critical dep or an end dep.  If it is a
 
675
  // conflicts, we might need to push down into Provides...
 
676
  if(!the_dep.end() && is_conflict(the_dep->Type))
 
677
    {
 
678
      // If we aren't in provides, check whether the dep is
 
679
      // trivially broken (i.e., without following provides).
 
680
      if(!prv_open)
 
681
        {
 
682
          // If it's a direct self-conflict, jump into provides
 
683
          // right away.
 
684
          if(the_dep.TargetPkg() != the_dep.ParentPkg())
 
685
            {
 
686
              pkgCache::VerIterator ver=(*cache)[the_dep.TargetPkg()].InstVerIter(*cache);
 
687
 
 
688
              if(!ver.end() &&
 
689
                 !ver_disappeared(ver) &&
 
690
                 (!the_dep.TargetVer() ||
 
691
                  (ver.VerStr() &&
 
692
                   _system->VS->CheckDep(ver.VerStr(),
 
693
                                         the_dep->CompareOp,
 
694
                                         the_dep.TargetVer()))))
 
695
                // OK, the dep is broken without provides, no need
 
696
                // to descend.
 
697
                return;
 
698
            }
 
699
 
 
700
          prv_open=true;
 
701
          prv=the_dep.TargetPkg().ProvidesList();
 
702
        }
 
703
 
 
704
      // Ok, we have found something that causes breakage.  The
 
705
      // provides-list is a list of all the package versions that
 
706
      // provide this package name; move forward until we find one
 
707
      // that matches.
 
708
      while(!prv.end())
 
709
        {
 
710
          // Ignore indirect self-conflicts.
 
711
          if(prv.OwnerPkg() != the_dep.ParentPkg())
 
712
            {
 
713
              // First, is the providing version going to be
 
714
              // installed?
 
715
              if((*cache)[prv.OwnerPkg()].InstVerIter(*cache) == prv.OwnerVer())
 
716
                {
 
717
                  // Ok, does it match the version string?
 
718
                  bool matches =
 
719
                    !the_dep.TargetVer() ||
 
720
                    (prv.ProvideVersion() &&
 
721
                     _system->VS->CheckDep(prv.ProvideVersion(),
 
722
                                           the_dep->CompareOp,
 
723
                                           the_dep.TargetVer()));
 
724
 
 
725
                  if(ver_disappeared(prv.OwnerVer()))
 
726
                    matches = false;
 
727
 
 
728
                  if(matches)
 
729
                    return;
 
730
                }
 
731
            }
 
732
 
 
733
          ++prv;
 
734
        }
 
735
 
 
736
      // if all provides are exhausted, increment the dep and try
 
737
      // again.  (probably this was only a self-conflict and
 
738
      // nothing else)
 
739
      ++the_dep;
 
740
      prv_open=false;
 
741
      normalize();
 
742
      // hopefully g++ is smart enough to optimize this into a
 
743
      // tail call.
 
744
      return;
 
745
    }
 
746
 
 
747
  if(!end() && !(**this).broken_under(DummyEmptySolution()))
 
748
    {
 
749
      std::ostringstream s;
 
750
      s << **this;
 
751
      // Not translated because this is an internal error that users
 
752
      // should report to me verbatim.
 
753
      _error->Warning("apt thinks that %s is broken, but I don't.",
 
754
                      s.str().c_str());
 
755
      ++(*this);
 
756
      return;
 
757
    }
 
758
}
 
759
 
 
760
aptitude_universe::broken_dep_iterator &aptitude_universe::broken_dep_iterator::operator++()
 
761
{
 
762
  eassert(!pkg.end());
 
763
  // If the_dep.end() we have pkg.end().
 
764
  eassert(!the_dep.end());
 
765
 
 
766
  if(!prv_open && is_conflict(the_dep->Type))
 
767
    {
 
768
      prv_open = true;
 
769
      prv = the_dep.TargetPkg().ProvidesList();
 
770
    }
 
771
  else if(prv_open && !prv.end())
 
772
    ++prv;
 
773
  else
 
774
    ++the_dep;
 
775
 
 
776
  normalize();
 
777
  return *this;
 
778
}
 
779
 
 
780
std::ostream &operator<<(ostream &out, const aptitude_resolver_package &p)
 
781
{
 
782
  return out << p.get_name();
 
783
}
 
784
 
 
785
std::ostream &operator<<(ostream &out, const aptitude_resolver_version &v)
 
786
{
 
787
  return out << v.get_package().get_name() << " " << v.get_name();
 
788
}
 
789
 
 
790
std::ostream &operator<<(ostream &out, const aptitude_resolver_dep &d)
 
791
{
 
792
  std::vector<aptitude_resolver_version> solvers;
 
793
  for(aptitude_resolver_dep::solver_iterator i=d.solvers_begin(); !i.end(); ++i)
 
794
    solvers.push_back(*i);
 
795
 
 
796
  generic_solution<aptitude_universe>::ver_name_lt lt;
 
797
  sort(solvers.begin(), solvers.end(), lt);
 
798
 
 
799
  out << d.get_source() << (d.is_soft() ? " -S> {" : " -> {");
 
800
 
 
801
  for(std::vector<aptitude_resolver_version>::const_iterator i = solvers.begin();
 
802
      i != solvers.end(); ++i)
 
803
    {
 
804
      if(i != solvers.begin())
 
805
        out << " ";
 
806
      out << *i;
 
807
    }
 
808
  out << "}";
 
809
 
 
810
  return out;
 
811
}
 
812
 
 
813
std::ostream &operator<<(std::ostream &out, const cfg_level &level)
 
814
{
 
815
  if(level.get_is_discard())
 
816
    out << "discard";
 
817
  else
 
818
    out << level.get_level();
 
819
 
 
820
  return out;
 
821
}
 
822
 
 
823
cfg_level aptitude_universe::parse_level(const std::string &s)
 
824
{
 
825
  typedef generic_problem_resolver<aptitude_universe> aptitude_resolver;
 
826
  if(s == "maximum")
 
827
    return cfg_level::make_level(cost_limits::maximum_level);
 
828
  else if(s == "minimum" || s == "")
 
829
    return cfg_level::make_level(cost_limits::minimum_level);
 
830
  else if(s == "conflict" || s == "discard")
 
831
    return cfg_level::make_conflict();
 
832
  else
 
833
    {
 
834
      char *endptr;
 
835
      int n = static_cast<int>(strtol(s.c_str(), &endptr, 0));
 
836
      if(*endptr != '\0')
 
837
        {
 
838
          std::string msg(ssprintf(N_("Invalid safety level \"%s\" (not \"discard\", \"maximum\", \"minimum\", or an integer)."), s.c_str()));
 
839
          LOG_ERROR(Loggers::getAptitudeResolverCosts(), msg);
 
840
          _error->Error("%s", _(msg.c_str()));
 
841
          return cfg_level::make_level(cost_limits::minimum_level);
 
842
        }
 
843
      else
 
844
        return cfg_level::make_level(n);
 
845
    }
 
846
}
 
847
 
 
848
cfg_level aptitude_universe::parse_levels(const std::string &level1,
 
849
                                          const std::string &level2,
 
850
                                          cfg_level default_level)
 
851
{
 
852
  if(level1.empty() && level2.empty())
 
853
    return default_level;
 
854
  else if(level1.empty())
 
855
    return parse_level(level2);
 
856
  else if(level2.empty())
 
857
    return parse_level(level1);
 
858
  else
 
859
    return std::max<cfg_level>(parse_level(level1), parse_level(level2));
 
860
}
 
861
 
 
862
cfg_level aptitude_universe::get_safe_level()
 
863
{
 
864
  return
 
865
    parse_levels(aptcfg->Find(PACKAGE "::ProblemResolver::Safe-Level", ""),
 
866
                 aptcfg->Find(PACKAGE "::ProblemResolver::Safe-Tier", ""),
 
867
                 cfg_level::make_level(10000));
 
868
}
 
869
 
 
870
cfg_level aptitude_universe::get_keep_all_level()
 
871
{
 
872
  return parse_levels(aptcfg->Find(PACKAGE "::ProblemResolver::Keep-All-Level", ""),
 
873
                      aptcfg->Find(PACKAGE "::ProblemResolver::Keep-All-Tier", ""),
 
874
                      cfg_level::make_level(20000));
 
875
}
 
876
 
 
877
cfg_level aptitude_universe::get_remove_level()
 
878
{
 
879
  return parse_levels(aptcfg->Find(PACKAGE "::ProblemResolver::Remove-Level", ""),
 
880
                      aptcfg->Find(PACKAGE "::ProblemResolver::Remove-Tier", ""),
 
881
                      cfg_level::make_level(10000));
 
882
}
 
883
 
 
884
cfg_level aptitude_universe::get_break_hold_level()
 
885
{
 
886
  return parse_levels(aptcfg->Find(PACKAGE "::ProblemResolver::Break-Hold-Level", ""),
 
887
                      aptcfg->Find(PACKAGE "::ProblemResolver::Break-Hold-Tier", ""),
 
888
                      cfg_level::make_level(40000));
 
889
}
 
890
 
 
891
cfg_level aptitude_universe::get_non_default_level()
 
892
{
 
893
  return parse_levels(aptcfg->Find(PACKAGE "::ProblemResolver::Non-Default-Level", ""),
 
894
                      aptcfg->Find(PACKAGE "::ProblemResolver::Non-Default-Tier", ""),
 
895
                      cfg_level::make_level(50000));
 
896
}
 
897
 
 
898
cfg_level aptitude_universe::get_remove_essential_level()
 
899
{
 
900
  return parse_levels(aptcfg->Find(PACKAGE "::ProblemResolver::Remove-Essential-Level", ""),
 
901
                      aptcfg->Find(PACKAGE "::ProblemResolver::Remove-Essential-Tier", ""),
 
902
                      cfg_level::make_level(60000));
 
903
}
 
904
 
 
905
bool aptitude_universe::is_candidate_for_initial_set(const aptitude_resolver_dep &d) const
 
906
{
 
907
  if(!d.is_soft())
 
908
    return true;
 
909
 
 
910
  if(cache == NULL)
 
911
    return false;
 
912
 
 
913
  pkgCache::DepIterator d2(d.get_dep());
 
914
  while(!d2.end() && (d2->CompareOp & pkgCache::Dep::Or))
 
915
    ++d2;
 
916
 
 
917
  if(d2.end())
 
918
    return true;
 
919
 
 
920
  // Return true only if the dependency is *currently* not broken.
 
921
  return (*cache)[d2] & pkgDepCache::DepGNow;
 
922
}