]> cygwin.com Git - cygwin-apps/setup.git/blame - package_version.cc
2002-11-25 Robert Collins <rbtcollins@hotmail.com>
[cygwin-apps/setup.git] / package_version.cc
CommitLineData
7939f6d1
RC
1/*
2 * Copyright (c) 2001, Robert Collins.
3 *
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.
8 *
9 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
11 *
12 * Written by Robert Collins <rbtcollins@hotmail.com>
13 *
14 */
15
16/* this is the parent class for all package operations.
17 */
18
19#if 0
20static const char *cvsid =
21 "\n%%% $Id$\n";
22#endif
bb849dbd
RC
23
24#include "package_version.h"
3c196821
RC
25#include "package_db.h"
26#include "package_meta.h"
27#include "state.h"
28#include "resource.h"
4f591f9d 29#include <algorithm>
3c196821 30
666bf37d
RC
31using namespace std;
32
3c196821
RC
33/* a default class to avoid special casing empty packageversions */
34
35/* TODO place into the class header */
36class _defaultversion : public _packageversion
bb849dbd 37{
3c196821
RC
38public:
39 _defaultversion()
40 {
41 // never try to free me!
42 ++references;
43 }
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 &) {}
57 void uninstall (){}
bb849dbd 58};
3c196821
RC
59static _defaultversion defaultversion;
60
61/* the wrapper class */
62packageversion::packageversion() : data (&defaultversion)
63{
64 ++data->references;
65}
66
67/* Create from an actual package */
68packageversion::packageversion (_packageversion *pkg)
69{
70 if (pkg)
71 data = pkg;
72 else
73 data = &defaultversion;
74 ++data->references;
75}
76
77packageversion::packageversion (packageversion const &existing) :
78data(existing.data)
79{
80 ++data->references;
81}
82
83packageversion::~packageversion()
84{
85 if (--data->references == 0)
86 delete data;
87}
88
89packageversion &
90packageversion::operator= (packageversion const &rhs)
91{
92 ++rhs.data->references;
93 if (--data->references == 0)
94 delete data;
95 data = rhs.data;
96 return *this;
97}
98
99bool
100packageversion::operator ! () const
101{
102 return !data->Name().size();
103}
104
105packageversion::operator bool () const
106{
107 return data->Name().size();
108}
109
110bool
111packageversion::operator == (packageversion const &rhs) const
112{
113 if (this == &rhs || data == rhs.data)
114 return true;
115 else
116 return data->Name () == rhs.data->Name() && data->Canonical_version () == rhs.data->Canonical_version();
117}
118
119bool
120packageversion::operator != (packageversion const &rhs) const
121{
122 return ! (*this == rhs);
123}
124
125bool
126packageversion::operator < (packageversion const &rhs) const
127{
128 int t = data->Name ().casecompare (rhs.data->Name());
129 if (t < 0)
130 return true;
131 else if (t > 0)
132 return false;
133 else if (data->Canonical_version().casecompare (rhs.data->Canonical_version()) < 0)
134 return true;
135 return false;
136}
137
138String const
139packageversion::Name () const
140{
141 return data->Name ();
142}
143
144String const
145packageversion::Canonical_version() const
146{
147 return data->Canonical_version();
148}
149
150void
151packageversion::setCanonicalVersion (String const &ver)
152{
153 data->setCanonicalVersion (ver);
154}
155
156String const
157packageversion::getfirstfile ()
158{
159 return data->getfirstfile ();
160}
161
162String const
163packageversion::getnextfile ()
164{
165 return data->getnextfile ();
166}
167
168String const
169packageversion::SDesc () const
170{
171 return data->SDesc ();
172}
173
174void
175packageversion::set_sdesc (String const &sdesc)
176{
177 data->set_sdesc (sdesc);
178}
179
180String const
181packageversion::LDesc () const
182{
183 return data->LDesc ();
184}
185
186void
187packageversion::set_ldesc (String const &ldesc)
188{
189 data->set_ldesc (ldesc);
190}
191
192packageversion
193packageversion::sourcePackage()
194{
195 return data->sourcePackage();
196}
aa1e3b4d
RC
197
198PackageSpecification &
3c196821
RC
199packageversion::sourcePackageSpecification ()
200{
201 return data->sourcePackageSpecification ();
202}
203
204void
205packageversion::setSourcePackageSpecification (PackageSpecification const &spec)
206{
207 data->setSourcePackageSpecification(spec);
208}
209
210vector <vector <PackageSpecification *> *> *
211packageversion::depends()
212{
213 return &data->depends;
214}
215
216vector <vector <PackageSpecification *> *> *
217packageversion::predepends()
218{
219 return &data->predepends;
220}
221
222vector <vector <PackageSpecification *> *> *
223packageversion::recommends()
224{
225 return &data->recommends;
226}
227
228vector <vector <PackageSpecification *> *> *
229packageversion::suggests()
230{
231 return &data->suggests;
232}
233
234vector <vector <PackageSpecification *> *> *
235packageversion::replaces()
236{
237 return &data->replaces;
238}
239
240vector <vector <PackageSpecification *> *> *
241packageversion::conflicts()
242{
243 return &data->conflicts;
244}
245
246vector <vector <PackageSpecification *> *> *
247packageversion::provides()
248{
249 return &data->provides;
250}
251
b1ff53ed
RC
252vector <vector <PackageSpecification *> *> *
253packageversion::binaries()
254{
255 return &data->binaries;
256}
3c196821
RC
257
258bool
259packageversion::picked () const
260{
261 return data->picked;
262}
263
264void
265packageversion::pick (bool aBool)
266{
267 data->picked = aBool;
268}
269
270bool
271packageversion::changeRequested () const
272{
273 return data->changeRequested ();
274}
275
276void
277packageversion::uninstall ()
278{
279 data->uninstall ();
280}
281
282packagesource *
283packageversion::source ()
284{
e5662e0a
RC
285 if (!data->sources.size())
286 data->sources.push_back (packagesource());
287 return &data->sources[0];
3c196821
RC
288}
289
ec13f13c
RC
290vector<packagesource> *
291packageversion::sources ()
292{
293 return &data->sources;
294}
295
3c196821
RC
296bool
297packageversion::accessible() const
298{
299 return data->accessible();
300}
301
4f591f9d
RC
302static bool
303checkForInstalled (PackageSpecification *spec)
304{
305 packagedb db;
306 packagemeta *required = db.findBinary (*spec);
307 if (!required)
308 return false;
309 if (spec->satisfies (required->installed)
310 && required->desired == required->installed )
311 /* done, found a satisfactory installed version that will remain
312 installed */
313 return true;
314 return false;
315}
316
317static bool
318checkForUpgradeable (PackageSpecification *spec)
319{
320 packagedb db;
321 packagemeta *required = db.findBinary (*spec);
322 if (!required || !required->installed)
323 return false;
324 for (set <packageversion>::iterator i = required->versions.begin();
325 i != required->versions.end(); ++i)
326 if (spec->satisfies (*i))
327 return true;
328 return false;
329}
330
331static bool
332checkForSatisfiable (PackageSpecification *spec)
333{
334 packagedb db;
335 packagemeta *required = db.findBinary (*spec);
336 if (!required)
337 return false;
338 for (set <packageversion>::iterator i = required->versions.begin();
339 i != required->versions.end(); ++i)
340 if (spec->satisfies (*i))
341 return true;
342 return false;
343}
344
05c5b8a6
RC
345/* Convenience class for now */
346class DependencyProcessor {
347public:
348 DependencyProcessor (trusts const &aTrust, int aDepth=0) : deftrust (aTrust), depth (aDepth) {}
349 trusts const deftrust;
350 size_t depth;
351};
352
353static int
354select (DependencyProcessor &processor, packagemeta *required, packageversion const &aVersion)
355{
356 /* preserve source */
357 bool sourceticked = required->desired.sourcePackage().picked();
358 /* install this version */
359 required->desired = aVersion;
360 required->desired.pick (required->installed != required->desired);
361 required->desired.sourcePackage().pick (sourceticked);
362 /* does this requirement have requirements? */
363 return required->set_requirements (processor.deftrust, processor.depth + 1);
364}
365
4f591f9d
RC
366static int
367processOneDependency(trusts deftrust, size_t depth, PackageSpecification *spec)
368{
369 /* TODO: add this to a set of packages to be offered to meet the
370 requirement. For now, simply set the install to the first
371 satisfactory version. The user can step through the list if
372 desired */
373 packagedb db;
374 packagemeta *required = db.findBinary (*spec);
05c5b8a6
RC
375 DependencyProcessor processor (deftrust, depth);
376
377 packageversion trusted = required->trustp(deftrust);
378 if (spec->satisfies (trusted))
379 select (processor,required,trusted);
380
4f591f9d
RC
381 set <packageversion>::iterator v;
382 for (v = required->versions.begin();
383 v != required->versions.end() && !spec->satisfies (*v); ++v);
05c5b8a6
RC
384
385 if (v == required->versions.end())
386 /* assert ?! */
387 return 0;
388
389 return select (processor, required, *v);
4f591f9d
RC
390}
391
392int
666bf37d 393packageversion::set_requirements (trusts deftrust, size_t depth)
4f591f9d
RC
394{
395 int changed = 0;
396 vector <vector <PackageSpecification *> *>::iterator dp = depends ()->begin();
397 /* cheap test for too much recursion */
398 if (depth > 5)
399 return changed;
400 /* walk through each and clause */
401 while (dp != depends ()->end())
402 {
403 /* three step:
404 1) is a satisfactory or clause installed?
405 2) is an unsatisfactory version of an or clause which has
406 a satisfactory version available installed?
407 3) is a satisfactory package available?
408 */
409 /* check each or clause for an installed match */
410 vector <PackageSpecification *>::iterator i =
411 find_if ((*dp)->begin(), (*dp)->end(), checkForInstalled);
412 if (i != (*dp)->end())
413 {
414 /* we found an installed ok package */
415 /* next and clause */
416 ++dp;
417 continue;
418 }
419 /* check each or clause for an upgradeable version */
420 i = find_if ((*dp)->begin(), (*dp)->end(), checkForUpgradeable);
421 if (i != (*dp)->end())
422 {
423 /* we found a package that can be up/downgraded to meet the
424 requirement. (*i is the packagespec that can be satisfied.)
425 */
426 ++dp;
427 changed += processOneDependency (deftrust, depth, *i) + 1;
428 continue;
429 }
430 /* check each or clause for an installable version */
431 i = find_if ((*dp)->begin(), (*dp)->end(), checkForSatisfiable);
432 if (i != (*dp)->end())
433 {
434 /* we found a package that can be installed to meet the requirement */
435 ++dp;
436 changed += processOneDependency (deftrust, depth, *i) + 1;
437 continue;
438 }
439 ++dp;
440 }
441 return changed;
442}
443
3c196821
RC
444/* the parent data class */
445
446_packageversion::_packageversion ():picked (false), references (0)
447{
448}
449
450_packageversion::~_packageversion ()
451{
452}
453
454PackageSpecification &
455_packageversion::sourcePackageSpecification ()
aa1e3b4d
RC
456{
457 return _sourcePackage;
458}
459
460void
3c196821 461_packageversion::setSourcePackageSpecification (PackageSpecification const &spec)
aa1e3b4d
RC
462{
463 _sourcePackage = spec;
464}
3c196821
RC
465
466packageversion
467_packageversion::sourcePackage ()
468{
469 if (!sourceVersion)
470 {
471 packagedb db;
472 packagemeta * pkg;
473 pkg = db.findSource (_sourcePackage);
474 /* no valid source meta available, just return the default
475 (blank) package version
476 */
477 if (!pkg)
478 return sourceVersion;
479 set<packageversion>::iterator i=pkg->versions.begin();
480 while (i != pkg->versions.end())
481 {
482 packageversion const & ver = * i;
483 if (_sourcePackage.satisfies (ver))
484 sourceVersion = ver;
485 ++i;
486 }
487 }
488 return sourceVersion;
489}
490
491bool
492_packageversion::accessible() const
493{
e5662e0a
RC
494 bool cached = true;
495 for (vector<packagesource>::const_iterator i = sources.begin();
496 i!=sources.end(); ++i)
497 if (!i->Cached ())
498 cached = false;
499 if (cached)
500 return true;
501 if (::source == IDC_SOURCE_CWD)
502 return false;
503 unsigned int retrievable = 0;
504 for (vector<packagesource>::const_iterator i = sources.begin();
505 i!=sources.end(); ++i)
506 if (i->sites.size() || i->Cached ())
507 retrievable += 1;
508 return retrievable == sources.size();
3c196821
RC
509}
510
511bool
512_packageversion::changeRequested ()
513{
514 return (picked || sourcePackage().picked());
515}
This page took 0.078155 seconds and 5 git commands to generate.