2 * Copyright (c) 2001, Robert Collins.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * A copy of the GNU General Public License can be found at
12 * Written by Robert Collins <rbtcollins@hotmail.com>
16 /* this is the parent class for all package operations.
20 static const char *cvsid
=
24 #include "package_version.h"
25 #include "package_db.h"
26 #include "package_meta.h"
33 /* a default class to avoid special casing empty packageversions */
35 /* TODO place into the class header */
36 class _defaultversion
: public _packageversion
41 // never try to free me!
44 String
const Name(){return String();}
45 String
const Vendor_version() {return String();}
46 String
const Package_version() {return String();}
47 String
const Canonical_version() {return String();}
48 void setCanonicalVersion (String
const &) {}
49 package_status_t
Status (){return package_notinstalled
;}
50 package_type_t
Type () {return package_binary
;}
51 String
const getfirstfile () {return String();}
52 String
const getnextfile () {return String();}
53 String
const SDesc () {return String();}
54 void set_sdesc (String
const &) {}
55 String
const LDesc () {return String();}
56 void set_ldesc (String
const &) {}
59 static _defaultversion defaultversion
;
61 /* the wrapper class */
62 packageversion::packageversion() : data (&defaultversion
)
67 /* Create from an actual package */
68 packageversion::packageversion (_packageversion
*pkg
)
73 data
= &defaultversion
;
77 packageversion::packageversion (packageversion
const &existing
) :
83 packageversion::~packageversion()
85 if (--data
->references
== 0)
90 packageversion::operator= (packageversion
const &rhs
)
92 ++rhs
.data
->references
;
93 if (--data
->references
== 0)
100 packageversion::operator ! () const
102 return !data
->Name().size();
105 packageversion::operator bool () const
107 return data
->Name().size();
111 packageversion::operator == (packageversion
const &rhs
) const
113 if (this == &rhs
|| data
== rhs
.data
)
116 return data
->Name () == rhs
.data
->Name() && data
->Canonical_version () == rhs
.data
->Canonical_version();
120 packageversion::operator != (packageversion
const &rhs
) const
122 return ! (*this == rhs
);
126 packageversion::operator < (packageversion
const &rhs
) const
128 int t
= data
->Name ().casecompare (rhs
.data
->Name());
133 else if (data
->Canonical_version().casecompare (rhs
.data
->Canonical_version()) < 0)
139 packageversion::Name () const
141 return data
->Name ();
145 packageversion::Canonical_version() const
147 return data
->Canonical_version();
151 packageversion::setCanonicalVersion (String
const &ver
)
153 data
->setCanonicalVersion (ver
);
157 packageversion::getfirstfile ()
159 return data
->getfirstfile ();
163 packageversion::getnextfile ()
165 return data
->getnextfile ();
169 packageversion::SDesc () const
171 return data
->SDesc ();
175 packageversion::set_sdesc (String
const &sdesc
)
177 data
->set_sdesc (sdesc
);
181 packageversion::LDesc () const
183 return data
->LDesc ();
187 packageversion::set_ldesc (String
const &ldesc
)
189 data
->set_ldesc (ldesc
);
193 packageversion::sourcePackage()
195 return data
->sourcePackage();
198 PackageSpecification
&
199 packageversion::sourcePackageSpecification ()
201 return data
->sourcePackageSpecification ();
205 packageversion::setSourcePackageSpecification (PackageSpecification
const &spec
)
207 data
->setSourcePackageSpecification(spec
);
210 vector
<vector
<PackageSpecification
*> *> *
211 packageversion::depends()
213 return &data
->depends
;
216 vector
<vector
<PackageSpecification
*> *> *
217 packageversion::predepends()
219 return &data
->predepends
;
222 vector
<vector
<PackageSpecification
*> *> *
223 packageversion::recommends()
225 return &data
->recommends
;
228 vector
<vector
<PackageSpecification
*> *> *
229 packageversion::suggests()
231 return &data
->suggests
;
234 vector
<vector
<PackageSpecification
*> *> *
235 packageversion::replaces()
237 return &data
->replaces
;
240 vector
<vector
<PackageSpecification
*> *> *
241 packageversion::conflicts()
243 return &data
->conflicts
;
246 vector
<vector
<PackageSpecification
*> *> *
247 packageversion::provides()
249 return &data
->provides
;
252 vector
<vector
<PackageSpecification
*> *> *
253 packageversion::binaries()
255 return &data
->binaries
;
259 packageversion::picked () const
265 packageversion::pick (bool aBool
)
267 data
->picked
= aBool
;
271 packageversion::changeRequested () const
273 return data
->changeRequested ();
277 packageversion::uninstall ()
283 packageversion::source ()
285 if (!data
->sources
.size())
286 data
->sources
.push_back (packagesource());
287 return &data
->sources
[0];
290 vector
<packagesource
> *
291 packageversion::sources ()
293 return &data
->sources
;
297 packageversion::accessible() const
299 return data
->accessible();
303 checkForInstalled (PackageSpecification
*spec
)
306 packagemeta
*required
= db
.findBinary (*spec
);
309 if (spec
->satisfies (required
->installed
)
310 && required
->desired
== required
->installed
)
311 /* done, found a satisfactory installed version that will remain
318 checkForUpgradeable (PackageSpecification
*spec
)
321 packagemeta
*required
= db
.findBinary (*spec
);
322 if (!required
|| !required
->installed
)
324 for (set
<packageversion
>::iterator i
= required
->versions
.begin();
325 i
!= required
->versions
.end(); ++i
)
326 if (spec
->satisfies (*i
))
332 checkForSatisfiable (PackageSpecification
*spec
)
335 packagemeta
*required
= db
.findBinary (*spec
);
338 for (set
<packageversion
>::iterator i
= required
->versions
.begin();
339 i
!= required
->versions
.end(); ++i
)
340 if (spec
->satisfies (*i
))
346 processOneDependency(trusts deftrust
, size_t depth
, PackageSpecification
*spec
)
348 /* TODO: add this to a set of packages to be offered to meet the
349 requirement. For now, simply set the install to the first
350 satisfactory version. The user can step through the list if
353 packagemeta
*required
= db
.findBinary (*spec
);
354 set
<packageversion
>::iterator v
;
355 for (v
= required
->versions
.begin();
356 v
!= required
->versions
.end() && !spec
->satisfies (*v
); ++v
);
357 if (v
!= required
->versions
.end())
359 /* preserve source */
360 bool sourceticked
= required
->desired
.sourcePackage().picked();
361 /* install this version */
362 required
->desired
= *v
;
363 required
->desired
.pick (required
->installed
!= required
->desired
);
364 required
->desired
.sourcePackage().pick (sourceticked
);
365 /* does this requirement have requirements? */
366 return required
->set_requirements (deftrust
, depth
+ 1);
373 packageversion::set_requirements (trusts deftrust
, size_t depth
)
376 vector
<vector
<PackageSpecification
*> *>::iterator dp
= depends ()->begin();
377 /* cheap test for too much recursion */
380 /* walk through each and clause */
381 while (dp
!= depends ()->end())
384 1) is a satisfactory or clause installed?
385 2) is an unsatisfactory version of an or clause which has
386 a satisfactory version available installed?
387 3) is a satisfactory package available?
389 /* check each or clause for an installed match */
390 vector
<PackageSpecification
*>::iterator i
=
391 find_if ((*dp
)->begin(), (*dp
)->end(), checkForInstalled
);
392 if (i
!= (*dp
)->end())
394 /* we found an installed ok package */
395 /* next and clause */
399 /* check each or clause for an upgradeable version */
400 i
= find_if ((*dp
)->begin(), (*dp
)->end(), checkForUpgradeable
);
401 if (i
!= (*dp
)->end())
403 /* we found a package that can be up/downgraded to meet the
404 requirement. (*i is the packagespec that can be satisfied.)
407 changed
+= processOneDependency (deftrust
, depth
, *i
) + 1;
410 /* check each or clause for an installable version */
411 i
= find_if ((*dp
)->begin(), (*dp
)->end(), checkForSatisfiable
);
412 if (i
!= (*dp
)->end())
414 /* we found a package that can be installed to meet the requirement */
416 changed
+= processOneDependency (deftrust
, depth
, *i
) + 1;
424 /* the parent data class */
426 _packageversion::_packageversion ():picked (false), references (0)
430 _packageversion::~_packageversion ()
434 PackageSpecification
&
435 _packageversion::sourcePackageSpecification ()
437 return _sourcePackage
;
441 _packageversion::setSourcePackageSpecification (PackageSpecification
const &spec
)
443 _sourcePackage
= spec
;
447 _packageversion::sourcePackage ()
453 pkg
= db
.findSource (_sourcePackage
);
454 /* no valid source meta available, just return the default
455 (blank) package version
458 return sourceVersion
;
459 set
<packageversion
>::iterator i
=pkg
->versions
.begin();
460 while (i
!= pkg
->versions
.end())
462 packageversion
const & ver
= * i
;
463 if (_sourcePackage
.satisfies (ver
))
468 return sourceVersion
;
472 _packageversion::accessible() const
475 for (vector
<packagesource
>::const_iterator i
= sources
.begin();
476 i
!=sources
.end(); ++i
)
481 if (::source
== IDC_SOURCE_CWD
)
483 unsigned int retrievable
= 0;
484 for (vector
<packagesource
>::const_iterator i
= sources
.begin();
485 i
!=sources
.end(); ++i
)
486 if (i
->sites
.size() || i
->Cached ())
488 return retrievable
== sources
.size();
492 _packageversion::changeRequested ()
494 return (picked
|| sourcePackage().picked());