]>
git.saurik.com Git - apt.git/blob - apt-pkg/cacheset.cc
1 // -*- mode: cpp; mode: fold -*-
3 /* ######################################################################
5 Simple wrapper around a std::set to provide a similar interface to
6 a set of cache structures as to the complete set of all structures
7 in the pkgCache. Currently only Package is supported.
9 ##################################################################### */
11 // Include Files /*{{{*/
14 #include <apt-pkg/aptconfiguration.h>
15 #include <apt-pkg/cachefile.h>
16 #include <apt-pkg/cachefilter.h>
17 #include <apt-pkg/cacheset.h>
18 #include <apt-pkg/error.h>
19 #include <apt-pkg/strutl.h>
20 #include <apt-pkg/versionmatch.h>
21 #include <apt-pkg/pkgrecords.h>
22 #include <apt-pkg/policy.h>
31 // FromTask - Return all packages in the cache from a specific task /*{{{*/
32 PackageSet
PackageSet :: FromTask ( pkgCacheFile
& Cache
, std :: string pattern
, CacheSetHelper
& helper
) {
33 size_t const archfound
= pattern
. find_last_of ( ':' );
34 std :: string arch
= "native" ;
35 if ( archfound
!= std :: string :: npos
) {
36 arch
= pattern
. substr ( archfound
+ 1 );
37 pattern
. erase ( archfound
);
40 if ( pattern
[ pattern
. length () - 1 ] != '^' )
41 return APT :: PackageSet ( TASK
);
42 pattern
. erase ( pattern
. length ()- 1 );
44 if ( unlikely ( Cache
. GetPkgCache () == 0 || Cache
. GetDepCache () == 0 ))
45 return APT :: PackageSet ( TASK
);
47 PackageSet
pkgset ( TASK
);
49 pkgRecords
Recs ( Cache
);
51 // build regexp for the task
54 snprintf ( S
, sizeof ( S
), "^Task:.*[, ] %s ([, ]|$)" , pattern
. c_str ());
55 if ( regcomp (& Pattern
, S
, REG_EXTENDED
| REG_NOSUB
| REG_NEWLINE
) != 0 ) {
56 _error
-> Error ( "Failed to compile task regexp" );
60 for ( pkgCache :: GrpIterator Grp
= Cache
-> GrpBegin (); Grp
. end () == false ; ++ Grp
) {
61 pkgCache :: PkgIterator Pkg
= Grp
. FindPkg ( arch
);
62 if ( Pkg
. end () == true )
64 pkgCache :: VerIterator ver
= Cache
[ Pkg
]. CandidateVerIter ( Cache
);
68 pkgRecords :: Parser
& parser
= Recs
. Lookup ( ver
. FileList ());
69 const char * start
, * end
;
70 parser
. GetRec ( start
, end
);
71 unsigned int const length
= end
- start
;
73 strncpy ( buf
, start
, length
);
75 if ( regexec (& Pattern
, buf
, 0 , 0 , 0 ) != 0 )
82 if ( pkgset
. empty () == true )
83 return helper
. canNotFindTask ( Cache
, pattern
);
85 helper
. showTaskSelection ( pkgset
, pattern
);
89 // FromRegEx - Return all packages in the cache matching a pattern /*{{{*/
90 PackageSet
PackageSet :: FromRegEx ( pkgCacheFile
& Cache
, std :: string pattern
, CacheSetHelper
& helper
) {
91 static const char * const isregex
= ".?+*|[^$" ;
92 if ( pattern
. find_first_of ( isregex
) == std :: string :: npos
)
93 return PackageSet ( REGEX
);
95 size_t archfound
= pattern
. find_last_of ( ':' );
96 std :: string arch
= "native" ;
97 if ( archfound
!= std :: string :: npos
) {
98 arch
= pattern
. substr ( archfound
+ 1 );
99 if ( arch
. find_first_of ( isregex
) == std :: string :: npos
)
100 pattern
. erase ( archfound
);
105 if ( unlikely ( Cache
. GetPkgCache () == 0 ))
106 return PackageSet ( REGEX
);
108 APT :: CacheFilter :: PackageNameMatchesRegEx
regexfilter ( pattern
);
110 PackageSet
pkgset ( REGEX
);
111 for ( pkgCache :: GrpIterator Grp
= Cache
. GetPkgCache ()-> GrpBegin (); Grp
. end () == false ; ++ Grp
) {
112 if ( regexfilter ( Grp
) == false )
114 pkgCache :: PkgIterator Pkg
= Grp
. FindPkg ( arch
);
115 if ( Pkg
. end () == true ) {
116 if ( archfound
== std :: string :: npos
) {
117 std :: vector
< std :: string
> archs
= APT :: Configuration :: getArchitectures ();
118 for ( std :: vector
< std :: string
>:: const_iterator a
= archs
. begin ();
119 a
!= archs
. end () && Pkg
. end () != true ; ++ a
)
120 Pkg
= Grp
. FindPkg (* a
);
122 if ( Pkg
. end () == true )
129 if ( pkgset
. empty () == true )
130 return helper
. canNotFindRegEx ( Cache
, pattern
);
132 helper
. showRegExSelection ( pkgset
, pattern
);
136 // FromName - Returns the package defined by this string /*{{{*/
137 pkgCache :: PkgIterator
PackageSet :: FromName ( pkgCacheFile
& Cache
,
138 std :: string
const & str
, CacheSetHelper
& helper
) {
139 std :: string pkg
= str
;
140 size_t archfound
= pkg
. find_last_of ( ':' );
142 if ( archfound
!= std :: string :: npos
) {
143 arch
= pkg
. substr ( archfound
+ 1 );
144 pkg
. erase ( archfound
);
147 if ( Cache
. GetPkgCache () == 0 )
148 return pkgCache :: PkgIterator ( Cache
, 0 );
150 pkgCache :: PkgIterator
Pkg ( Cache
, 0 );
151 if ( arch
. empty () == true ) {
152 pkgCache :: GrpIterator Grp
= Cache
. GetPkgCache ()-> FindGrp ( pkg
);
153 if ( Grp
. end () == false )
154 Pkg
= Grp
. FindPreferredPkg ();
156 Pkg
= Cache
. GetPkgCache ()-> FindPkg ( pkg
, arch
);
158 if ( Pkg
. end () == true )
159 return helper
. canNotFindPkgName ( Cache
, str
);
163 // GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/
164 std :: map
< unsigned short , PackageSet
> PackageSet :: GroupedFromCommandLine (
165 pkgCacheFile
& Cache
, const char ** cmdline
,
166 std :: list
< PackageSet :: Modifier
> const & mods
,
167 unsigned short const & fallback
, CacheSetHelper
& helper
) {
168 std :: map
< unsigned short , PackageSet
> pkgsets
;
169 for ( const char ** I
= cmdline
; * I
!= 0 ; ++ I
) {
170 unsigned short modID
= fallback
;
171 std :: string str
= * I
;
172 bool modifierPresent
= false ;
173 for ( std :: list
< PackageSet :: Modifier
>:: const_iterator mod
= mods
. begin ();
174 mod
!= mods
. end (); ++ mod
) {
175 size_t const alength
= strlen ( mod
-> Alias
);
177 case PackageSet :: Modifier :: POSTFIX
:
178 if ( str
. compare ( str
. length () - alength
, alength
,
179 mod
-> Alias
, 0 , alength
) != 0 )
181 str
. erase ( str
. length () - alength
);
184 case PackageSet :: Modifier :: PREFIX
:
186 case PackageSet :: Modifier :: NONE
:
189 modifierPresent
= true ;
192 if ( modifierPresent
== true ) {
193 bool const errors
= helper
. showErrors ( false );
194 pkgCache :: PkgIterator Pkg
= FromName ( Cache
, * I
, helper
);
195 helper
. showErrors ( errors
);
196 if ( Pkg
. end () == false ) {
197 pkgsets
[ fallback
]. insert ( Pkg
);
201 pkgsets
[ modID
]. insert ( PackageSet :: FromString ( Cache
, str
, helper
));
206 // FromCommandLine - Return all packages specified on commandline /*{{{*/
207 PackageSet
PackageSet :: FromCommandLine ( pkgCacheFile
& Cache
, const char ** cmdline
, CacheSetHelper
& helper
) {
209 for ( const char ** I
= cmdline
; * I
!= 0 ; ++ I
) {
210 PackageSet pset
= FromString ( Cache
, * I
, helper
);
211 pkgset
. insert ( pset
. begin (), pset
. end ());
216 // FromString - Return all packages matching a specific string /*{{{*/
217 PackageSet
PackageSet :: FromString ( pkgCacheFile
& Cache
, std :: string
const & str
, CacheSetHelper
& helper
) {
218 _error
-> PushToStack ();
221 pkgCache :: PkgIterator Pkg
= FromName ( Cache
, str
, helper
);
222 if ( Pkg
. end () == false )
225 pkgset
= FromTask ( Cache
, str
, helper
);
226 if ( pkgset
. empty () == true ) {
227 pkgset
= FromRegEx ( Cache
, str
, helper
);
228 if ( pkgset
. empty () == true )
229 pkgset
= helper
. canNotFindPackage ( Cache
, str
);
233 if ( pkgset
. empty () == false )
234 _error
-> RevertToStack ();
236 _error
-> MergeWithStack ();
240 // GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/
241 std :: map
< unsigned short , VersionSet
> VersionSet :: GroupedFromCommandLine (
242 pkgCacheFile
& Cache
, const char ** cmdline
,
243 std :: list
< VersionSet :: Modifier
> const & mods
,
244 unsigned short const & fallback
, CacheSetHelper
& helper
) {
245 std :: map
< unsigned short , VersionSet
> versets
;
246 for ( const char ** I
= cmdline
; * I
!= 0 ; ++ I
) {
247 unsigned short modID
= fallback
;
248 VersionSet :: Version select
= VersionSet :: NEWEST
;
249 std :: string str
= * I
;
250 bool modifierPresent
= false ;
251 for ( std :: list
< VersionSet :: Modifier
>:: const_iterator mod
= mods
. begin ();
252 mod
!= mods
. end (); ++ mod
) {
253 if ( modID
== fallback
&& mod
-> ID
== fallback
)
254 select
= mod
-> SelectVersion
;
255 size_t const alength
= strlen ( mod
-> Alias
);
257 case VersionSet :: Modifier :: POSTFIX
:
258 if ( str
. compare ( str
. length () - alength
, alength
,
259 mod
-> Alias
, 0 , alength
) != 0 )
261 str
. erase ( str
. length () - alength
);
263 select
= mod
-> SelectVersion
;
265 case VersionSet :: Modifier :: PREFIX
:
267 case VersionSet :: Modifier :: NONE
:
270 modifierPresent
= true ;
274 if ( modifierPresent
== true ) {
275 bool const errors
= helper
. showErrors ( false );
276 VersionSet
const vset
= VersionSet :: FromString ( Cache
, std :: string (* I
), select
, helper
, true );
277 helper
. showErrors ( errors
);
278 if ( vset
. empty () == false ) {
279 versets
[ fallback
]. insert ( vset
);
283 versets
[ modID
]. insert ( VersionSet :: FromString ( Cache
, str
, select
, helper
));
288 // FromCommandLine - Return all versions specified on commandline /*{{{*/
289 APT :: VersionSet
VersionSet :: FromCommandLine ( pkgCacheFile
& Cache
, const char ** cmdline
,
290 APT :: VersionSet :: Version
const & fallback
, CacheSetHelper
& helper
) {
292 for ( const char ** I
= cmdline
; * I
!= 0 ; ++ I
)
293 verset
. insert ( VersionSet :: FromString ( Cache
, * I
, fallback
, helper
));
297 // FromString - Returns all versions spedcified by a string /*{{{*/
298 APT :: VersionSet
VersionSet :: FromString ( pkgCacheFile
& Cache
, std :: string pkg
,
299 APT :: VersionSet :: Version
const & fallback
, CacheSetHelper
& helper
,
300 bool const & onlyFromName
) {
302 bool verIsRel
= false ;
303 size_t const vertag
= pkg
. find_last_of ( "/=" );
304 if ( vertag
!= std :: string :: npos
) {
305 ver
= pkg
. substr ( vertag
+ 1 );
306 verIsRel
= ( pkg
[ vertag
] == '/' );
310 if ( onlyFromName
== false )
311 pkgset
= PackageSet :: FromString ( Cache
, pkg
, helper
);
313 pkgset
. insert ( PackageSet :: FromName ( Cache
, pkg
, helper
));
318 if ( pkgset
. getConstructor () != PackageSet :: UNKNOWN
)
319 errors
= helper
. showErrors ( false );
320 for ( PackageSet :: const_iterator P
= pkgset
. begin ();
321 P
!= pkgset
. end (); ++ P
) {
322 if ( vertag
== std :: string :: npos
) {
323 verset
. insert ( VersionSet :: FromPackage ( Cache
, P
, fallback
, helper
));
326 pkgCache :: VerIterator V
;
327 if ( ver
== "installed" )
328 V
= getInstalledVer ( Cache
, P
, helper
);
329 else if ( ver
== "candidate" )
330 V
= getCandidateVer ( Cache
, P
, helper
);
331 else if ( ver
== "newest" ) {
332 if ( P
-> VersionList
!= 0 )
335 V
= helper
. canNotFindNewestVer ( Cache
, P
);
337 pkgVersionMatch
Match ( ver
, ( verIsRel
== true ? pkgVersionMatch :: Release
:
338 pkgVersionMatch :: Version
));
340 if ( V
. end () == true ) {
341 if ( verIsRel
== true )
342 _error
-> Error ( _ ( "Release ' %s ' for ' %s ' was not found" ),
343 ver
. c_str (), P
. FullName ( true ). c_str ());
345 _error
-> Error ( _ ( "Version ' %s ' for ' %s ' was not found" ),
346 ver
. c_str (), P
. FullName ( true ). c_str ());
352 helper
. showSelectedVersion ( P
, V
, ver
, verIsRel
);
355 if ( pkgset
. getConstructor () != PackageSet :: UNKNOWN
)
356 helper
. showErrors ( errors
);
360 // FromPackage - versions from package based on fallback /*{{{*/
361 VersionSet
VersionSet :: FromPackage ( pkgCacheFile
& Cache
, pkgCache :: PkgIterator
const & P
,
362 VersionSet :: Version
const & fallback
, CacheSetHelper
& helper
) {
364 pkgCache :: VerIterator V
;
367 case VersionSet :: ALL
:
368 if ( P
-> VersionList
!= 0 )
369 for ( V
= P
. VersionList (); V
. end () != true ; ++ V
)
372 verset
. insert ( helper
. canNotFindAllVer ( Cache
, P
));
374 case VersionSet :: CANDANDINST
:
375 verset
. insert ( getInstalledVer ( Cache
, P
, helper
));
376 verset
. insert ( getCandidateVer ( Cache
, P
, helper
));
378 case VersionSet :: CANDIDATE
:
379 verset
. insert ( getCandidateVer ( Cache
, P
, helper
));
381 case VersionSet :: INSTALLED
:
382 verset
. insert ( getInstalledVer ( Cache
, P
, helper
));
384 case VersionSet :: CANDINST
:
385 showErrors
= helper
. showErrors ( false );
386 V
= getCandidateVer ( Cache
, P
, helper
);
388 V
= getInstalledVer ( Cache
, P
, helper
);
389 helper
. showErrors ( showErrors
);
390 if ( V
. end () == false )
393 verset
. insert ( helper
. canNotFindInstCandVer ( Cache
, P
));
395 case VersionSet :: INSTCAND
:
396 showErrors
= helper
. showErrors ( false );
397 V
= getInstalledVer ( Cache
, P
, helper
);
399 V
= getCandidateVer ( Cache
, P
, helper
);
400 helper
. showErrors ( showErrors
);
401 if ( V
. end () == false )
404 verset
. insert ( helper
. canNotFindInstCandVer ( Cache
, P
));
406 case VersionSet :: NEWEST
:
407 if ( P
-> VersionList
!= 0 )
408 verset
. insert ( P
. VersionList ());
410 verset
. insert ( helper
. canNotFindNewestVer ( Cache
, P
));
416 // getCandidateVer - Returns the candidate version of the given package /*{{{*/
417 pkgCache :: VerIterator
VersionSet :: getCandidateVer ( pkgCacheFile
& Cache
,
418 pkgCache :: PkgIterator
const & Pkg
, CacheSetHelper
& helper
) {
419 pkgCache :: VerIterator Cand
;
420 if ( Cache
. IsPolicyBuilt () == true || Cache
. IsDepCacheBuilt () == false )
422 if ( unlikely ( Cache
. GetPolicy () == 0 ))
423 return pkgCache :: VerIterator ( Cache
);
424 Cand
= Cache
. GetPolicy ()-> GetCandidateVer ( Pkg
);
426 Cand
= Cache
[ Pkg
]. CandidateVerIter ( Cache
);
428 if ( Cand
. end () == true )
429 return helper
. canNotFindCandidateVer ( Cache
, Pkg
);
433 // getInstalledVer - Returns the installed version of the given package /*{{{*/
434 pkgCache :: VerIterator
VersionSet :: getInstalledVer ( pkgCacheFile
& Cache
,
435 pkgCache :: PkgIterator
const & Pkg
, CacheSetHelper
& helper
) {
436 if ( Pkg
-> CurrentVer
== 0 )
437 return helper
. canNotFindInstalledVer ( Cache
, Pkg
);
438 return Pkg
. CurrentVer ();
441 // canNotFindPkgName - handle the case no package has this name /*{{{*/
442 pkgCache :: PkgIterator
CacheSetHelper :: canNotFindPkgName ( pkgCacheFile
& Cache
,
443 std :: string
const & str
) {
444 if ( ShowError
== true )
445 _error
-> Insert ( ErrorType
, _ ( "Unable to locate package %s " ), str
. c_str ());
446 return pkgCache :: PkgIterator ( Cache
, 0 );
449 // canNotFindTask - handle the case no package is found for a task /*{{{*/
450 PackageSet
CacheSetHelper :: canNotFindTask ( pkgCacheFile
& Cache
, std :: string pattern
) {
451 if ( ShowError
== true )
452 _error
-> Insert ( ErrorType
, _ ( "Couldn't find task ' %s '" ), pattern
. c_str ());
456 // canNotFindRegEx - handle the case no package is found by a regex /*{{{*/
457 PackageSet
CacheSetHelper :: canNotFindRegEx ( pkgCacheFile
& Cache
, std :: string pattern
) {
458 if ( ShowError
== true )
459 _error
-> Insert ( ErrorType
, _ ( "Couldn't find any package by regex ' %s '" ), pattern
. c_str ());
463 // canNotFindPackage - handle the case no package is found from a string/*{{{*/
464 PackageSet
CacheSetHelper :: canNotFindPackage ( pkgCacheFile
& Cache
, std :: string
const & str
) {
468 // canNotFindAllVer /*{{{*/
469 VersionSet
CacheSetHelper :: canNotFindAllVer ( pkgCacheFile
& Cache
,
470 pkgCache :: PkgIterator
const & Pkg
) {
471 if ( ShowError
== true )
472 _error
-> Insert ( ErrorType
, _ ( "Can't select versions from package ' %s ' as it is purely virtual" ), Pkg
. FullName ( true ). c_str ());
476 // canNotFindInstCandVer /*{{{*/
477 VersionSet
CacheSetHelper :: canNotFindInstCandVer ( pkgCacheFile
& Cache
,
478 pkgCache :: PkgIterator
const & Pkg
) {
479 if ( ShowError
== true )
480 _error
-> Insert ( ErrorType
, _ ( "Can't select installed nor candidate version from package ' %s ' as it has neither of them" ), Pkg
. FullName ( true ). c_str ());
484 // canNotFindInstCandVer /*{{{*/
485 VersionSet
CacheSetHelper :: canNotFindCandInstVer ( pkgCacheFile
& Cache
,
486 pkgCache :: PkgIterator
const & Pkg
) {
487 if ( ShowError
== true )
488 _error
-> Insert ( ErrorType
, _ ( "Can't select installed nor candidate version from package ' %s ' as it has neither of them" ), Pkg
. FullName ( true ). c_str ());
492 // canNotFindNewestVer /*{{{*/
493 pkgCache :: VerIterator
CacheSetHelper :: canNotFindNewestVer ( pkgCacheFile
& Cache
,
494 pkgCache :: PkgIterator
const & Pkg
) {
495 if ( ShowError
== true )
496 _error
-> Insert ( ErrorType
, _ ( "Can't select newest version from package ' %s ' as it is purely virtual" ), Pkg
. FullName ( true ). c_str ());
497 return pkgCache :: VerIterator ( Cache
, 0 );
500 // canNotFindCandidateVer /*{{{*/
501 pkgCache :: VerIterator
CacheSetHelper :: canNotFindCandidateVer ( pkgCacheFile
& Cache
,
502 pkgCache :: PkgIterator
const & Pkg
) {
503 if ( ShowError
== true )
504 _error
-> Insert ( ErrorType
, _ ( "Can't select candidate version from package %s as it has no candidate" ), Pkg
. FullName ( true ). c_str ());
505 return pkgCache :: VerIterator ( Cache
, 0 );
508 // canNotFindInstalledVer /*{{{*/
509 pkgCache :: VerIterator
CacheSetHelper :: canNotFindInstalledVer ( pkgCacheFile
& Cache
,
510 pkgCache :: PkgIterator
const & Pkg
) {
511 if ( ShowError
== true )
512 _error
-> Insert ( ErrorType
, _ ( "Can't select installed version from package %s as it is not installed" ), Pkg
. FullName ( true ). c_str ());
513 return pkgCache :: VerIterator ( Cache
, 0 );