]>
git.saurik.com Git - apt.git/blob - apt-pkg/deb/deblistparser.cc
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 /*{{{*/
13 #include <apt-pkg/deblistparser.h>
14 #include <apt-pkg/error.h>
15 #include <apt-pkg/configuration.h>
16 #include <apt-pkg/aptconfiguration.h>
17 #include <apt-pkg/strutl.h>
18 #include <apt-pkg/crc-16.h>
19 #include <apt-pkg/md5.h>
20 #include <apt-pkg/macros.h>
26 static debListParser::WordList PrioList
[] = {{"important",pkgCache::State::Important
},
27 {"required",pkgCache::State::Required
},
28 {"standard",pkgCache::State::Standard
},
29 {"optional",pkgCache::State::Optional
},
30 {"extra",pkgCache::State::Extra
},
33 // ListParser::debListParser - Constructor /*{{{*/
34 // ---------------------------------------------------------------------
35 /* Provide an architecture and only this one and "all" will be accepted
36 in Step(), if no Architecture is given we will accept every arch
37 we would accept in general with checkArchitecture() */
38 debListParser::debListParser(FileFd
*File
, string
const &Arch
) : Tags(File
),
41 this->Arch
= _config
->Find("APT::Architecture");
42 Architectures
= APT::Configuration::getArchitectures();
43 MultiArchEnabled
= Architectures
.size() > 1;
46 // ListParser::UniqFindTagWrite - Find the tag and write a unq string /*{{{*/
47 // ---------------------------------------------------------------------
49 unsigned long debListParser::UniqFindTagWrite(const char *Tag
)
53 if (Section
.Find(Tag
,Start
,Stop
) == false)
55 return WriteUniqString(Start
,Stop
- Start
);
58 // ListParser::Package - Return the package name /*{{{*/
59 // ---------------------------------------------------------------------
60 /* This is to return the name of the package this section describes */
61 string
debListParser::Package() {
62 string
const Result
= Section
.FindS("Package");
63 if(unlikely(Result
.empty() == true))
64 _error
->Error("Encountered a section with no Package: header");
68 // ListParser::Architecture - Return the package arch /*{{{*/
69 // ---------------------------------------------------------------------
70 /* This will return the Architecture of the package this section describes */
71 string
debListParser::Architecture() {
72 std::string
const Arch
= Section
.FindS("Architecture");
73 if (Arch
.empty() == true)
74 return _config
->Find("APT::Architecture");
78 // ListParser::ArchitectureAll /*{{{*/
79 // ---------------------------------------------------------------------
81 bool debListParser::ArchitectureAll() {
82 return Section
.FindS("Architecture") == "all";
85 // ListParser::Version - Return the version string /*{{{*/
86 // ---------------------------------------------------------------------
87 /* This is to return the string describing the version in debian form,
88 epoch:upstream-release. If this returns the blank string then the
89 entry is assumed to only describe package properties */
90 string
debListParser::Version()
92 return Section
.FindS("Version");
95 // ListParser::NewVersion - Fill in the version structure /*{{{*/
96 // ---------------------------------------------------------------------
98 bool debListParser::NewVersion(pkgCache::VerIterator
&Ver
)
101 Ver
->Section
= UniqFindTagWrite("Section");
104 string
const MultiArch
= Section
.FindS("Multi-Arch");
105 if (MultiArch
.empty() == true)
106 Ver
->MultiArch
= pkgCache::Version::None
;
107 else if (MultiArch
== "same") {
109 if (ArchitectureAll() == true)
111 /* Arch all packages can't be Multi-Arch: same */
112 _error
->Warning("Architecture: all package '%s' can't be Multi-Arch: same",
113 Section
.FindS("Package").c_str());
114 Ver
->MultiArch
= pkgCache::Version::None
;
117 Ver
->MultiArch
= pkgCache::Version::Same
;
119 else if (MultiArch
== "foreign")
120 Ver
->MultiArch
= pkgCache::Version::Foreign
;
121 else if (MultiArch
== "allowed")
122 Ver
->MultiArch
= pkgCache::Version::Allowed
;
125 _error
->Warning("Unknown Multi-Arch type '%s' for package '%s'",
126 MultiArch
.c_str(), Section
.FindS("Package").c_str());
127 Ver
->MultiArch
= pkgCache::Version::None
;
130 if (ArchitectureAll() == true)
131 switch (Ver
->MultiArch
)
133 case pkgCache::Version::Foreign
: Ver
->MultiArch
= pkgCache::Version::AllForeign
; break;
134 case pkgCache::Version::Allowed
: Ver
->MultiArch
= pkgCache::Version::AllAllowed
; break;
135 default: Ver
->MultiArch
= pkgCache::Version::All
;
139 Ver
->Size
= Section
.FindULL("Size");
140 // Unpacked Size (in K)
141 Ver
->InstalledSize
= Section
.FindULL("Installed-Size");
142 Ver
->InstalledSize
*= 1024;
147 if (Section
.Find("Priority",Start
,Stop
) == true)
149 if (GrabWord(string(Start
,Stop
-Start
),PrioList
,Ver
->Priority
) == false)
150 Ver
->Priority
= pkgCache::State::Extra
;
153 if (ParseDepends(Ver
,"Depends",pkgCache::Dep::Depends
) == false)
155 if (ParseDepends(Ver
,"Pre-Depends",pkgCache::Dep::PreDepends
) == false)
157 if (ParseDepends(Ver
,"Suggests",pkgCache::Dep::Suggests
) == false)
159 if (ParseDepends(Ver
,"Recommends",pkgCache::Dep::Recommends
) == false)
161 if (ParseDepends(Ver
,"Conflicts",pkgCache::Dep::Conflicts
) == false)
163 if (ParseDepends(Ver
,"Breaks",pkgCache::Dep::DpkgBreaks
) == false)
165 if (ParseDepends(Ver
,"Replaces",pkgCache::Dep::Replaces
) == false)
167 if (ParseDepends(Ver
,"Enhances",pkgCache::Dep::Enhances
) == false)
171 if (ParseDepends(Ver
,"Optional",pkgCache::Dep::Suggests
) == false)
174 if (ParseProvides(Ver
) == false)
180 // ListParser::Description - Return the description string /*{{{*/
181 // ---------------------------------------------------------------------
182 /* This is to return the string describing the package in debian
183 form. If this returns the blank string then the entry is assumed to
184 only describe package properties */
185 string
debListParser::Description()
187 string
const lang
= DescriptionLanguage();
189 return Section
.FindS("Description");
191 return Section
.FindS(string("Description-").append(lang
).c_str());
194 // ListParser::DescriptionLanguage - Return the description lang string /*{{{*/
195 // ---------------------------------------------------------------------
196 /* This is to return the string describing the language of
197 description. If this returns the blank string then the entry is
198 assumed to describe original description. */
199 string
debListParser::DescriptionLanguage()
201 if (Section
.FindS("Description").empty() == false)
204 std::vector
<string
> const lang
= APT::Configuration::getLanguages(true);
205 for (std::vector
<string
>::const_iterator l
= lang
.begin();
206 l
!= lang
.end(); l
++)
207 if (Section
.FindS(string("Description-").append(*l
).c_str()).empty() == false)
213 // ListParser::Description - Return the description_md5 MD5SumValue /*{{{*/
214 // ---------------------------------------------------------------------
215 /* This is to return the md5 string to allow the check if it is the right
216 description. If no Description-md5 is found in the section it will be
219 MD5SumValue
debListParser::Description_md5()
221 string value
= Section
.FindS("Description-md5");
226 md5
.Add((Description() + "\n").c_str());
229 return MD5SumValue(value
);
232 // ListParser::UsePackage - Update a package structure /*{{{*/
233 // ---------------------------------------------------------------------
234 /* This is called to update the package with any new information
235 that might be found in the section */
236 bool debListParser::UsePackage(pkgCache::PkgIterator
&Pkg
,
237 pkgCache::VerIterator
&Ver
)
239 if (Pkg
->Section
== 0)
240 Pkg
->Section
= UniqFindTagWrite("Section");
242 // Packages which are not from the "native" arch doesn't get the essential flag
243 // in the default "native" mode - it is also possible to mark "all" or "none".
244 // The "installed" mode is handled by ParseStatus(), See #544481 and friends.
245 string
const static myArch
= _config
->Find("APT::Architecture");
246 string
const static essential
= _config
->Find("pkgCacheGen::Essential", "native");
247 if ((essential
== "native" && Pkg
->Arch
!= 0 && myArch
== Pkg
.Arch()) ||
249 if (Section
.FindFlag("Essential",Pkg
->Flags
,pkgCache::Flag::Essential
) == false)
251 if (Section
.FindFlag("Important",Pkg
->Flags
,pkgCache::Flag::Important
) == false)
254 if (strcmp(Pkg
.Name(),"apt") == 0)
255 Pkg
->Flags
|= pkgCache::Flag::Important
;
257 if (ParseStatus(Pkg
,Ver
) == false)
262 // ListParser::VersionHash - Compute a unique hash for this version /*{{{*/
263 // ---------------------------------------------------------------------
265 unsigned short debListParser::VersionHash()
267 const char *Sections
[] ={"Installed-Size",
275 unsigned long Result
= INIT_FCS
;
277 for (const char **I
= Sections
; *I
!= 0; I
++)
281 if (Section
.Find(*I
,Start
,End
) == false || End
- Start
>= (signed)sizeof(S
))
284 /* Strip out any spaces from the text, this undoes dpkgs reformatting
285 of certain fields. dpkg also has the rather interesting notion of
286 reformatting depends operators < -> <= */
288 for (; Start
!= End
; Start
++)
290 if (isspace(*Start
) == 0)
291 *J
++ = tolower_ascii(*Start
);
292 if (*Start
== '<' && Start
[1] != '<' && Start
[1] != '=')
294 if (*Start
== '>' && Start
[1] != '>' && Start
[1] != '=')
298 Result
= AddCRC16(Result
,S
,J
- S
);
304 // ListParser::ParseStatus - Parse the status field /*{{{*/
305 // ---------------------------------------------------------------------
306 /* Status lines are of the form,
307 Status: want flag status
308 want = unknown, install, hold, deinstall, purge
309 flag = ok, reinstreq, hold, hold-reinstreq
310 status = not-installed, unpacked, half-configured,
311 half-installed, config-files, post-inst-failed,
312 removal-failed, installed
314 Some of the above are obsolete (I think?) flag = hold-* and
315 status = post-inst-failed, removal-failed at least.
317 bool debListParser::ParseStatus(pkgCache::PkgIterator
&Pkg
,
318 pkgCache::VerIterator
&Ver
)
322 if (Section
.Find("Status",Start
,Stop
) == false)
325 // UsePackage() is responsible for setting the flag in the default case
326 bool const static essential
= _config
->Find("pkgCacheGen::Essential", "") == "installed";
327 if (essential
== true &&
328 Section
.FindFlag("Essential",Pkg
->Flags
,pkgCache::Flag::Essential
) == false)
331 // Isolate the first word
332 const char *I
= Start
;
333 for(; I
< Stop
&& *I
!= ' '; I
++);
334 if (I
>= Stop
|| *I
!= ' ')
335 return _error
->Error("Malformed Status line");
337 // Process the want field
338 WordList WantList
[] = {{"unknown",pkgCache::State::Unknown
},
339 {"install",pkgCache::State::Install
},
340 {"hold",pkgCache::State::Hold
},
341 {"deinstall",pkgCache::State::DeInstall
},
342 {"purge",pkgCache::State::Purge
},
344 if (GrabWord(string(Start
,I
-Start
),WantList
,Pkg
->SelectedState
) == false)
345 return _error
->Error("Malformed 1st word in the Status line");
347 // Isloate the next word
350 for(; I
< Stop
&& *I
!= ' '; I
++);
351 if (I
>= Stop
|| *I
!= ' ')
352 return _error
->Error("Malformed status line, no 2nd word");
354 // Process the flag field
355 WordList FlagList
[] = {{"ok",pkgCache::State::Ok
},
356 {"reinstreq",pkgCache::State::ReInstReq
},
357 {"hold",pkgCache::State::HoldInst
},
358 {"hold-reinstreq",pkgCache::State::HoldReInstReq
},
360 if (GrabWord(string(Start
,I
-Start
),FlagList
,Pkg
->InstState
) == false)
361 return _error
->Error("Malformed 2nd word in the Status line");
363 // Isloate the last word
366 for(; I
< Stop
&& *I
!= ' '; I
++);
368 return _error
->Error("Malformed Status line, no 3rd word");
370 // Process the flag field
371 WordList StatusList
[] = {{"not-installed",pkgCache::State::NotInstalled
},
372 {"unpacked",pkgCache::State::UnPacked
},
373 {"half-configured",pkgCache::State::HalfConfigured
},
374 {"installed",pkgCache::State::Installed
},
375 {"half-installed",pkgCache::State::HalfInstalled
},
376 {"config-files",pkgCache::State::ConfigFiles
},
377 {"triggers-awaited",pkgCache::State::TriggersAwaited
},
378 {"triggers-pending",pkgCache::State::TriggersPending
},
379 {"post-inst-failed",pkgCache::State::HalfConfigured
},
380 {"removal-failed",pkgCache::State::HalfInstalled
},
382 if (GrabWord(string(Start
,I
-Start
),StatusList
,Pkg
->CurrentState
) == false)
383 return _error
->Error("Malformed 3rd word in the Status line");
385 /* A Status line marks the package as indicating the current
386 version as well. Only if it is actually installed.. Otherwise
387 the interesting dpkg handling of the status file creates bogus
389 if (!(Pkg
->CurrentState
== pkgCache::State::NotInstalled
||
390 Pkg
->CurrentState
== pkgCache::State::ConfigFiles
))
392 if (Ver
.end() == true)
393 _error
->Warning("Encountered status field in a non-version description");
395 Pkg
->CurrentVer
= Ver
.Index();
401 const char *debListParser::ConvertRelation(const char *I
,unsigned int &Op
)
403 // Determine the operator
411 Op
= pkgCache::Dep::LessEq
;
418 Op
= pkgCache::Dep::Less
;
422 // < is the same as <= and << is really Cs < for some reason
423 Op
= pkgCache::Dep::LessEq
;
431 Op
= pkgCache::Dep::GreaterEq
;
438 Op
= pkgCache::Dep::Greater
;
442 // > is the same as >= and >> is really Cs > for some reason
443 Op
= pkgCache::Dep::GreaterEq
;
447 Op
= pkgCache::Dep::Equals
;
451 // HACK around bad package definitions
453 Op
= pkgCache::Dep::Equals
;
462 * The complete architecture, consisting of <kernel>-<cpu>.
464 static string
CompleteArch(std::string
const &arch
) {
465 if (arch
== "armel") return "linux-arm";
466 if (arch
== "armhf") return "linux-arm";
467 if (arch
== "lpia") return "linux-i386";
468 if (arch
== "powerpcspe") return "linux-powerpc";
469 if (arch
== "uclibc-linux-armel") return "linux-arm";
470 if (arch
== "uclinux-armel") return "uclinux-arm";
472 return (arch
.find("-") != string::npos
) ? arch
: "linux-" + arch
;
475 // ListParser::ParseDepends - Parse a dependency element /*{{{*/
476 // ---------------------------------------------------------------------
477 /* This parses the dependency elements out of a standard string in place,
479 const char *debListParser::ParseDepends(const char *Start
,const char *Stop
,
480 string
&Package
,string
&Ver
,
481 unsigned int &Op
, bool const &ParseArchFlags
,
482 bool const &StripMultiArch
)
484 // Strip off leading space
485 for (;Start
!= Stop
&& isspace(*Start
) != 0; Start
++);
487 // Parse off the package name
488 const char *I
= Start
;
489 for (;I
!= Stop
&& isspace(*I
) == 0 && *I
!= '(' && *I
!= ')' &&
490 *I
!= ',' && *I
!= '|' && *I
!= '[' && *I
!= ']'; I
++);
493 if (I
!= Stop
&& *I
== ')')
499 // Stash the package name
500 Package
.assign(Start
,I
- Start
);
502 // We don't want to confuse library users which can't handle MultiArch
503 string
const arch
= _config
->Find("APT::Architecture");
504 if (StripMultiArch
== true) {
505 size_t const found
= Package
.rfind(':');
506 if (found
!= string::npos
&&
507 (strcmp(Package
.c_str() + found
, ":any") == 0 ||
508 strcmp(Package
.c_str() + found
, ":native") == 0 ||
509 strcmp(Package
.c_str() + found
+ 1, arch
.c_str()) == 0))
510 Package
= Package
.substr(0,found
);
513 // Skip white space to the '('
514 for (;I
!= Stop
&& isspace(*I
) != 0 ; I
++);
517 if (I
!= Stop
&& *I
== '(')
520 for (I
++; I
!= Stop
&& isspace(*I
) != 0 ; I
++);
523 I
= ConvertRelation(I
,Op
);
526 for (;I
!= Stop
&& isspace(*I
) != 0; I
++);
528 for (;I
!= Stop
&& *I
!= ')'; I
++);
529 if (I
== Stop
|| Start
== I
)
532 // Skip trailing whitespace
534 for (; End
> Start
&& isspace(End
[-1]); End
--);
536 Ver
.assign(Start
,End
-Start
);
542 Op
= pkgCache::Dep::NoOp
;
546 for (;I
!= Stop
&& isspace(*I
) != 0; I
++);
548 if (ParseArchFlags
== true)
550 string completeArch
= CompleteArch(arch
);
552 // Parse an architecture
553 if (I
!= Stop
&& *I
== '[')
562 bool NegArch
= false;
565 // look for whitespace or ending ']'
566 while (End
!= Stop
&& !isspace(*End
) && *End
!= ']')
578 if (stringcmp(arch
,I
,End
) == 0) {
581 std::string wildcard
= SubstVar(string(I
, End
), "any", "*");
582 if (fnmatch(wildcard
.c_str(), completeArch
.c_str(), 0) == 0)
592 for (;I
!= Stop
&& isspace(*I
) != 0; I
++);
599 Package
= ""; /* not for this arch */
603 for (;I
!= Stop
&& isspace(*I
) != 0; I
++);
606 if (I
!= Stop
&& *I
== '|')
607 Op
|= pkgCache::Dep::Or
;
609 if (I
== Stop
|| *I
== ',' || *I
== '|')
612 for (I
++; I
!= Stop
&& isspace(*I
) != 0; I
++);
619 // ListParser::ParseDepends - Parse a dependency list /*{{{*/
620 // ---------------------------------------------------------------------
621 /* This is the higher level depends parser. It takes a tag and generates
622 a complete depends tree for the given version. */
623 bool debListParser::ParseDepends(pkgCache::VerIterator
&Ver
,
624 const char *Tag
,unsigned int Type
)
628 if (Section
.Find(Tag
,Start
,Stop
) == false)
632 string
const pkgArch
= Ver
.Arch();
638 Start
= ParseDepends(Start
,Stop
,Package
,Version
,Op
,false,!MultiArchEnabled
);
640 return _error
->Error("Problem parsing dependency %s",Tag
);
642 if (MultiArchEnabled
== true &&
643 (Type
== pkgCache::Dep::Conflicts
||
644 Type
== pkgCache::Dep::DpkgBreaks
||
645 Type
== pkgCache::Dep::Replaces
))
647 for (std::vector
<std::string
>::const_iterator a
= Architectures
.begin();
648 a
!= Architectures
.end(); ++a
)
649 if (NewDepends(Ver
,Package
,*a
,Version
,Op
,Type
) == false)
652 else if (NewDepends(Ver
,Package
,pkgArch
,Version
,Op
,Type
) == false)
660 // ListParser::ParseProvides - Parse the provides list /*{{{*/
661 // ---------------------------------------------------------------------
663 bool debListParser::ParseProvides(pkgCache::VerIterator
&Ver
)
667 if (Section
.Find("Provides",Start
,Stop
) == true)
671 string
const Arch
= Ver
.Arch();
676 Start
= ParseDepends(Start
,Stop
,Package
,Version
,Op
);
678 return _error
->Error("Problem parsing Provides line");
679 if (Op
!= pkgCache::Dep::NoOp
) {
680 _error
->Warning("Ignoring Provides line with DepCompareOp for package %s", Package
.c_str());
682 if (NewProvides(Ver
, Package
, Arch
, Version
) == false)
691 if (MultiArchEnabled
== false)
693 else if (Ver
->MultiArch
== pkgCache::Version::Allowed
|| Ver
->MultiArch
== pkgCache::Version::AllAllowed
)
695 string
const Package
= string(Ver
.ParentPkg().Name()).append(":").append("any");
696 return NewProvidesAllArch(Ver
, Package
, Ver
.VerStr());
698 else if (Ver
->MultiArch
== pkgCache::Version::Foreign
|| Ver
->MultiArch
== pkgCache::Version::AllForeign
)
699 return NewProvidesAllArch(Ver
, Ver
.ParentPkg().Name(), Ver
.VerStr());
704 // ListParser::NewProvides - add provides for all architectures /*{{{*/
705 bool debListParser::NewProvidesAllArch(pkgCache::VerIterator
&Ver
, string
const &Package
,
706 string
const &Version
) {
707 for (std::vector
<string
>::const_iterator a
= Architectures
.begin();
708 a
!= Architectures
.end(); ++a
)
710 if (NewProvides(Ver
, Package
, *a
, Version
) == false)
716 // ListParser::GrabWord - Matches a word and returns /*{{{*/
717 // ---------------------------------------------------------------------
718 /* Looks for a word in a list of words - for ParseStatus */
719 bool debListParser::GrabWord(string Word
,WordList
*List
,unsigned char &Out
)
721 for (unsigned int C
= 0; List
[C
].Str
!= 0; C
++)
723 if (strcasecmp(Word
.c_str(),List
[C
].Str
) == 0)
732 // ListParser::Step - Move to the next section in the file /*{{{*/
733 // ---------------------------------------------------------------------
734 /* This has to be carefull to only process the correct architecture */
735 bool debListParser::Step()
737 iOffset
= Tags
.Offset();
738 while (Tags
.Step(Section
) == true)
740 /* See if this is the correct Architecture, if it isn't then we
741 drop the whole section. A missing arch tag only happens (in theory)
742 inside the Status file, so that is a positive return */
743 string
const Architecture
= Section
.FindS("Architecture");
744 if (Architecture
.empty() == true)
747 if (Arch
.empty() == true || Arch
== "any" || MultiArchEnabled
== false)
749 if (APT::Configuration::checkArchitecture(Architecture
) == true)
754 if (Architecture
== Arch
)
757 if (Architecture
== "all" && Arch
== _config
->Find("APT::Architecture"))
761 iOffset
= Tags
.Offset();
766 // ListParser::LoadReleaseInfo - Load the release information /*{{{*/
767 // ---------------------------------------------------------------------
769 bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator
&FileI
,
770 FileFd
&File
, string component
)
772 // apt-secure does no longer download individual (per-section) Release
773 // file. to provide Component pinning we use the section name now
774 FileI
->Component
= WriteUniqString(component
);
776 FILE* release
= fdopen(dup(File
.Fd()), "r");
781 bool gpgClose
= false;
782 while (fgets(buffer
, sizeof(buffer
), release
) != NULL
)
787 for (; buffer
[len
] == '\r' && buffer
[len
] == '\n'; ++len
);
788 if (buffer
[len
] == '\0')
791 // only evalute the first GPG section
792 if (strncmp("-----", buffer
, 5) == 0)
794 if (gpgClose
== true)
800 // seperate the tag from the data
801 for (; buffer
[len
] != ':' && buffer
[len
] != '\0'; ++len
);
802 if (buffer
[len
] == '\0')
804 char* dataStart
= buffer
+ len
;
805 for (++dataStart
; *dataStart
== ' '; ++dataStart
);
806 char* dataEnd
= dataStart
;
807 for (++dataEnd
; *dataEnd
!= '\0'; ++dataEnd
);
809 // which datastorage need to be updated
810 map_ptrloc
* writeTo
= NULL
;
811 if (buffer
[0] == ' ')
813 #define APT_PARSER_WRITETO(X, Y) else if (strncmp(Y, buffer, len) == 0) writeTo = &X;
814 APT_PARSER_WRITETO(FileI
->Archive
, "Suite")
815 APT_PARSER_WRITETO(FileI
->Component
, "Component")
816 APT_PARSER_WRITETO(FileI
->Version
, "Version")
817 APT_PARSER_WRITETO(FileI
->Origin
, "Origin")
818 APT_PARSER_WRITETO(FileI
->Codename
, "Codename")
819 APT_PARSER_WRITETO(FileI
->Label
, "Label")
820 #undef APT_PARSER_WRITETO
821 #define APT_PARSER_FLAGIT(X) else if (strncmp(#X, buffer, len) == 0) \
822 pkgTagSection::FindFlag(FileI->Flags, pkgCache::Flag:: X, dataStart, dataEnd-1);
823 APT_PARSER_FLAGIT(NotAutomatic
)
824 APT_PARSER_FLAGIT(ButAutomaticUpgrades
)
825 #undef APT_PARSER_FLAGIT
827 // load all data from the line and save it
830 data
.append(dataStart
, dataEnd
);
831 if (sizeof(buffer
) - 1 == (dataEnd
- buffer
))
833 while (fgets(buffer
, sizeof(buffer
), release
) != NULL
)
837 if (strlen(buffer
) != sizeof(buffer
) - 1)
843 // remove spaces and stuff from the end of the data line
844 for (std::string::reverse_iterator s
= data
.rbegin();
845 s
!= data
.rend(); ++s
)
847 if (*s
!= '\r' && *s
!= '\n' && *s
!= ' ')
851 *writeTo
= WriteUniqString(data
);
856 return !_error
->PendingError();
859 // ListParser::GetPrio - Convert the priority from a string /*{{{*/
860 // ---------------------------------------------------------------------
862 unsigned char debListParser::GetPrio(string Str
)
865 if (GrabWord(Str
,PrioList
,Out
) == false)
866 Out
= pkgCache::State::Extra
;