]>
git.saurik.com Git - apt.git/blob - apt-pkg/cacheset.cc
386ecfb5fad83f4f7106348c6c79a7ba2e3dfec0
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/cachefilter.h>
16 #include <apt-pkg/cacheset.h>
17 #include <apt-pkg/error.h>
18 #include <apt-pkg/strutl.h>
19 #include <apt-pkg/versionmatch.h>
28 // FromTask - Return all packages in the cache from a specific task /*{{{*/
29 PackageSet
PackageSet :: FromTask ( pkgCacheFile
& Cache
, std :: string pattern
, CacheSetHelper
& helper
) {
30 size_t const archfound
= pattern
. find_last_of ( ':' );
31 std :: string arch
= "native" ;
32 if ( archfound
!= std :: string :: npos
) {
33 arch
= pattern
. substr ( archfound
+ 1 );
34 pattern
. erase ( archfound
);
37 if ( pattern
[ pattern
. length () - 1 ] != '^' )
38 return APT :: PackageSet ( TASK
);
39 pattern
. erase ( pattern
. length ()- 1 );
41 if ( unlikely ( Cache
. GetPkgCache () == 0 || Cache
. GetDepCache () == 0 ))
42 return APT :: PackageSet ( TASK
);
44 PackageSet
pkgset ( TASK
);
46 pkgRecords
Recs ( Cache
);
48 // build regexp for the task
51 snprintf ( S
, sizeof ( S
), "^Task:.*[, ] %s ([, ]|$)" , pattern
. c_str ());
52 if ( regcomp (& Pattern
, S
, REG_EXTENDED
| REG_NOSUB
| REG_NEWLINE
) != 0 ) {
53 _error
-> Error ( "Failed to compile task regexp" );
57 for ( pkgCache :: GrpIterator Grp
= Cache
-> GrpBegin (); Grp
. end () == false ; ++ Grp
) {
58 pkgCache :: PkgIterator Pkg
= Grp
. FindPkg ( arch
);
59 if ( Pkg
. end () == true )
61 pkgCache :: VerIterator ver
= Cache
[ Pkg
]. CandidateVerIter ( Cache
);
65 pkgRecords :: Parser
& parser
= Recs
. Lookup ( ver
. FileList ());
66 const char * start
, * end
;
67 parser
. GetRec ( start
, end
);
68 unsigned int const length
= end
- start
;
70 strncpy ( buf
, start
, length
);
72 if ( regexec (& Pattern
, buf
, 0 , 0 , 0 ) != 0 )
79 if ( pkgset
. empty () == true )
80 return helper
. canNotFindTask ( Cache
, pattern
);
82 helper
. showTaskSelection ( pkgset
, pattern
);
86 // FromRegEx - Return all packages in the cache matching a pattern /*{{{*/
87 PackageSet
PackageSet :: FromRegEx ( pkgCacheFile
& Cache
, std :: string pattern
, CacheSetHelper
& helper
) {
88 static const char * const isregex
= ".?+*|[^$" ;
89 if ( pattern
. find_first_of ( isregex
) == std :: string :: npos
)
90 return PackageSet ( REGEX
);
92 size_t archfound
= pattern
. find_last_of ( ':' );
93 std :: string arch
= "native" ;
94 if ( archfound
!= std :: string :: npos
) {
95 arch
= pattern
. substr ( archfound
+ 1 );
96 if ( arch
. find_first_of ( isregex
) == std :: string :: npos
)
97 pattern
. erase ( archfound
);
102 if ( unlikely ( Cache
. GetPkgCache () == 0 ))
103 return PackageSet ( REGEX
);
105 APT :: CacheFilter :: PackageNameMatchesRegEx
regexfilter ( pattern
);
107 PackageSet
pkgset ( REGEX
);
108 for ( pkgCache :: GrpIterator Grp
= Cache
. GetPkgCache ()-> GrpBegin (); Grp
. end () == false ; ++ Grp
) {
109 if ( regexfilter ( Grp
) == false )
111 pkgCache :: PkgIterator Pkg
= Grp
. FindPkg ( arch
);
112 if ( Pkg
. end () == true ) {
113 if ( archfound
== std :: string :: npos
) {
114 std :: vector
< std :: string
> archs
= APT :: Configuration :: getArchitectures ();
115 for ( std :: vector
< std :: string
>:: const_iterator a
= archs
. begin ();
116 a
!= archs
. end () && Pkg
. end () != true ; ++ a
)
117 Pkg
= Grp
. FindPkg (* a
);
119 if ( Pkg
. end () == true )
126 if ( pkgset
. empty () == true )
127 return helper
. canNotFindRegEx ( Cache
, pattern
);
129 helper
. showRegExSelection ( pkgset
, pattern
);
133 // FromName - Returns the package defined by this string /*{{{*/
134 pkgCache :: PkgIterator
PackageSet :: FromName ( pkgCacheFile
& Cache
,
135 std :: string
const & str
, CacheSetHelper
& helper
) {
136 std :: string pkg
= str
;
137 size_t archfound
= pkg
. find_last_of ( ':' );
139 if ( archfound
!= std :: string :: npos
) {
140 arch
= pkg
. substr ( archfound
+ 1 );
141 pkg
. erase ( archfound
);
144 if ( Cache
. GetPkgCache () == 0 )
145 return pkgCache :: PkgIterator ( Cache
, 0 );
147 pkgCache :: PkgIterator
Pkg ( Cache
, 0 );
148 if ( arch
. empty () == true ) {
149 pkgCache :: GrpIterator Grp
= Cache
. GetPkgCache ()-> FindGrp ( pkg
);
150 if ( Grp
. end () == false )
151 Pkg
= Grp
. FindPreferredPkg ();
153 Pkg
= Cache
. GetPkgCache ()-> FindPkg ( pkg
, arch
);
155 if ( Pkg
. end () == true )
156 return helper
. canNotFindPkgName ( Cache
, str
);
160 // GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/
161 std :: map
< unsigned short , PackageSet
> PackageSet :: GroupedFromCommandLine (
162 pkgCacheFile
& Cache
, const char ** cmdline
,
163 std :: list
< PackageSet :: Modifier
> const & mods
,
164 unsigned short const & fallback
, CacheSetHelper
& helper
) {
165 std :: map
< unsigned short , PackageSet
> pkgsets
;
166 for ( const char ** I
= cmdline
; * I
!= 0 ; ++ I
) {
167 unsigned short modID
= fallback
;
168 std :: string str
= * I
;
169 bool modifierPresent
= false ;
170 for ( std :: list
< PackageSet :: Modifier
>:: const_iterator mod
= mods
. begin ();
171 mod
!= mods
. end (); ++ mod
) {
172 size_t const alength
= strlen ( mod
-> Alias
);
174 case PackageSet :: Modifier :: POSTFIX
:
175 if ( str
. compare ( str
. length () - alength
, alength
,
176 mod
-> Alias
, 0 , alength
) != 0 )
178 str
. erase ( str
. length () - alength
);
181 case PackageSet :: Modifier :: PREFIX
:
183 case PackageSet :: Modifier :: NONE
:
186 modifierPresent
= true ;
189 if ( modifierPresent
== true ) {
190 bool const errors
= helper
. showErrors ( false );
191 pkgCache :: PkgIterator Pkg
= FromName ( Cache
, * I
, helper
);
192 helper
. showErrors ( errors
);
193 if ( Pkg
. end () == false ) {
194 pkgsets
[ fallback
]. insert ( Pkg
);
198 pkgsets
[ modID
]. insert ( PackageSet :: FromString ( Cache
, str
, helper
));
203 // FromCommandLine - Return all packages specified on commandline /*{{{*/
204 PackageSet
PackageSet :: FromCommandLine ( pkgCacheFile
& Cache
, const char ** cmdline
, CacheSetHelper
& helper
) {
206 for ( const char ** I
= cmdline
; * I
!= 0 ; ++ I
) {
207 PackageSet pset
= FromString ( Cache
, * I
, helper
);
208 pkgset
. insert ( pset
. begin (), pset
. end ());
213 // FromString - Return all packages matching a specific string /*{{{*/
214 PackageSet
PackageSet :: FromString ( pkgCacheFile
& Cache
, std :: string
const & str
, CacheSetHelper
& helper
) {
215 _error
-> PushToStack ();
218 pkgCache :: PkgIterator Pkg
= FromName ( Cache
, str
, helper
);
219 if ( Pkg
. end () == false )
222 pkgset
= FromTask ( Cache
, str
, helper
);
223 if ( pkgset
. empty () == true ) {
224 pkgset
= FromRegEx ( Cache
, str
, helper
);
225 if ( pkgset
. empty () == true )
226 pkgset
= helper
. canNotFindPackage ( Cache
, str
);
230 if ( pkgset
. empty () == false )
231 _error
-> RevertToStack ();
233 _error
-> MergeWithStack ();
237 // GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/
238 std :: map
< unsigned short , VersionSet
> VersionSet :: GroupedFromCommandLine (
239 pkgCacheFile
& Cache
, const char ** cmdline
,
240 std :: list
< VersionSet :: Modifier
> const & mods
,
241 unsigned short const & fallback
, CacheSetHelper
& helper
) {
242 std :: map
< unsigned short , VersionSet
> versets
;
243 for ( const char ** I
= cmdline
; * I
!= 0 ; ++ I
) {
244 unsigned short modID
= fallback
;
245 VersionSet :: Version select
= VersionSet :: NEWEST
;
246 std :: string str
= * I
;
247 bool modifierPresent
= false ;
248 for ( std :: list
< VersionSet :: Modifier
>:: const_iterator mod
= mods
. begin ();
249 mod
!= mods
. end (); ++ mod
) {
250 if ( modID
== fallback
&& mod
-> ID
== fallback
)
251 select
= mod
-> SelectVersion
;
252 size_t const alength
= strlen ( mod
-> Alias
);
254 case VersionSet :: Modifier :: POSTFIX
:
255 if ( str
. compare ( str
. length () - alength
, alength
,
256 mod
-> Alias
, 0 , alength
) != 0 )
258 str
. erase ( str
. length () - alength
);
260 select
= mod
-> SelectVersion
;
262 case VersionSet :: Modifier :: PREFIX
:
264 case VersionSet :: Modifier :: NONE
:
267 modifierPresent
= true ;
271 if ( modifierPresent
== true ) {
272 bool const errors
= helper
. showErrors ( false );
273 VersionSet
const vset
= VersionSet :: FromString ( Cache
, std :: string (* I
), select
, helper
, true );
274 helper
. showErrors ( errors
);
275 if ( vset
. empty () == false ) {
276 versets
[ fallback
]. insert ( vset
);
280 versets
[ modID
]. insert ( VersionSet :: FromString ( Cache
, str
, select
, helper
));
285 // FromCommandLine - Return all versions specified on commandline /*{{{*/
286 APT :: VersionSet
VersionSet :: FromCommandLine ( pkgCacheFile
& Cache
, const char ** cmdline
,
287 APT :: VersionSet :: Version
const & fallback
, CacheSetHelper
& helper
) {
289 for ( const char ** I
= cmdline
; * I
!= 0 ; ++ I
)
290 verset
. insert ( VersionSet :: FromString ( Cache
, * I
, fallback
, helper
));
294 // FromString - Returns all versions spedcified by a string /*{{{*/
295 APT :: VersionSet
VersionSet :: FromString ( pkgCacheFile
& Cache
, std :: string pkg
,
296 APT :: VersionSet :: Version
const & fallback
, CacheSetHelper
& helper
,
297 bool const & onlyFromName
) {
299 bool verIsRel
= false ;
300 size_t const vertag
= pkg
. find_last_of ( "/=" );
301 if ( vertag
!= string :: npos
) {
302 ver
= pkg
. substr ( vertag
+ 1 );
303 verIsRel
= ( pkg
[ vertag
] == '/' );
307 if ( onlyFromName
== false )
308 pkgset
= PackageSet :: FromString ( Cache
, pkg
, helper
);
310 pkgset
. insert ( PackageSet :: FromName ( Cache
, pkg
, helper
));
315 if ( pkgset
. getConstructor () != PackageSet :: UNKNOWN
)
316 errors
= helper
. showErrors ( false );
317 for ( PackageSet :: const_iterator P
= pkgset
. begin ();
318 P
!= pkgset
. end (); ++ P
) {
319 if ( vertag
== string :: npos
) {
320 verset
. insert ( VersionSet :: FromPackage ( Cache
, P
, fallback
, helper
));
323 pkgCache :: VerIterator V
;
324 if ( ver
== "installed" )
325 V
= getInstalledVer ( Cache
, P
, helper
);
326 else if ( ver
== "candidate" )
327 V
= getCandidateVer ( Cache
, P
, helper
);
328 else if ( ver
== "newest" ) {
329 if ( P
-> VersionList
!= 0 )
332 V
= helper
. canNotFindNewestVer ( Cache
, P
);
334 pkgVersionMatch
Match ( ver
, ( verIsRel
== true ? pkgVersionMatch :: Release
:
335 pkgVersionMatch :: Version
));
337 if ( V
. end () == true ) {
338 if ( verIsRel
== true )
339 _error
-> Error ( _ ( "Release ' %s ' for ' %s ' was not found" ),
340 ver
. c_str (), P
. FullName ( true ). c_str ());
342 _error
-> Error ( _ ( "Version ' %s ' for ' %s ' was not found" ),
343 ver
. c_str (), P
. FullName ( true ). c_str ());
349 helper
. showSelectedVersion ( P
, V
, ver
, verIsRel
);
352 if ( pkgset
. getConstructor () != PackageSet :: UNKNOWN
)
353 helper
. showErrors ( errors
);
357 // FromPackage - versions from package based on fallback /*{{{*/
358 VersionSet
VersionSet :: FromPackage ( pkgCacheFile
& Cache
, pkgCache :: PkgIterator
const & P
,
359 VersionSet :: Version
const & fallback
, CacheSetHelper
& helper
) {
361 pkgCache :: VerIterator V
;
364 case VersionSet :: ALL
:
365 if ( P
-> VersionList
!= 0 )
366 for ( V
= P
. VersionList (); V
. end () != true ; ++ V
)
369 verset
. insert ( helper
. canNotFindAllVer ( Cache
, P
));
371 case VersionSet :: CANDANDINST
:
372 verset
. insert ( getInstalledVer ( Cache
, P
, helper
));
373 verset
. insert ( getCandidateVer ( Cache
, P
, helper
));
375 case VersionSet :: CANDIDATE
:
376 verset
. insert ( getCandidateVer ( Cache
, P
, helper
));
378 case VersionSet :: INSTALLED
:
379 verset
. insert ( getInstalledVer ( Cache
, P
, helper
));
381 case VersionSet :: CANDINST
:
382 showErrors
= helper
. showErrors ( false );
383 V
= getCandidateVer ( Cache
, P
, helper
);
385 V
= getInstalledVer ( Cache
, P
, helper
);
386 helper
. showErrors ( showErrors
);
387 if ( V
. end () == false )
390 verset
. insert ( helper
. canNotFindInstCandVer ( Cache
, P
));
392 case VersionSet :: INSTCAND
:
393 showErrors
= helper
. showErrors ( false );
394 V
= getInstalledVer ( Cache
, P
, helper
);
396 V
= getCandidateVer ( Cache
, P
, helper
);
397 helper
. showErrors ( showErrors
);
398 if ( V
. end () == false )
401 verset
. insert ( helper
. canNotFindInstCandVer ( Cache
, P
));
403 case VersionSet :: NEWEST
:
404 if ( P
-> VersionList
!= 0 )
405 verset
. insert ( P
. VersionList ());
407 verset
. insert ( helper
. canNotFindNewestVer ( Cache
, P
));
413 // getCandidateVer - Returns the candidate version of the given package /*{{{*/
414 pkgCache :: VerIterator
VersionSet :: getCandidateVer ( pkgCacheFile
& Cache
,
415 pkgCache :: PkgIterator
const & Pkg
, CacheSetHelper
& helper
) {
416 pkgCache :: VerIterator Cand
;
417 if ( Cache
. IsPolicyBuilt () == true || Cache
. IsDepCacheBuilt () == false )
419 if ( unlikely ( Cache
. GetPolicy () == 0 ))
420 return pkgCache :: VerIterator ( Cache
);
421 Cand
= Cache
. GetPolicy ()-> GetCandidateVer ( Pkg
);
423 Cand
= Cache
[ Pkg
]. CandidateVerIter ( Cache
);
425 if ( Cand
. end () == true )
426 return helper
. canNotFindCandidateVer ( Cache
, Pkg
);
430 // getInstalledVer - Returns the installed version of the given package /*{{{*/
431 pkgCache :: VerIterator
VersionSet :: getInstalledVer ( pkgCacheFile
& Cache
,
432 pkgCache :: PkgIterator
const & Pkg
, CacheSetHelper
& helper
) {
433 if ( Pkg
-> CurrentVer
== 0 )
434 return helper
. canNotFindInstalledVer ( Cache
, Pkg
);
435 return Pkg
. CurrentVer ();
438 // canNotFindPkgName - handle the case no package has this name /*{{{*/
439 pkgCache :: PkgIterator
CacheSetHelper :: canNotFindPkgName ( pkgCacheFile
& Cache
,
440 std :: string
const & str
) {
441 if ( ShowError
== true )
442 _error
-> Insert ( ErrorType
, _ ( "Unable to locate package %s " ), str
. c_str ());
443 return pkgCache :: PkgIterator ( Cache
, 0 );
446 // canNotFindTask - handle the case no package is found for a task /*{{{*/
447 PackageSet
CacheSetHelper :: canNotFindTask ( pkgCacheFile
& Cache
, std :: string pattern
) {
448 if ( ShowError
== true )
449 _error
-> Insert ( ErrorType
, _ ( "Couldn't find task ' %s '" ), pattern
. c_str ());
453 // canNotFindRegEx - handle the case no package is found by a regex /*{{{*/
454 PackageSet
CacheSetHelper :: canNotFindRegEx ( pkgCacheFile
& Cache
, std :: string pattern
) {
455 if ( ShowError
== true )
456 _error
-> Insert ( ErrorType
, _ ( "Couldn't find any package by regex ' %s '" ), pattern
. c_str ());
460 // canNotFindPackage - handle the case no package is found from a string/*{{{*/
461 PackageSet
CacheSetHelper :: canNotFindPackage ( pkgCacheFile
& Cache
, std :: string
const & str
) {
465 // canNotFindAllVer /*{{{*/
466 VersionSet
CacheSetHelper :: canNotFindAllVer ( pkgCacheFile
& Cache
,
467 pkgCache :: PkgIterator
const & Pkg
) {
468 if ( ShowError
== true )
469 _error
-> Insert ( ErrorType
, _ ( "Can't select versions from package ' %s ' as it is purely virtual" ), Pkg
. FullName ( true ). c_str ());
473 // canNotFindInstCandVer /*{{{*/
474 VersionSet
CacheSetHelper :: canNotFindInstCandVer ( pkgCacheFile
& Cache
,
475 pkgCache :: PkgIterator
const & Pkg
) {
476 if ( ShowError
== true )
477 _error
-> Insert ( ErrorType
, _ ( "Can't select installed nor candidate version from package ' %s ' as it has neither of them" ), Pkg
. FullName ( true ). c_str ());
481 // canNotFindInstCandVer /*{{{*/
482 VersionSet
CacheSetHelper :: canNotFindCandInstVer ( pkgCacheFile
& Cache
,
483 pkgCache :: PkgIterator
const & Pkg
) {
484 if ( ShowError
== true )
485 _error
-> Insert ( ErrorType
, _ ( "Can't select installed nor candidate version from package ' %s ' as it has neither of them" ), Pkg
. FullName ( true ). c_str ());
489 // canNotFindNewestVer /*{{{*/
490 pkgCache :: VerIterator
CacheSetHelper :: canNotFindNewestVer ( pkgCacheFile
& Cache
,
491 pkgCache :: PkgIterator
const & Pkg
) {
492 if ( ShowError
== true )
493 _error
-> Insert ( ErrorType
, _ ( "Can't select newest version from package ' %s ' as it is purely virtual" ), Pkg
. FullName ( true ). c_str ());
494 return pkgCache :: VerIterator ( Cache
, 0 );
497 // canNotFindCandidateVer /*{{{*/
498 pkgCache :: VerIterator
CacheSetHelper :: canNotFindCandidateVer ( pkgCacheFile
& Cache
,
499 pkgCache :: PkgIterator
const & Pkg
) {
500 if ( ShowError
== true )
501 _error
-> Insert ( ErrorType
, _ ( "Can't select candidate version from package %s as it has no candidate" ), Pkg
. FullName ( true ). c_str ());
502 return pkgCache :: VerIterator ( Cache
, 0 );
505 // canNotFindInstalledVer /*{{{*/
506 pkgCache :: VerIterator
CacheSetHelper :: canNotFindInstalledVer ( pkgCacheFile
& Cache
,
507 pkgCache :: PkgIterator
const & Pkg
) {
508 if ( ShowError
== true )
509 _error
-> Insert ( ErrorType
, _ ( "Can't select installed version from package %s as it is not installed" ), Pkg
. FullName ( true ). c_str ());
510 return pkgCache :: VerIterator ( Cache
, 0 );