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"
31 /* a default class to avoid special casing empty packageversions */
33 /* TODO place into the class header */
34 class _defaultversion
: public _packageversion
39 // never try to free me!
42 String
const Name(){return String();}
43 String
const Vendor_version() {return String();}
44 String
const Package_version() {return String();}
45 String
const Canonical_version() {return String();}
46 void setCanonicalVersion (String
const &) {}
47 package_status_t
Status (){return package_notinstalled
;}
48 package_type_t
Type () {return package_binary
;}
49 String
const getfirstfile () {return String();}
50 String
const getnextfile () {return String();}
51 String
const SDesc () {return String();}
52 void set_sdesc (String
const &) {}
53 String
const LDesc () {return String();}
54 void set_ldesc (String
const &) {}
57 static _defaultversion defaultversion
;
59 /* the wrapper class */
60 packageversion::packageversion() : data (&defaultversion
)
65 /* Create from an actual package */
66 packageversion::packageversion (_packageversion
*pkg
)
71 data
= &defaultversion
;
75 packageversion::packageversion (packageversion
const &existing
) :
81 packageversion::~packageversion()
83 if (--data
->references
== 0)
88 packageversion::operator= (packageversion
const &rhs
)
90 ++rhs
.data
->references
;
91 if (--data
->references
== 0)
98 packageversion::operator ! () const
100 return !data
->Name().size();
103 packageversion::operator bool () const
105 return data
->Name().size();
109 packageversion::operator == (packageversion
const &rhs
) const
111 if (this == &rhs
|| data
== rhs
.data
)
114 return data
->Name () == rhs
.data
->Name() && data
->Canonical_version () == rhs
.data
->Canonical_version();
118 packageversion::operator != (packageversion
const &rhs
) const
120 return ! (*this == rhs
);
124 packageversion::operator < (packageversion
const &rhs
) const
126 int t
= data
->Name ().casecompare (rhs
.data
->Name());
131 else if (data
->Canonical_version().casecompare (rhs
.data
->Canonical_version()) < 0)
137 packageversion::Name () const
139 return data
->Name ();
143 packageversion::Canonical_version() const
145 return data
->Canonical_version();
149 packageversion::setCanonicalVersion (String
const &ver
)
151 data
->setCanonicalVersion (ver
);
155 packageversion::getfirstfile ()
157 return data
->getfirstfile ();
161 packageversion::getnextfile ()
163 return data
->getnextfile ();
167 packageversion::SDesc () const
169 return data
->SDesc ();
173 packageversion::set_sdesc (String
const &sdesc
)
175 data
->set_sdesc (sdesc
);
179 packageversion::LDesc () const
181 return data
->LDesc ();
185 packageversion::set_ldesc (String
const &ldesc
)
187 data
->set_ldesc (ldesc
);
191 packageversion::sourcePackage()
193 return data
->sourcePackage();
196 PackageSpecification
&
197 packageversion::sourcePackageSpecification ()
199 return data
->sourcePackageSpecification ();
203 packageversion::setSourcePackageSpecification (PackageSpecification
const &spec
)
205 data
->setSourcePackageSpecification(spec
);
208 vector
<vector
<PackageSpecification
*> *> *
209 packageversion::depends()
211 return &data
->depends
;
214 vector
<vector
<PackageSpecification
*> *> *
215 packageversion::predepends()
217 return &data
->predepends
;
220 vector
<vector
<PackageSpecification
*> *> *
221 packageversion::recommends()
223 return &data
->recommends
;
226 vector
<vector
<PackageSpecification
*> *> *
227 packageversion::suggests()
229 return &data
->suggests
;
232 vector
<vector
<PackageSpecification
*> *> *
233 packageversion::replaces()
235 return &data
->replaces
;
238 vector
<vector
<PackageSpecification
*> *> *
239 packageversion::conflicts()
241 return &data
->conflicts
;
244 vector
<vector
<PackageSpecification
*> *> *
245 packageversion::provides()
247 return &data
->provides
;
250 vector
<vector
<PackageSpecification
*> *> *
251 packageversion::binaries()
253 return &data
->binaries
;
257 packageversion::picked () const
263 packageversion::pick (bool aBool
)
265 data
->picked
= aBool
;
269 packageversion::changeRequested () const
271 return data
->changeRequested ();
275 packageversion::uninstall ()
281 packageversion::source ()
283 if (!data
->sources
.size())
284 data
->sources
.push_back (packagesource());
285 return &data
->sources
[0];
289 packageversion::accessible() const
291 return data
->accessible();
295 checkForInstalled (PackageSpecification
*spec
)
298 packagemeta
*required
= db
.findBinary (*spec
);
301 if (spec
->satisfies (required
->installed
)
302 && required
->desired
== required
->installed
)
303 /* done, found a satisfactory installed version that will remain
310 checkForUpgradeable (PackageSpecification
*spec
)
313 packagemeta
*required
= db
.findBinary (*spec
);
314 if (!required
|| !required
->installed
)
316 for (set
<packageversion
>::iterator i
= required
->versions
.begin();
317 i
!= required
->versions
.end(); ++i
)
318 if (spec
->satisfies (*i
))
324 checkForSatisfiable (PackageSpecification
*spec
)
327 packagemeta
*required
= db
.findBinary (*spec
);
330 for (set
<packageversion
>::iterator i
= required
->versions
.begin();
331 i
!= required
->versions
.end(); ++i
)
332 if (spec
->satisfies (*i
))
338 processOneDependency(trusts deftrust
, size_t depth
, PackageSpecification
*spec
)
340 /* TODO: add this to a set of packages to be offered to meet the
341 requirement. For now, simply set the install to the first
342 satisfactory version. The user can step through the list if
345 packagemeta
*required
= db
.findBinary (*spec
);
346 set
<packageversion
>::iterator v
;
347 for (v
= required
->versions
.begin();
348 v
!= required
->versions
.end() && !spec
->satisfies (*v
); ++v
);
349 if (v
!= required
->versions
.end())
351 /* preserve source */
352 bool sourceticked
= required
->desired
.sourcePackage().picked();
353 /* install this version */
354 required
->desired
= *v
;
355 required
->desired
.pick (required
->installed
!= required
->desired
);
356 required
->desired
.sourcePackage().pick (sourceticked
);
357 /* does this requirement have requirements? */
358 return required
->set_requirements (deftrust
, depth
+ 1);
365 packageversion::set_requirements (trusts deftrust
= TRUST_CURR
, size_t depth
= 0)
368 vector
<vector
<PackageSpecification
*> *>::iterator dp
= depends ()->begin();
369 /* cheap test for too much recursion */
372 /* walk through each and clause */
373 while (dp
!= depends ()->end())
376 1) is a satisfactory or clause installed?
377 2) is an unsatisfactory version of an or clause which has
378 a satisfactory version available installed?
379 3) is a satisfactory package available?
381 /* check each or clause for an installed match */
382 vector
<PackageSpecification
*>::iterator i
=
383 find_if ((*dp
)->begin(), (*dp
)->end(), checkForInstalled
);
384 if (i
!= (*dp
)->end())
386 /* we found an installed ok package */
387 /* next and clause */
391 /* check each or clause for an upgradeable version */
392 i
= find_if ((*dp
)->begin(), (*dp
)->end(), checkForUpgradeable
);
393 if (i
!= (*dp
)->end())
395 /* we found a package that can be up/downgraded to meet the
396 requirement. (*i is the packagespec that can be satisfied.)
399 changed
+= processOneDependency (deftrust
, depth
, *i
) + 1;
402 /* check each or clause for an installable version */
403 i
= find_if ((*dp
)->begin(), (*dp
)->end(), checkForSatisfiable
);
404 if (i
!= (*dp
)->end())
406 /* we found a package that can be installed to meet the requirement */
408 changed
+= processOneDependency (deftrust
, depth
, *i
) + 1;
416 /* the parent data class */
418 _packageversion::_packageversion ():picked (false), references (0)
422 _packageversion::~_packageversion ()
426 PackageSpecification
&
427 _packageversion::sourcePackageSpecification ()
429 return _sourcePackage
;
433 _packageversion::setSourcePackageSpecification (PackageSpecification
const &spec
)
435 _sourcePackage
= spec
;
439 _packageversion::sourcePackage ()
445 pkg
= db
.findSource (_sourcePackage
);
446 /* no valid source meta available, just return the default
447 (blank) package version
450 return sourceVersion
;
451 set
<packageversion
>::iterator i
=pkg
->versions
.begin();
452 while (i
!= pkg
->versions
.end())
454 packageversion
const & ver
= * i
;
455 if (_sourcePackage
.satisfies (ver
))
460 return sourceVersion
;
464 _packageversion::accessible() const
467 for (vector
<packagesource
>::const_iterator i
= sources
.begin();
468 i
!=sources
.end(); ++i
)
473 if (::source
== IDC_SOURCE_CWD
)
475 unsigned int retrievable
= 0;
476 for (vector
<packagesource
>::const_iterator i
= sources
.begin();
477 i
!=sources
.end(); ++i
)
478 if (i
->sites
.size() || i
->Cached ())
480 return retrievable
== sources
.size();
484 _packageversion::changeRequested ()
486 return (picked
|| sourcePackage().picked());