]> cygwin.com Git - cygwin-apps/setup.git/blame - package_version.cc
2002-07-15 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
RC
30
31/* a default class to avoid special casing empty packageversions */
32
33/* TODO place into the class header */
34class _defaultversion : public _packageversion
bb849dbd 35{
3c196821
RC
36public:
37 _defaultversion()
38 {
39 // never try to free me!
40 ++references;
41 }
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 &) {}
55 void uninstall (){}
bb849dbd 56};
3c196821
RC
57static _defaultversion defaultversion;
58
59/* the wrapper class */
60packageversion::packageversion() : data (&defaultversion)
61{
62 ++data->references;
63}
64
65/* Create from an actual package */
66packageversion::packageversion (_packageversion *pkg)
67{
68 if (pkg)
69 data = pkg;
70 else
71 data = &defaultversion;
72 ++data->references;
73}
74
75packageversion::packageversion (packageversion const &existing) :
76data(existing.data)
77{
78 ++data->references;
79}
80
81packageversion::~packageversion()
82{
83 if (--data->references == 0)
84 delete data;
85}
86
87packageversion &
88packageversion::operator= (packageversion const &rhs)
89{
90 ++rhs.data->references;
91 if (--data->references == 0)
92 delete data;
93 data = rhs.data;
94 return *this;
95}
96
97bool
98packageversion::operator ! () const
99{
100 return !data->Name().size();
101}
102
103packageversion::operator bool () const
104{
105 return data->Name().size();
106}
107
108bool
109packageversion::operator == (packageversion const &rhs) const
110{
111 if (this == &rhs || data == rhs.data)
112 return true;
113 else
114 return data->Name () == rhs.data->Name() && data->Canonical_version () == rhs.data->Canonical_version();
115}
116
117bool
118packageversion::operator != (packageversion const &rhs) const
119{
120 return ! (*this == rhs);
121}
122
123bool
124packageversion::operator < (packageversion const &rhs) const
125{
126 int t = data->Name ().casecompare (rhs.data->Name());
127 if (t < 0)
128 return true;
129 else if (t > 0)
130 return false;
131 else if (data->Canonical_version().casecompare (rhs.data->Canonical_version()) < 0)
132 return true;
133 return false;
134}
135
136String const
137packageversion::Name () const
138{
139 return data->Name ();
140}
141
142String const
143packageversion::Canonical_version() const
144{
145 return data->Canonical_version();
146}
147
148void
149packageversion::setCanonicalVersion (String const &ver)
150{
151 data->setCanonicalVersion (ver);
152}
153
154String const
155packageversion::getfirstfile ()
156{
157 return data->getfirstfile ();
158}
159
160String const
161packageversion::getnextfile ()
162{
163 return data->getnextfile ();
164}
165
166String const
167packageversion::SDesc () const
168{
169 return data->SDesc ();
170}
171
172void
173packageversion::set_sdesc (String const &sdesc)
174{
175 data->set_sdesc (sdesc);
176}
177
178String const
179packageversion::LDesc () const
180{
181 return data->LDesc ();
182}
183
184void
185packageversion::set_ldesc (String const &ldesc)
186{
187 data->set_ldesc (ldesc);
188}
189
190packageversion
191packageversion::sourcePackage()
192{
193 return data->sourcePackage();
194}
aa1e3b4d
RC
195
196PackageSpecification &
3c196821
RC
197packageversion::sourcePackageSpecification ()
198{
199 return data->sourcePackageSpecification ();
200}
201
202void
203packageversion::setSourcePackageSpecification (PackageSpecification const &spec)
204{
205 data->setSourcePackageSpecification(spec);
206}
207
208vector <vector <PackageSpecification *> *> *
209packageversion::depends()
210{
211 return &data->depends;
212}
213
214vector <vector <PackageSpecification *> *> *
215packageversion::predepends()
216{
217 return &data->predepends;
218}
219
220vector <vector <PackageSpecification *> *> *
221packageversion::recommends()
222{
223 return &data->recommends;
224}
225
226vector <vector <PackageSpecification *> *> *
227packageversion::suggests()
228{
229 return &data->suggests;
230}
231
232vector <vector <PackageSpecification *> *> *
233packageversion::replaces()
234{
235 return &data->replaces;
236}
237
238vector <vector <PackageSpecification *> *> *
239packageversion::conflicts()
240{
241 return &data->conflicts;
242}
243
244vector <vector <PackageSpecification *> *> *
245packageversion::provides()
246{
247 return &data->provides;
248}
249
b1ff53ed
RC
250vector <vector <PackageSpecification *> *> *
251packageversion::binaries()
252{
253 return &data->binaries;
254}
3c196821
RC
255
256bool
257packageversion::picked () const
258{
259 return data->picked;
260}
261
262void
263packageversion::pick (bool aBool)
264{
265 data->picked = aBool;
266}
267
268bool
269packageversion::changeRequested () const
270{
271 return data->changeRequested ();
272}
273
274void
275packageversion::uninstall ()
276{
277 data->uninstall ();
278}
279
280packagesource *
281packageversion::source ()
282{
e5662e0a
RC
283 if (!data->sources.size())
284 data->sources.push_back (packagesource());
285 return &data->sources[0];
3c196821
RC
286}
287
ec13f13c
RC
288vector<packagesource> *
289packageversion::sources ()
290{
291 return &data->sources;
292}
293
3c196821
RC
294bool
295packageversion::accessible() const
296{
297 return data->accessible();
298}
299
4f591f9d
RC
300static bool
301checkForInstalled (PackageSpecification *spec)
302{
303 packagedb db;
304 packagemeta *required = db.findBinary (*spec);
305 if (!required)
306 return false;
307 if (spec->satisfies (required->installed)
308 && required->desired == required->installed )
309 /* done, found a satisfactory installed version that will remain
310 installed */
311 return true;
312 return false;
313}
314
315static bool
316checkForUpgradeable (PackageSpecification *spec)
317{
318 packagedb db;
319 packagemeta *required = db.findBinary (*spec);
320 if (!required || !required->installed)
321 return false;
322 for (set <packageversion>::iterator i = required->versions.begin();
323 i != required->versions.end(); ++i)
324 if (spec->satisfies (*i))
325 return true;
326 return false;
327}
328
329static bool
330checkForSatisfiable (PackageSpecification *spec)
331{
332 packagedb db;
333 packagemeta *required = db.findBinary (*spec);
334 if (!required)
335 return false;
336 for (set <packageversion>::iterator i = required->versions.begin();
337 i != required->versions.end(); ++i)
338 if (spec->satisfies (*i))
339 return true;
340 return false;
341}
342
343static int
344processOneDependency(trusts deftrust, size_t depth, PackageSpecification *spec)
345{
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
349 desired */
350 packagedb db;
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())
356 {
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);
365 }
366 /* else assert !! */
367 return 0;
368}
369
370int
371packageversion::set_requirements (trusts deftrust = TRUST_CURR, size_t depth = 0)
372{
373 int changed = 0;
374 vector <vector <PackageSpecification *> *>::iterator dp = depends ()->begin();
375 /* cheap test for too much recursion */
376 if (depth > 5)
377 return changed;
378 /* walk through each and clause */
379 while (dp != depends ()->end())
380 {
381 /* three step:
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?
386 */
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())
391 {
392 /* we found an installed ok package */
393 /* next and clause */
394 ++dp;
395 continue;
396 }
397 /* check each or clause for an upgradeable version */
398 i = find_if ((*dp)->begin(), (*dp)->end(), checkForUpgradeable);
399 if (i != (*dp)->end())
400 {
401 /* we found a package that can be up/downgraded to meet the
402 requirement. (*i is the packagespec that can be satisfied.)
403 */
404 ++dp;
405 changed += processOneDependency (deftrust, depth, *i) + 1;
406 continue;
407 }
408 /* check each or clause for an installable version */
409 i = find_if ((*dp)->begin(), (*dp)->end(), checkForSatisfiable);
410 if (i != (*dp)->end())
411 {
412 /* we found a package that can be installed to meet the requirement */
413 ++dp;
414 changed += processOneDependency (deftrust, depth, *i) + 1;
415 continue;
416 }
417 ++dp;
418 }
419 return changed;
420}
421
3c196821
RC
422/* the parent data class */
423
424_packageversion::_packageversion ():picked (false), references (0)
425{
426}
427
428_packageversion::~_packageversion ()
429{
430}
431
432PackageSpecification &
433_packageversion::sourcePackageSpecification ()
aa1e3b4d
RC
434{
435 return _sourcePackage;
436}
437
438void
3c196821 439_packageversion::setSourcePackageSpecification (PackageSpecification const &spec)
aa1e3b4d
RC
440{
441 _sourcePackage = spec;
442}
3c196821
RC
443
444packageversion
445_packageversion::sourcePackage ()
446{
447 if (!sourceVersion)
448 {
449 packagedb db;
450 packagemeta * pkg;
451 pkg = db.findSource (_sourcePackage);
452 /* no valid source meta available, just return the default
453 (blank) package version
454 */
455 if (!pkg)
456 return sourceVersion;
457 set<packageversion>::iterator i=pkg->versions.begin();
458 while (i != pkg->versions.end())
459 {
460 packageversion const & ver = * i;
461 if (_sourcePackage.satisfies (ver))
462 sourceVersion = ver;
463 ++i;
464 }
465 }
466 return sourceVersion;
467}
468
469bool
470_packageversion::accessible() const
471{
e5662e0a
RC
472 bool cached = true;
473 for (vector<packagesource>::const_iterator i = sources.begin();
474 i!=sources.end(); ++i)
475 if (!i->Cached ())
476 cached = false;
477 if (cached)
478 return true;
479 if (::source == IDC_SOURCE_CWD)
480 return false;
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 ())
485 retrievable += 1;
486 return retrievable == sources.size();
3c196821
RC
487}
488
489bool
490_packageversion::changeRequested ()
491{
492 return (picked || sourcePackage().picked());
493}
This page took 0.072736 seconds and 5 git commands to generate.