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];
288 vector
<packagesource
> *
289 packageversion::sources ()
291 return &data
->sources
;
295 packageversion::accessible() const
297 return data
->accessible();
301 checkForInstalled (PackageSpecification
*spec
)
304 packagemeta
*required
= db
.findBinary (*spec
);
307 if (spec
->satisfies (required
->installed
)
308 && required
->desired
== required
->installed
)
309 /* done, found a satisfactory installed version that will remain
316 checkForUpgradeable (PackageSpecification
*spec
)
319 packagemeta
*required
= db
.findBinary (*spec
);
320 if (!required
|| !required
->installed
)
322 for (set
<packageversion
>::iterator i
= required
->versions
.begin();
323 i
!= required
->versions
.end(); ++i
)
324 if (spec
->satisfies (*i
))
330 checkForSatisfiable (PackageSpecification
*spec
)
333 packagemeta
*required
= db
.findBinary (*spec
);
336 for (set
<packageversion
>::iterator i
= required
->versions
.begin();
337 i
!= required
->versions
.end(); ++i
)
338 if (spec
->satisfies (*i
))
344 processOneDependency(trusts deftrust
, size_t depth
, PackageSpecification
*spec
)
346 /* TODO: add this to a set of packages to be offered to meet the
347 requirement. For now, simply set the install to the first
348 satisfactory version. The user can step through the list if
351 packagemeta
*required
= db
.findBinary (*spec
);
352 set
<packageversion
>::iterator v
;
353 for (v
= required
->versions
.begin();
354 v
!= required
->versions
.end() && !spec
->satisfies (*v
); ++v
);
355 if (v
!= required
->versions
.end())
357 /* preserve source */
358 bool sourceticked
= required
->desired
.sourcePackage().picked();
359 /* install this version */
360 required
->desired
= *v
;
361 required
->desired
.pick (required
->installed
!= required
->desired
);
362 required
->desired
.sourcePackage().pick (sourceticked
);
363 /* does this requirement have requirements? */
364 return required
->set_requirements (deftrust
, depth
+ 1);
371 packageversion::set_requirements (trusts deftrust
= TRUST_CURR
, size_t depth
= 0)
374 vector
<vector
<PackageSpecification
*> *>::iterator dp
= depends ()->begin();
375 /* cheap test for too much recursion */
378 /* walk through each and clause */
379 while (dp
!= depends ()->end())
382 1) is a satisfactory or clause installed?
383 2) is an unsatisfactory version of an or clause which has
384 a satisfactory version available installed?
385 3) is a satisfactory package available?
387 /* check each or clause for an installed match */
388 vector
<PackageSpecification
*>::iterator i
=
389 find_if ((*dp
)->begin(), (*dp
)->end(), checkForInstalled
);
390 if (i
!= (*dp
)->end())
392 /* we found an installed ok package */
393 /* next and clause */
397 /* check each or clause for an upgradeable version */
398 i
= find_if ((*dp
)->begin(), (*dp
)->end(), checkForUpgradeable
);
399 if (i
!= (*dp
)->end())
401 /* we found a package that can be up/downgraded to meet the
402 requirement. (*i is the packagespec that can be satisfied.)
405 changed
+= processOneDependency (deftrust
, depth
, *i
) + 1;
408 /* check each or clause for an installable version */
409 i
= find_if ((*dp
)->begin(), (*dp
)->end(), checkForSatisfiable
);
410 if (i
!= (*dp
)->end())
412 /* we found a package that can be installed to meet the requirement */
414 changed
+= processOneDependency (deftrust
, depth
, *i
) + 1;
422 /* the parent data class */
424 _packageversion::_packageversion ():picked (false), references (0)
428 _packageversion::~_packageversion ()
432 PackageSpecification
&
433 _packageversion::sourcePackageSpecification ()
435 return _sourcePackage
;
439 _packageversion::setSourcePackageSpecification (PackageSpecification
const &spec
)
441 _sourcePackage
= spec
;
445 _packageversion::sourcePackage ()
451 pkg
= db
.findSource (_sourcePackage
);
452 /* no valid source meta available, just return the default
453 (blank) package version
456 return sourceVersion
;
457 set
<packageversion
>::iterator i
=pkg
->versions
.begin();
458 while (i
!= pkg
->versions
.end())
460 packageversion
const & ver
= * i
;
461 if (_sourcePackage
.satisfies (ver
))
466 return sourceVersion
;
470 _packageversion::accessible() const
473 for (vector
<packagesource
>::const_iterator i
= sources
.begin();
474 i
!=sources
.end(); ++i
)
479 if (::source
== IDC_SOURCE_CWD
)
481 unsigned int retrievable
= 0;
482 for (vector
<packagesource
>::const_iterator i
= sources
.begin();
483 i
!=sources
.end(); ++i
)
484 if (i
->sites
.size() || i
->Cached ())
486 return retrievable
== sources
.size();
490 _packageversion::changeRequested ()
492 return (picked
|| sourcePackage().picked());