1 // -*- mode: cpp; mode: fold -*-
3 // $Id: deblistparser.cc,v 1.29.2.5 2004/01/06 01:43:44 mdz Exp $
4 /* ######################################################################
6 Package Cache Generator - Generator for the cache structure.
8 This builds the cache structure from the abstract package list parser.
10 ##################################################################### */
12 // Include Files /*{{{*/
15 #include <apt-pkg/deblistparser.h>
16 #include <apt-pkg/error.h>
17 #include <apt-pkg/configuration.h>
18 #include <apt-pkg/cachefilter.h>
19 #include <apt-pkg/aptconfiguration.h>
20 #include <apt-pkg/strutl.h>
21 #include <apt-pkg/fileutl.h>
22 #include <apt-pkg/crc-16.h>
23 #include <apt-pkg/md5.h>
24 #include <apt-pkg/macros.h>
31 static debListParser::WordList PrioList
[] = {
32 {"required",pkgCache::State::Required
},
33 {"important",pkgCache::State::Important
},
34 {"standard",pkgCache::State::Standard
},
35 {"optional",pkgCache::State::Optional
},
36 {"extra",pkgCache::State::Extra
},
39 // ListParser::debListParser - Constructor /*{{{*/
40 // ---------------------------------------------------------------------
41 /* Provide an architecture and only this one and "all" will be accepted
42 in Step(), if no Architecture is given we will accept every arch
43 we would accept in general with checkArchitecture() */
44 debListParser::debListParser(FileFd
*File
, string
const &Arch
) : Tags(File
),
47 this->Arch
= _config
->Find("APT::Architecture");
48 Architectures
= APT::Configuration::getArchitectures();
49 MultiArchEnabled
= Architectures
.size() > 1;
52 // ListParser::UniqFindTagWrite - Find the tag and write a unq string /*{{{*/
53 // ---------------------------------------------------------------------
55 unsigned long debListParser::UniqFindTagWrite(const char *Tag
)
59 if (Section
.Find(Tag
,Start
,Stop
) == false)
61 return WriteUniqString(Start
,Stop
- Start
);
64 // ListParser::Package - Return the package name /*{{{*/
65 // ---------------------------------------------------------------------
66 /* This is to return the name of the package this section describes */
67 string
debListParser::Package() {
68 string
const Result
= Section
.FindS("Package");
69 if(unlikely(Result
.empty() == true))
70 _error
->Error("Encountered a section with no Package: header");
74 // ListParser::Architecture - Return the package arch /*{{{*/
75 // ---------------------------------------------------------------------
76 /* This will return the Architecture of the package this section describes */
77 string
debListParser::Architecture() {
78 return Section
.FindS("Architecture");
81 // ListParser::ArchitectureAll /*{{{*/
82 // ---------------------------------------------------------------------
84 bool debListParser::ArchitectureAll() {
85 return Section
.FindS("Architecture") == "all";
88 // ListParser::Version - Return the version string /*{{{*/
89 // ---------------------------------------------------------------------
90 /* This is to return the string describing the version in debian form,
91 epoch:upstream-release. If this returns the blank string then the
92 entry is assumed to only describe package properties */
93 string
debListParser::Version()
95 return Section
.FindS("Version");
98 // ListParser::NewVersion - Fill in the version structure /*{{{*/
99 // ---------------------------------------------------------------------
101 bool debListParser::NewVersion(pkgCache::VerIterator
&Ver
)
104 Ver
->Section
= UniqFindTagWrite("Section");
107 string
const MultiArch
= Section
.FindS("Multi-Arch");
108 if (MultiArch
.empty() == true)
109 Ver
->MultiArch
= pkgCache::Version::None
;
110 else if (MultiArch
== "same") {
112 if (ArchitectureAll() == true)
114 /* Arch all packages can't be Multi-Arch: same */
115 _error
->Warning("Architecture: all package '%s' can't be Multi-Arch: same",
116 Section
.FindS("Package").c_str());
117 Ver
->MultiArch
= pkgCache::Version::None
;
120 Ver
->MultiArch
= pkgCache::Version::Same
;
122 else if (MultiArch
== "foreign")
123 Ver
->MultiArch
= pkgCache::Version::Foreign
;
124 else if (MultiArch
== "allowed")
125 Ver
->MultiArch
= pkgCache::Version::Allowed
;
128 _error
->Warning("Unknown Multi-Arch type '%s' for package '%s'",
129 MultiArch
.c_str(), Section
.FindS("Package").c_str());
130 Ver
->MultiArch
= pkgCache::Version::None
;
133 if (ArchitectureAll() == true)
134 Ver
->MultiArch
|= pkgCache::Version::All
;
137 Ver
->Size
= Section
.FindULL("Size");
138 // Unpacked Size (in K)
139 Ver
->InstalledSize
= Section
.FindULL("Installed-Size");
140 Ver
->InstalledSize
*= 1024;
145 if (Section
.Find("Priority",Start
,Stop
) == true)
147 if (GrabWord(string(Start
,Stop
-Start
),PrioList
,Ver
->Priority
) == false)
148 Ver
->Priority
= pkgCache::State::Extra
;
151 if (ParseDepends(Ver
,"Depends",pkgCache::Dep::Depends
) == false)
153 if (ParseDepends(Ver
,"Pre-Depends",pkgCache::Dep::PreDepends
) == false)
155 if (ParseDepends(Ver
,"Suggests",pkgCache::Dep::Suggests
) == false)
157 if (ParseDepends(Ver
,"Recommends",pkgCache::Dep::Recommends
) == false)
159 if (ParseDepends(Ver
,"Conflicts",pkgCache::Dep::Conflicts
) == false)
161 if (ParseDepends(Ver
,"Breaks",pkgCache::Dep::DpkgBreaks
) == false)
163 if (ParseDepends(Ver
,"Replaces",pkgCache::Dep::Replaces
) == false)
165 if (ParseDepends(Ver
,"Enhances",pkgCache::Dep::Enhances
) == false)
169 if (ParseDepends(Ver
,"Optional",pkgCache::Dep::Suggests
) == false)
172 if (ParseProvides(Ver
) == false)
178 // ListParser::Description - Return the description string /*{{{*/
179 // ---------------------------------------------------------------------
180 /* This is to return the string describing the package in debian
181 form. If this returns the blank string then the entry is assumed to
182 only describe package properties */
183 string
debListParser::Description()
185 string
const lang
= DescriptionLanguage();
187 return Section
.FindS("Description");
189 return Section
.FindS(string("Description-").append(lang
).c_str());
192 // ListParser::DescriptionLanguage - Return the description lang string /*{{{*/
193 // ---------------------------------------------------------------------
194 /* This is to return the string describing the language of
195 description. If this returns the blank string then the entry is
196 assumed to describe original description. */
197 string
debListParser::DescriptionLanguage()
199 if (Section
.FindS("Description").empty() == false)
202 std::vector
<string
> const lang
= APT::Configuration::getLanguages(true);
203 for (std::vector
<string
>::const_iterator l
= lang
.begin();
204 l
!= lang
.end(); ++l
)
205 if (Section
.FindS(string("Description-").append(*l
).c_str()).empty() == false)
211 // ListParser::Description - Return the description_md5 MD5SumValue /*{{{*/
212 // ---------------------------------------------------------------------
213 /* This is to return the md5 string to allow the check if it is the right
214 description. If no Description-md5 is found in the section it will be
217 MD5SumValue
debListParser::Description_md5()
219 string
const value
= Section
.FindS("Description-md5");
220 if (value
.empty() == true)
222 std::string
const desc
= Description() + "\n";
224 return MD5SumValue();
227 md5
.Add(desc
.c_str());
230 else if (likely(value
.size() == 32))
232 if (likely(value
.find_first_not_of("0123456789abcdefABCDEF") == string::npos
))
233 return MD5SumValue(value
);
234 _error
->Error("Malformed Description-md5 line; includes invalid character '%s'", value
.c_str());
235 return MD5SumValue();
237 _error
->Error("Malformed Description-md5 line; doesn't have the required length (32 != %d) '%s'", (int)value
.size(), value
.c_str());
238 return MD5SumValue();
241 // ListParser::UsePackage - Update a package structure /*{{{*/
242 // ---------------------------------------------------------------------
243 /* This is called to update the package with any new information
244 that might be found in the section */
245 bool debListParser::UsePackage(pkgCache::PkgIterator
&Pkg
,
246 pkgCache::VerIterator
&Ver
)
248 if (Pkg
->Section
== 0)
249 Pkg
->Section
= UniqFindTagWrite("Section");
251 string
const static myArch
= _config
->Find("APT::Architecture");
252 // Possible values are: "all", "native", "installed" and "none"
253 // The "installed" mode is handled by ParseStatus(), See #544481 and friends.
254 string
const static essential
= _config
->Find("pkgCacheGen::Essential", "all");
255 if (essential
== "all" ||
256 (essential
== "native" && Pkg
->Arch
!= 0 && myArch
== Pkg
.Arch()))
257 if (Section
.FindFlag("Essential",Pkg
->Flags
,pkgCache::Flag::Essential
) == false)
259 if (Section
.FindFlag("Important",Pkg
->Flags
,pkgCache::Flag::Important
) == false)
262 if (strcmp(Pkg
.Name(),"apt") == 0)
264 if ((essential
== "native" && Pkg
->Arch
!= 0 && myArch
== Pkg
.Arch()) ||
266 Pkg
->Flags
|= pkgCache::Flag::Essential
| pkgCache::Flag::Important
;
268 Pkg
->Flags
|= pkgCache::Flag::Important
;
271 if (ParseStatus(Pkg
,Ver
) == false)
276 // ListParser::VersionHash - Compute a unique hash for this version /*{{{*/
277 // ---------------------------------------------------------------------
279 unsigned short debListParser::VersionHash()
281 const char *Sections
[] ={"Installed-Size",
289 unsigned long Result
= INIT_FCS
;
291 for (const char * const *I
= Sections
; *I
!= 0; ++I
)
295 if (Section
.Find(*I
,Start
,End
) == false || End
- Start
>= (signed)sizeof(S
))
298 /* Strip out any spaces from the text, this undoes dpkgs reformatting
299 of certain fields. dpkg also has the rather interesting notion of
300 reformatting depends operators < -> <= */
302 for (; Start
!= End
; ++Start
)
304 if (isspace(*Start
) != 0)
306 *J
++ = tolower_ascii(*Start
);
308 if ((*Start
== '<' || *Start
== '>') && Start
[1] != *Start
&& Start
[1] != '=')
312 Result
= AddCRC16(Result
,S
,J
- S
);
318 // ListParser::ParseStatus - Parse the status field /*{{{*/
319 // ---------------------------------------------------------------------
320 /* Status lines are of the form,
321 Status: want flag status
322 want = unknown, install, hold, deinstall, purge
323 flag = ok, reinstreq, hold, hold-reinstreq
324 status = not-installed, unpacked, half-configured,
325 half-installed, config-files, post-inst-failed,
326 removal-failed, installed
328 Some of the above are obsolete (I think?) flag = hold-* and
329 status = post-inst-failed, removal-failed at least.
331 bool debListParser::ParseStatus(pkgCache::PkgIterator
&Pkg
,
332 pkgCache::VerIterator
&Ver
)
336 if (Section
.Find("Status",Start
,Stop
) == false)
339 // UsePackage() is responsible for setting the flag in the default case
340 bool const static essential
= _config
->Find("pkgCacheGen::Essential", "") == "installed";
341 if (essential
== true &&
342 Section
.FindFlag("Essential",Pkg
->Flags
,pkgCache::Flag::Essential
) == false)
345 // Isolate the first word
346 const char *I
= Start
;
347 for(; I
< Stop
&& *I
!= ' '; I
++);
348 if (I
>= Stop
|| *I
!= ' ')
349 return _error
->Error("Malformed Status line");
351 // Process the want field
352 WordList WantList
[] = {{"unknown",pkgCache::State::Unknown
},
353 {"install",pkgCache::State::Install
},
354 {"hold",pkgCache::State::Hold
},
355 {"deinstall",pkgCache::State::DeInstall
},
356 {"purge",pkgCache::State::Purge
},
358 if (GrabWord(string(Start
,I
-Start
),WantList
,Pkg
->SelectedState
) == false)
359 return _error
->Error("Malformed 1st word in the Status line");
361 // Isloate the next word
364 for(; I
< Stop
&& *I
!= ' '; I
++);
365 if (I
>= Stop
|| *I
!= ' ')
366 return _error
->Error("Malformed status line, no 2nd word");
368 // Process the flag field
369 WordList FlagList
[] = {{"ok",pkgCache::State::Ok
},
370 {"reinstreq",pkgCache::State::ReInstReq
},
371 {"hold",pkgCache::State::HoldInst
},
372 {"hold-reinstreq",pkgCache::State::HoldReInstReq
},
374 if (GrabWord(string(Start
,I
-Start
),FlagList
,Pkg
->InstState
) == false)
375 return _error
->Error("Malformed 2nd word in the Status line");
377 // Isloate the last word
380 for(; I
< Stop
&& *I
!= ' '; I
++);
382 return _error
->Error("Malformed Status line, no 3rd word");
384 // Process the flag field
385 WordList StatusList
[] = {{"not-installed",pkgCache::State::NotInstalled
},
386 {"unpacked",pkgCache::State::UnPacked
},
387 {"half-configured",pkgCache::State::HalfConfigured
},
388 {"installed",pkgCache::State::Installed
},
389 {"half-installed",pkgCache::State::HalfInstalled
},
390 {"config-files",pkgCache::State::ConfigFiles
},
391 {"triggers-awaited",pkgCache::State::TriggersAwaited
},
392 {"triggers-pending",pkgCache::State::TriggersPending
},
393 {"post-inst-failed",pkgCache::State::HalfConfigured
},
394 {"removal-failed",pkgCache::State::HalfInstalled
},
396 if (GrabWord(string(Start
,I
-Start
),StatusList
,Pkg
->CurrentState
) == false)
397 return _error
->Error("Malformed 3rd word in the Status line");
399 /* A Status line marks the package as indicating the current
400 version as well. Only if it is actually installed.. Otherwise
401 the interesting dpkg handling of the status file creates bogus
403 if (!(Pkg
->CurrentState
== pkgCache::State::NotInstalled
||
404 Pkg
->CurrentState
== pkgCache::State::ConfigFiles
))
406 if (Ver
.end() == true)
407 _error
->Warning("Encountered status field in a non-version description");
409 Pkg
->CurrentVer
= Ver
.Index();
415 const char *debListParser::ConvertRelation(const char *I
,unsigned int &Op
)
417 // Determine the operator
425 Op
= pkgCache::Dep::LessEq
;
432 Op
= pkgCache::Dep::Less
;
436 // < is the same as <= and << is really Cs < for some reason
437 Op
= pkgCache::Dep::LessEq
;
445 Op
= pkgCache::Dep::GreaterEq
;
452 Op
= pkgCache::Dep::Greater
;
456 // > is the same as >= and >> is really Cs > for some reason
457 Op
= pkgCache::Dep::GreaterEq
;
461 Op
= pkgCache::Dep::Equals
;
465 // HACK around bad package definitions
467 Op
= pkgCache::Dep::Equals
;
473 // ListParser::ParseDepends - Parse a dependency element /*{{{*/
474 // ---------------------------------------------------------------------
475 /* This parses the dependency elements out of a standard string in place,
477 const char *debListParser::ParseDepends(const char *Start
,const char *Stop
,
478 string
&Package
,string
&Ver
,
479 unsigned int &Op
, bool const &ParseArchFlags
,
480 bool const &StripMultiArch
)
482 // Strip off leading space
483 for (;Start
!= Stop
&& isspace(*Start
) != 0; Start
++);
485 // Parse off the package name
486 const char *I
= Start
;
487 for (;I
!= Stop
&& isspace(*I
) == 0 && *I
!= '(' && *I
!= ')' &&
488 *I
!= ',' && *I
!= '|' && *I
!= '[' && *I
!= ']'; I
++);
491 if (I
!= Stop
&& *I
== ')')
497 // Stash the package name
498 Package
.assign(Start
,I
- Start
);
500 // We don't want to confuse library users which can't handle MultiArch
501 string
const arch
= _config
->Find("APT::Architecture");
502 if (StripMultiArch
== true) {
503 size_t const found
= Package
.rfind(':');
504 if (found
!= string::npos
&&
505 (strcmp(Package
.c_str() + found
, ":any") == 0 ||
506 strcmp(Package
.c_str() + found
, ":native") == 0 ||
507 strcmp(Package
.c_str() + found
+ 1, arch
.c_str()) == 0))
508 Package
= Package
.substr(0,found
);
511 // Skip white space to the '('
512 for (;I
!= Stop
&& isspace(*I
) != 0 ; I
++);
515 if (I
!= Stop
&& *I
== '(')
518 for (I
++; I
!= Stop
&& isspace(*I
) != 0 ; I
++);
521 I
= ConvertRelation(I
,Op
);
524 for (;I
!= Stop
&& isspace(*I
) != 0; I
++);
526 I
= (const char*) memchr(I
, ')', Stop
- I
);
527 if (I
== NULL
|| Start
== I
)
530 // Skip trailing whitespace
532 for (; End
> Start
&& isspace(End
[-1]); End
--);
534 Ver
.assign(Start
,End
-Start
);
540 Op
= pkgCache::Dep::NoOp
;
544 for (;I
!= Stop
&& isspace(*I
) != 0; I
++);
546 if (ParseArchFlags
== true)
548 APT::CacheFilter::PackageArchitectureMatchesSpecification
matchesArch(arch
, false);
550 // Parse an architecture
551 if (I
!= Stop
&& *I
== '[')
555 if (unlikely(I
== Stop
))
560 bool NegArch
= false;
563 // look for whitespace or ending ']'
564 for (;End
!= Stop
&& !isspace(*End
) && *End
!= ']'; ++End
);
566 if (unlikely(End
== Stop
))
575 std::string
arch(I
, End
);
576 if (arch
.empty() == false && matchesArch(arch
.c_str()) == true)
581 // we found a match, so fast-forward to the end of the wildcards
582 for (; End
!= Stop
&& *End
!= ']'; ++End
);
591 for (;I
!= Stop
&& isspace(*I
) != 0; I
++);
598 Package
= ""; /* not for this arch */
602 for (;I
!= Stop
&& isspace(*I
) != 0; I
++);
605 if (I
!= Stop
&& *I
== '|')
606 Op
|= pkgCache::Dep::Or
;
608 if (I
== Stop
|| *I
== ',' || *I
== '|')
611 for (I
++; I
!= Stop
&& isspace(*I
) != 0; I
++);
618 // ListParser::ParseDepends - Parse a dependency list /*{{{*/
619 // ---------------------------------------------------------------------
620 /* This is the higher level depends parser. It takes a tag and generates
621 a complete depends tree for the given version. */
622 bool debListParser::ParseDepends(pkgCache::VerIterator
&Ver
,
623 const char *Tag
,unsigned int Type
)
627 if (Section
.Find(Tag
,Start
,Stop
) == false)
630 string
const pkgArch
= Ver
.Arch();
638 Start
= ParseDepends(Start
, Stop
, Package
, Version
, Op
, false, false);
640 return _error
->Error("Problem parsing dependency %s",Tag
);
641 size_t const found
= Package
.rfind(':');
643 // If negative is unspecific it needs to apply on all architectures
644 if (MultiArchEnabled
== true && found
== string::npos
&&
645 (Type
== pkgCache::Dep::Conflicts
||
646 Type
== pkgCache::Dep::DpkgBreaks
||
647 Type
== pkgCache::Dep::Replaces
))
649 for (std::vector
<std::string
>::const_iterator a
= Architectures
.begin();
650 a
!= Architectures
.end(); ++a
)
651 if (NewDepends(Ver
,Package
,*a
,Version
,Op
,Type
) == false)
653 if (NewDepends(Ver
,Package
,"none",Version
,Op
,Type
) == false)
656 else if (MultiArchEnabled
== true && found
!= string::npos
&&
657 strcmp(Package
.c_str() + found
, ":any") != 0)
659 string Arch
= Package
.substr(found
+1, string::npos
);
660 Package
= Package
.substr(0, found
);
661 // Such dependencies are not supposed to be accepted …
662 // … but this is probably the best thing to do.
663 if (Arch
== "native")
664 Arch
= _config
->Find("APT::Architecture");
665 if (NewDepends(Ver
,Package
,Arch
,Version
,Op
,Type
) == false)
670 if (NewDepends(Ver
,Package
,pkgArch
,Version
,Op
,Type
) == false)
672 if ((Type
== pkgCache::Dep::Conflicts
||
673 Type
== pkgCache::Dep::DpkgBreaks
||
674 Type
== pkgCache::Dep::Replaces
) &&
675 NewDepends(Ver
, Package
,
676 (pkgArch
!= "none") ? "none" : _config
->Find("APT::Architecture"),
677 Version
,Op
,Type
) == false)
686 // ListParser::ParseProvides - Parse the provides list /*{{{*/
687 // ---------------------------------------------------------------------
689 bool debListParser::ParseProvides(pkgCache::VerIterator
&Ver
)
693 if (Section
.Find("Provides",Start
,Stop
) == true)
697 string
const Arch
= Ver
.Arch();
702 Start
= ParseDepends(Start
,Stop
,Package
,Version
,Op
);
704 return _error
->Error("Problem parsing Provides line");
705 if (Op
!= pkgCache::Dep::NoOp
) {
706 _error
->Warning("Ignoring Provides line with DepCompareOp for package %s", Package
.c_str());
707 } else if ((Ver
->MultiArch
& pkgCache::Version::Foreign
) == pkgCache::Version::Foreign
) {
708 if (NewProvidesAllArch(Ver
, Package
, Version
) == false)
711 if (NewProvides(Ver
, Package
, Arch
, Version
) == false)
720 if ((Ver
->MultiArch
& pkgCache::Version::Allowed
) == pkgCache::Version::Allowed
)
722 string
const Package
= string(Ver
.ParentPkg().Name()).append(":").append("any");
723 return NewProvidesAllArch(Ver
, Package
, Ver
.VerStr());
725 else if ((Ver
->MultiArch
& pkgCache::Version::Foreign
) == pkgCache::Version::Foreign
)
726 return NewProvidesAllArch(Ver
, Ver
.ParentPkg().Name(), Ver
.VerStr());
731 // ListParser::NewProvides - add provides for all architectures /*{{{*/
732 bool debListParser::NewProvidesAllArch(pkgCache::VerIterator
&Ver
, string
const &Package
,
733 string
const &Version
) {
734 for (std::vector
<string
>::const_iterator a
= Architectures
.begin();
735 a
!= Architectures
.end(); ++a
)
737 if (NewProvides(Ver
, Package
, *a
, Version
) == false)
743 // ListParser::GrabWord - Matches a word and returns /*{{{*/
744 // ---------------------------------------------------------------------
745 /* Looks for a word in a list of words - for ParseStatus */
746 bool debListParser::GrabWord(string Word
,WordList
*List
,unsigned char &Out
)
748 for (unsigned int C
= 0; List
[C
].Str
!= 0; C
++)
750 if (strcasecmp(Word
.c_str(),List
[C
].Str
) == 0)
759 // ListParser::Step - Move to the next section in the file /*{{{*/
760 // ---------------------------------------------------------------------
761 /* This has to be carefull to only process the correct architecture */
762 bool debListParser::Step()
764 iOffset
= Tags
.Offset();
765 while (Tags
.Step(Section
) == true)
767 /* See if this is the correct Architecture, if it isn't then we
768 drop the whole section. A missing arch tag only happens (in theory)
769 inside the Status file, so that is a positive return */
770 string
const Architecture
= Section
.FindS("Architecture");
772 if (Arch
.empty() == true || Arch
== "any" || MultiArchEnabled
== false)
774 if (APT::Configuration::checkArchitecture(Architecture
) == true)
776 /* parse version stanzas without an architecture only in the status file
777 (and as misfortune bycatch flat-archives) */
778 if ((Arch
.empty() == true || Arch
== "any") && Architecture
.empty() == true)
783 if (Architecture
== Arch
)
786 if (Architecture
== "all" && Arch
== _config
->Find("APT::Architecture"))
790 iOffset
= Tags
.Offset();
795 // ListParser::LoadReleaseInfo - Load the release information /*{{{*/
796 // ---------------------------------------------------------------------
798 bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator
&FileI
,
799 FileFd
&File
, string component
)
801 // apt-secure does no longer download individual (per-section) Release
802 // file. to provide Component pinning we use the section name now
803 map_ptrloc
const storage
= WriteUniqString(component
);
804 FileI
->Component
= storage
;
806 pkgTagFile
TagFile(&File
, File
.Size());
807 pkgTagSection Section
;
808 if (_error
->PendingError() == true || TagFile
.Step(Section
) == false)
812 #define APT_INRELEASE(TAG, STORE) \
813 data = Section.FindS(TAG); \
814 if (data.empty() == false) \
816 map_ptrloc const storage = WriteUniqString(data); \
819 APT_INRELEASE("Suite", FileI
->Archive
)
820 APT_INRELEASE("Component", FileI
->Component
)
821 APT_INRELEASE("Version", FileI
->Version
)
822 APT_INRELEASE("Origin", FileI
->Origin
)
823 APT_INRELEASE("Codename", FileI
->Codename
)
824 APT_INRELEASE("Label", FileI
->Label
)
826 Section
.FindFlag("NotAutomatic", FileI
->Flags
, pkgCache::Flag::NotAutomatic
);
827 Section
.FindFlag("ButAutomaticUpgrades", FileI
->Flags
, pkgCache::Flag::ButAutomaticUpgrades
);
829 return !_error
->PendingError();
832 // ListParser::GetPrio - Convert the priority from a string /*{{{*/
833 // ---------------------------------------------------------------------
835 unsigned char debListParser::GetPrio(string Str
)
838 if (GrabWord(Str
,PrioList
,Out
) == false)
839 Out
= pkgCache::State::Extra
;