]>
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 /*{{{*/
15 #include <apt-pkg/deblistparser.h>
16 #include <apt-pkg/error.h>
17 #include <apt-pkg/configuration.h>
18 #include <apt-pkg/aptconfiguration.h>
19 #include <apt-pkg/strutl.h>
20 #include <apt-pkg/fileutl.h>
21 #include <apt-pkg/crc-16.h>
22 #include <apt-pkg/md5.h>
23 #include <apt-pkg/macros.h>
31 static debListParser::WordList PrioList
[] = {{"important",pkgCache::State::Important
},
32 {"required",pkgCache::State::Required
},
33 {"standard",pkgCache::State::Standard
},
34 {"optional",pkgCache::State::Optional
},
35 {"extra",pkgCache::State::Extra
},
38 // ListParser::debListParser - Constructor /*{{{*/
39 // ---------------------------------------------------------------------
40 /* Provide an architecture and only this one and "all" will be accepted
41 in Step(), if no Architecture is given we will accept every arch
42 we would accept in general with checkArchitecture() */
43 debListParser::debListParser(FileFd
*File
, string
const &Arch
) : Tags(File
),
46 this->Arch
= _config
->Find("APT::Architecture");
47 Architectures
= APT::Configuration::getArchitectures();
48 MultiArchEnabled
= Architectures
.size() > 1;
51 // ListParser::UniqFindTagWrite - Find the tag and write a unq string /*{{{*/
52 // ---------------------------------------------------------------------
54 unsigned long debListParser::UniqFindTagWrite(const char *Tag
)
58 if (Section
.Find(Tag
,Start
,Stop
) == false)
60 return WriteUniqString(Start
,Stop
- Start
);
63 // ListParser::Package - Return the package name /*{{{*/
64 // ---------------------------------------------------------------------
65 /* This is to return the name of the package this section describes */
66 string
debListParser::Package() {
67 string
const Result
= Section
.FindS("Package");
68 if(unlikely(Result
.empty() == true))
69 _error
->Error("Encountered a section with no Package: header");
73 // ListParser::Architecture - Return the package arch /*{{{*/
74 // ---------------------------------------------------------------------
75 /* This will return the Architecture of the package this section describes */
76 string
debListParser::Architecture() {
77 return Section
.FindS("Architecture");
80 // ListParser::ArchitectureAll /*{{{*/
81 // ---------------------------------------------------------------------
83 bool debListParser::ArchitectureAll() {
84 return Section
.FindS("Architecture") == "all";
87 // ListParser::Version - Return the version string /*{{{*/
88 // ---------------------------------------------------------------------
89 /* This is to return the string describing the version in debian form,
90 epoch:upstream-release. If this returns the blank string then the
91 entry is assumed to only describe package properties */
92 string
debListParser::Version()
94 return Section
.FindS("Version");
97 // ListParser::NewVersion - Fill in the version structure /*{{{*/
98 // ---------------------------------------------------------------------
100 bool debListParser::NewVersion(pkgCache::VerIterator
&Ver
)
103 Ver
->Section
= UniqFindTagWrite("Section");
106 string
const MultiArch
= Section
.FindS("Multi-Arch");
107 if (MultiArch
.empty() == true)
108 Ver
->MultiArch
= pkgCache::Version::None
;
109 else if (MultiArch
== "same") {
111 if (ArchitectureAll() == true)
113 /* Arch all packages can't be Multi-Arch: same */
114 _error
->Warning("Architecture: all package '%s' can't be Multi-Arch: same",
115 Section
.FindS("Package").c_str());
116 Ver
->MultiArch
= pkgCache::Version::None
;
119 Ver
->MultiArch
= pkgCache::Version::Same
;
121 else if (MultiArch
== "foreign")
122 Ver
->MultiArch
= pkgCache::Version::Foreign
;
123 else if (MultiArch
== "allowed")
124 Ver
->MultiArch
= pkgCache::Version::Allowed
;
127 _error
->Warning("Unknown Multi-Arch type '%s' for package '%s'",
128 MultiArch
.c_str(), Section
.FindS("Package").c_str());
129 Ver
->MultiArch
= pkgCache::Version::None
;
132 if (ArchitectureAll() == true)
133 Ver
->MultiArch
|= pkgCache::Version::All
;
136 Ver
->Size
= Section
.FindULL("Size");
137 // Unpacked Size (in K)
138 Ver
->InstalledSize
= Section
.FindULL("Installed-Size");
139 Ver
->InstalledSize
*= 1024;
144 if (Section
.Find("Priority",Start
,Stop
) == true)
146 if (GrabWord(string(Start
,Stop
-Start
),PrioList
,Ver
->Priority
) == false)
147 Ver
->Priority
= pkgCache::State::Extra
;
150 if (ParseDepends(Ver
,"Depends",pkgCache::Dep::Depends
) == false)
152 if (ParseDepends(Ver
,"Pre-Depends",pkgCache::Dep::PreDepends
) == false)
154 if (ParseDepends(Ver
,"Suggests",pkgCache::Dep::Suggests
) == false)
156 if (ParseDepends(Ver
,"Recommends",pkgCache::Dep::Recommends
) == false)
158 if (ParseDepends(Ver
,"Conflicts",pkgCache::Dep::Conflicts
) == false)
160 if (ParseDepends(Ver
,"Breaks",pkgCache::Dep::DpkgBreaks
) == false)
162 if (ParseDepends(Ver
,"Replaces",pkgCache::Dep::Replaces
) == false)
164 if (ParseDepends(Ver
,"Enhances",pkgCache::Dep::Enhances
) == false)
168 if (ParseDepends(Ver
,"Optional",pkgCache::Dep::Suggests
) == false)
171 if (ParseProvides(Ver
) == false)
177 // ListParser::Description - Return the description string /*{{{*/
178 // ---------------------------------------------------------------------
179 /* This is to return the string describing the package in debian
180 form. If this returns the blank string then the entry is assumed to
181 only describe package properties */
182 string
debListParser::Description()
184 string
const lang
= DescriptionLanguage();
186 return Section
.FindS("Description");
188 return Section
.FindS(string("Description-").append(lang
).c_str());
191 // ListParser::DescriptionLanguage - Return the description lang string /*{{{*/
192 // ---------------------------------------------------------------------
193 /* This is to return the string describing the language of
194 description. If this returns the blank string then the entry is
195 assumed to describe original description. */
196 string
debListParser::DescriptionLanguage()
198 if (Section
.FindS("Description").empty() == false)
201 std::vector
<string
> const lang
= APT::Configuration::getLanguages(true);
202 for (std::vector
<string
>::const_iterator l
= lang
.begin();
203 l
!= lang
.end(); ++l
)
204 if (Section
.FindS(string("Description-").append(*l
).c_str()).empty() == false)
210 // ListParser::Description - Return the description_md5 MD5SumValue /*{{{*/
211 // ---------------------------------------------------------------------
212 /* This is to return the md5 string to allow the check if it is the right
213 description. If no Description-md5 is found in the section it will be
216 MD5SumValue
debListParser::Description_md5()
218 string value
= Section
.FindS("Description-md5");
223 md5
.Add((Description() + "\n").c_str());
226 return MD5SumValue(value
);
229 // ListParser::UsePackage - Update a package structure /*{{{*/
230 // ---------------------------------------------------------------------
231 /* This is called to update the package with any new information
232 that might be found in the section */
233 bool debListParser::UsePackage(pkgCache::PkgIterator
&Pkg
,
234 pkgCache::VerIterator
&Ver
)
236 if (Pkg
->Section
== 0)
237 Pkg
->Section
= UniqFindTagWrite("Section");
239 // Packages which are not from the "native" arch doesn't get the essential flag
240 // in the default "native" mode - it is also possible to mark "all" or "none".
241 // The "installed" mode is handled by ParseStatus(), See #544481 and friends.
242 string
const static myArch
= _config
->Find("APT::Architecture");
243 string
const static essential
= _config
->Find("pkgCacheGen::Essential", "native");
244 if ((essential
== "native" && Pkg
->Arch
!= 0 && myArch
== Pkg
.Arch()) ||
246 if (Section
.FindFlag("Essential",Pkg
->Flags
,pkgCache::Flag::Essential
) == false)
248 if (Section
.FindFlag("Important",Pkg
->Flags
,pkgCache::Flag::Important
) == false)
251 if (strcmp(Pkg
.Name(),"apt") == 0)
252 Pkg
->Flags
|= pkgCache::Flag::Essential
| pkgCache::Flag::Important
;
254 if (ParseStatus(Pkg
,Ver
) == false)
259 // ListParser::VersionHash - Compute a unique hash for this version /*{{{*/
260 // ---------------------------------------------------------------------
262 unsigned short debListParser::VersionHash()
264 const char *Sections
[] ={"Installed-Size",
272 unsigned long Result
= INIT_FCS
;
274 for (const char **I
= Sections
; *I
!= 0; I
++)
278 if (Section
.Find(*I
,Start
,End
) == false || End
- Start
>= (signed)sizeof(S
))
281 /* Strip out any spaces from the text, this undoes dpkgs reformatting
282 of certain fields. dpkg also has the rather interesting notion of
283 reformatting depends operators < -> <= */
285 for (; Start
!= End
; Start
++)
287 if (isspace(*Start
) == 0)
288 *J
++ = tolower_ascii(*Start
);
289 if (*Start
== '<' && Start
[1] != '<' && Start
[1] != '=')
291 if (*Start
== '>' && Start
[1] != '>' && Start
[1] != '=')
295 Result
= AddCRC16(Result
,S
,J
- S
);
301 // ListParser::ParseStatus - Parse the status field /*{{{*/
302 // ---------------------------------------------------------------------
303 /* Status lines are of the form,
304 Status: want flag status
305 want = unknown, install, hold, deinstall, purge
306 flag = ok, reinstreq, hold, hold-reinstreq
307 status = not-installed, unpacked, half-configured,
308 half-installed, config-files, post-inst-failed,
309 removal-failed, installed
311 Some of the above are obsolete (I think?) flag = hold-* and
312 status = post-inst-failed, removal-failed at least.
314 bool debListParser::ParseStatus(pkgCache::PkgIterator
&Pkg
,
315 pkgCache::VerIterator
&Ver
)
319 if (Section
.Find("Status",Start
,Stop
) == false)
322 // UsePackage() is responsible for setting the flag in the default case
323 bool const static essential
= _config
->Find("pkgCacheGen::Essential", "") == "installed";
324 if (essential
== true &&
325 Section
.FindFlag("Essential",Pkg
->Flags
,pkgCache::Flag::Essential
) == false)
328 // Isolate the first word
329 const char *I
= Start
;
330 for(; I
< Stop
&& *I
!= ' '; I
++);
331 if (I
>= Stop
|| *I
!= ' ')
332 return _error
->Error("Malformed Status line");
334 // Process the want field
335 WordList WantList
[] = {{"unknown",pkgCache::State::Unknown
},
336 {"install",pkgCache::State::Install
},
337 {"hold",pkgCache::State::Hold
},
338 {"deinstall",pkgCache::State::DeInstall
},
339 {"purge",pkgCache::State::Purge
},
341 if (GrabWord(string(Start
,I
-Start
),WantList
,Pkg
->SelectedState
) == false)
342 return _error
->Error("Malformed 1st word in the Status line");
344 // Isloate the next word
347 for(; I
< Stop
&& *I
!= ' '; I
++);
348 if (I
>= Stop
|| *I
!= ' ')
349 return _error
->Error("Malformed status line, no 2nd word");
351 // Process the flag field
352 WordList FlagList
[] = {{"ok",pkgCache::State::Ok
},
353 {"reinstreq",pkgCache::State::ReInstReq
},
354 {"hold",pkgCache::State::HoldInst
},
355 {"hold-reinstreq",pkgCache::State::HoldReInstReq
},
357 if (GrabWord(string(Start
,I
-Start
),FlagList
,Pkg
->InstState
) == false)
358 return _error
->Error("Malformed 2nd word in the Status line");
360 // Isloate the last word
363 for(; I
< Stop
&& *I
!= ' '; I
++);
365 return _error
->Error("Malformed Status line, no 3rd word");
367 // Process the flag field
368 WordList StatusList
[] = {{"not-installed",pkgCache::State::NotInstalled
},
369 {"unpacked",pkgCache::State::UnPacked
},
370 {"half-configured",pkgCache::State::HalfConfigured
},
371 {"installed",pkgCache::State::Installed
},
372 {"half-installed",pkgCache::State::HalfInstalled
},
373 {"config-files",pkgCache::State::ConfigFiles
},
374 {"triggers-awaited",pkgCache::State::TriggersAwaited
},
375 {"triggers-pending",pkgCache::State::TriggersPending
},
376 {"post-inst-failed",pkgCache::State::HalfConfigured
},
377 {"removal-failed",pkgCache::State::HalfInstalled
},
379 if (GrabWord(string(Start
,I
-Start
),StatusList
,Pkg
->CurrentState
) == false)
380 return _error
->Error("Malformed 3rd word in the Status line");
382 /* A Status line marks the package as indicating the current
383 version as well. Only if it is actually installed.. Otherwise
384 the interesting dpkg handling of the status file creates bogus
386 if (!(Pkg
->CurrentState
== pkgCache::State::NotInstalled
||
387 Pkg
->CurrentState
== pkgCache::State::ConfigFiles
))
389 if (Ver
.end() == true)
390 _error
->Warning("Encountered status field in a non-version description");
392 Pkg
->CurrentVer
= Ver
.Index();
398 const char *debListParser::ConvertRelation(const char *I
,unsigned int &Op
)
400 // Determine the operator
408 Op
= pkgCache::Dep::LessEq
;
415 Op
= pkgCache::Dep::Less
;
419 // < is the same as <= and << is really Cs < for some reason
420 Op
= pkgCache::Dep::LessEq
;
428 Op
= pkgCache::Dep::GreaterEq
;
435 Op
= pkgCache::Dep::Greater
;
439 // > is the same as >= and >> is really Cs > for some reason
440 Op
= pkgCache::Dep::GreaterEq
;
444 Op
= pkgCache::Dep::Equals
;
448 // HACK around bad package definitions
450 Op
= pkgCache::Dep::Equals
;
459 * The complete architecture, consisting of <kernel>-<cpu>.
461 static string
CompleteArch(std::string
const &arch
) {
462 if (arch
== "armel") return "linux-arm";
463 if (arch
== "armhf") return "linux-arm";
464 if (arch
== "lpia") return "linux-i386";
465 if (arch
== "powerpcspe") return "linux-powerpc";
466 if (arch
== "uclibc-linux-armel") return "linux-arm";
467 if (arch
== "uclinux-armel") return "uclinux-arm";
469 return (arch
.find("-") != string::npos
) ? arch
: "linux-" + arch
;
472 // ListParser::ParseDepends - Parse a dependency element /*{{{*/
473 // ---------------------------------------------------------------------
474 /* This parses the dependency elements out of a standard string in place,
476 const char *debListParser::ParseDepends(const char *Start
,const char *Stop
,
477 string
&Package
,string
&Ver
,
478 unsigned int &Op
, bool const &ParseArchFlags
,
479 bool const &StripMultiArch
)
481 // Strip off leading space
482 for (;Start
!= Stop
&& isspace(*Start
) != 0; Start
++);
484 // Parse off the package name
485 const char *I
= Start
;
486 for (;I
!= Stop
&& isspace(*I
) == 0 && *I
!= '(' && *I
!= ')' &&
487 *I
!= ',' && *I
!= '|' && *I
!= '[' && *I
!= ']'; I
++);
490 if (I
!= Stop
&& *I
== ')')
496 // Stash the package name
497 Package
.assign(Start
,I
- Start
);
499 // We don't want to confuse library users which can't handle MultiArch
500 string
const arch
= _config
->Find("APT::Architecture");
501 if (StripMultiArch
== true) {
502 size_t const found
= Package
.rfind(':');
503 if (found
!= string::npos
&&
504 (strcmp(Package
.c_str() + found
, ":any") == 0 ||
505 strcmp(Package
.c_str() + found
, ":native") == 0 ||
506 strcmp(Package
.c_str() + found
+ 1, arch
.c_str()) == 0))
507 Package
= Package
.substr(0,found
);
510 // Skip white space to the '('
511 for (;I
!= Stop
&& isspace(*I
) != 0 ; I
++);
514 if (I
!= Stop
&& *I
== '(')
517 for (I
++; I
!= Stop
&& isspace(*I
) != 0 ; I
++);
520 I
= ConvertRelation(I
,Op
);
523 for (;I
!= Stop
&& isspace(*I
) != 0; I
++);
525 I
= (const char*) memchr(I
, ')', Stop
- I
);
526 if (I
== NULL
|| Start
== I
)
529 // Skip trailing whitespace
531 for (; End
> Start
&& isspace(End
[-1]); End
--);
533 Ver
.assign(Start
,End
-Start
);
539 Op
= pkgCache::Dep::NoOp
;
543 for (;I
!= Stop
&& isspace(*I
) != 0; I
++);
545 if (ParseArchFlags
== true)
547 string completeArch
= CompleteArch(arch
);
549 // Parse an architecture
550 if (I
!= Stop
&& *I
== '[')
559 bool NegArch
= false;
562 // look for whitespace or ending ']'
563 while (End
!= Stop
&& !isspace(*End
) && *End
!= ']')
575 if (stringcmp(arch
,I
,End
) == 0) {
578 std::string wildcard
= SubstVar(string(I
, End
), "any", "*");
579 if (fnmatch(wildcard
.c_str(), completeArch
.c_str(), 0) == 0)
589 for (;I
!= Stop
&& isspace(*I
) != 0; I
++);
596 Package
= ""; /* not for this arch */
600 for (;I
!= Stop
&& isspace(*I
) != 0; I
++);
603 if (I
!= Stop
&& *I
== '|')
604 Op
|= pkgCache::Dep::Or
;
606 if (I
== Stop
|| *I
== ',' || *I
== '|')
609 for (I
++; I
!= Stop
&& isspace(*I
) != 0; I
++);
616 // ListParser::ParseDepends - Parse a dependency list /*{{{*/
617 // ---------------------------------------------------------------------
618 /* This is the higher level depends parser. It takes a tag and generates
619 a complete depends tree for the given version. */
620 bool debListParser::ParseDepends(pkgCache::VerIterator
&Ver
,
621 const char *Tag
,unsigned int Type
)
625 if (Section
.Find(Tag
,Start
,Stop
) == false)
629 string
const pkgArch
= Ver
.Arch();
635 Start
= ParseDepends(Start
,Stop
,Package
,Version
,Op
,false,!MultiArchEnabled
);
637 return _error
->Error("Problem parsing dependency %s",Tag
);
639 if (MultiArchEnabled
== true &&
640 (Type
== pkgCache::Dep::Conflicts
||
641 Type
== pkgCache::Dep::DpkgBreaks
||
642 Type
== pkgCache::Dep::Replaces
))
644 for (std::vector
<std::string
>::const_iterator a
= Architectures
.begin();
645 a
!= Architectures
.end(); ++a
)
646 if (NewDepends(Ver
,Package
,*a
,Version
,Op
,Type
) == false)
649 else if (NewDepends(Ver
,Package
,pkgArch
,Version
,Op
,Type
) == false)
657 // ListParser::ParseProvides - Parse the provides list /*{{{*/
658 // ---------------------------------------------------------------------
660 bool debListParser::ParseProvides(pkgCache::VerIterator
&Ver
)
664 if (Section
.Find("Provides",Start
,Stop
) == true)
668 string
const Arch
= Ver
.Arch();
673 Start
= ParseDepends(Start
,Stop
,Package
,Version
,Op
);
675 return _error
->Error("Problem parsing Provides line");
676 if (Op
!= pkgCache::Dep::NoOp
) {
677 _error
->Warning("Ignoring Provides line with DepCompareOp for package %s", Package
.c_str());
678 } else if ((Ver
->MultiArch
& pkgCache::Version::Foreign
) == pkgCache::Version::Foreign
) {
679 if (NewProvidesAllArch(Ver
, Package
, Version
) == false)
682 if (NewProvides(Ver
, Package
, Arch
, Version
) == false)
691 if (MultiArchEnabled
== false)
693 else if ((Ver
->MultiArch
& pkgCache::Version::Allowed
) == pkgCache::Version::Allowed
)
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
) == pkgCache::Version::Foreign
)
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 // FIXME: Code depends on the fact that Release files aren't compressed
777 FILE* release
= fdopen(dup(File
.Fd()), "r");
782 bool gpgClose
= false;
783 while (fgets(buffer
, sizeof(buffer
), release
) != NULL
)
788 for (; buffer
[len
] == '\r' && buffer
[len
] == '\n'; ++len
)
791 if (buffer
[len
] == '\0')
794 // only evalute the first GPG section
795 if (strncmp("-----", buffer
, 5) == 0)
797 if (gpgClose
== true)
803 // seperate the tag from the data
804 const char* dataStart
= strchr(buffer
+ len
, ':');
805 if (dataStart
== NULL
)
807 len
= dataStart
- buffer
;
808 for (++dataStart
; *dataStart
== ' '; ++dataStart
)
811 const char* dataEnd
= (const char*)rawmemchr(dataStart
, '\0');
812 // The last char should be a newline, but we can never be sure: #633350
813 const char* lineEnd
= dataEnd
;
814 for (--lineEnd
; *lineEnd
== '\r' || *lineEnd
== '\n'; --lineEnd
)
819 // which datastorage need to be updated
820 enum { Suite
, Component
, Version
, Origin
, Codename
, Label
, None
} writeTo
= None
;
821 if (buffer
[0] == ' ')
823 #define APT_PARSER_WRITETO(X) else if (strncmp(#X, buffer, len) == 0) writeTo = X;
824 APT_PARSER_WRITETO(Suite
)
825 APT_PARSER_WRITETO(Component
)
826 APT_PARSER_WRITETO(Version
)
827 APT_PARSER_WRITETO(Origin
)
828 APT_PARSER_WRITETO(Codename
)
829 APT_PARSER_WRITETO(Label
)
830 #undef APT_PARSER_WRITETO
831 #define APT_PARSER_FLAGIT(X) else if (strncmp(#X, buffer, len) == 0) \
832 pkgTagSection::FindFlag(FileI->Flags, pkgCache::Flag:: X, dataStart, lineEnd);
833 APT_PARSER_FLAGIT(NotAutomatic
)
834 APT_PARSER_FLAGIT(ButAutomaticUpgrades
)
835 #undef APT_PARSER_FLAGIT
837 // load all data from the line and save it
840 data
.append(dataStart
, dataEnd
);
841 if (sizeof(buffer
) - 1 == (dataEnd
- buffer
))
843 while (fgets(buffer
, sizeof(buffer
), release
) != NULL
)
847 if (strlen(buffer
) != sizeof(buffer
) - 1)
853 // remove spaces and stuff from the end of the data line
854 for (std::string::reverse_iterator s
= data
.rbegin();
855 s
!= data
.rend(); ++s
)
857 if (*s
!= '\r' && *s
!= '\n' && *s
!= ' ')
862 case Suite
: FileI
->Archive
= WriteUniqString(data
); break;
863 case Component
: FileI
->Component
= WriteUniqString(data
); break;
864 case Version
: FileI
->Version
= WriteUniqString(data
); break;
865 case Origin
: FileI
->Origin
= WriteUniqString(data
); break;
866 case Codename
: FileI
->Codename
= WriteUniqString(data
); break;
867 case Label
: FileI
->Label
= WriteUniqString(data
); break;
874 return !_error
->PendingError();
877 // ListParser::GetPrio - Convert the priority from a string /*{{{*/
878 // ---------------------------------------------------------------------
880 unsigned char debListParser::GetPrio(string Str
)
883 if (GrabWord(Str
,PrioList
,Out
) == false)
884 Out
= pkgCache::State::Extra
;