]>
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)
253 if ((essential
== "native" && Pkg
->Arch
!= 0 && myArch
== Pkg
.Arch()) ||
255 Pkg
->Flags
|= pkgCache::Flag::Essential
| pkgCache::Flag::Important
;
257 Pkg
->Flags
|= pkgCache::Flag::Important
;
260 if (ParseStatus(Pkg
,Ver
) == false)
265 // ListParser::VersionHash - Compute a unique hash for this version /*{{{*/
266 // ---------------------------------------------------------------------
268 unsigned short debListParser::VersionHash()
270 const char *Sections
[] ={"Installed-Size",
278 unsigned long Result
= INIT_FCS
;
280 for (const char **I
= Sections
; *I
!= 0; I
++)
284 if (Section
.Find(*I
,Start
,End
) == false || End
- Start
>= (signed)sizeof(S
))
287 /* Strip out any spaces from the text, this undoes dpkgs reformatting
288 of certain fields. dpkg also has the rather interesting notion of
289 reformatting depends operators < -> <= */
291 for (; Start
!= End
; Start
++)
293 if (isspace(*Start
) == 0)
294 *J
++ = tolower_ascii(*Start
);
295 if (*Start
== '<' && Start
[1] != '<' && Start
[1] != '=')
297 if (*Start
== '>' && Start
[1] != '>' && Start
[1] != '=')
301 Result
= AddCRC16(Result
,S
,J
- S
);
307 // ListParser::ParseStatus - Parse the status field /*{{{*/
308 // ---------------------------------------------------------------------
309 /* Status lines are of the form,
310 Status: want flag status
311 want = unknown, install, hold, deinstall, purge
312 flag = ok, reinstreq, hold, hold-reinstreq
313 status = not-installed, unpacked, half-configured,
314 half-installed, config-files, post-inst-failed,
315 removal-failed, installed
317 Some of the above are obsolete (I think?) flag = hold-* and
318 status = post-inst-failed, removal-failed at least.
320 bool debListParser::ParseStatus(pkgCache::PkgIterator
&Pkg
,
321 pkgCache::VerIterator
&Ver
)
325 if (Section
.Find("Status",Start
,Stop
) == false)
328 // UsePackage() is responsible for setting the flag in the default case
329 bool const static essential
= _config
->Find("pkgCacheGen::Essential", "") == "installed";
330 if (essential
== true &&
331 Section
.FindFlag("Essential",Pkg
->Flags
,pkgCache::Flag::Essential
) == false)
334 // Isolate the first word
335 const char *I
= Start
;
336 for(; I
< Stop
&& *I
!= ' '; I
++);
337 if (I
>= Stop
|| *I
!= ' ')
338 return _error
->Error("Malformed Status line");
340 // Process the want field
341 WordList WantList
[] = {{"unknown",pkgCache::State::Unknown
},
342 {"install",pkgCache::State::Install
},
343 {"hold",pkgCache::State::Hold
},
344 {"deinstall",pkgCache::State::DeInstall
},
345 {"purge",pkgCache::State::Purge
},
347 if (GrabWord(string(Start
,I
-Start
),WantList
,Pkg
->SelectedState
) == false)
348 return _error
->Error("Malformed 1st word in the Status line");
350 // Isloate the next word
353 for(; I
< Stop
&& *I
!= ' '; I
++);
354 if (I
>= Stop
|| *I
!= ' ')
355 return _error
->Error("Malformed status line, no 2nd word");
357 // Process the flag field
358 WordList FlagList
[] = {{"ok",pkgCache::State::Ok
},
359 {"reinstreq",pkgCache::State::ReInstReq
},
360 {"hold",pkgCache::State::HoldInst
},
361 {"hold-reinstreq",pkgCache::State::HoldReInstReq
},
363 if (GrabWord(string(Start
,I
-Start
),FlagList
,Pkg
->InstState
) == false)
364 return _error
->Error("Malformed 2nd word in the Status line");
366 // Isloate the last word
369 for(; I
< Stop
&& *I
!= ' '; I
++);
371 return _error
->Error("Malformed Status line, no 3rd word");
373 // Process the flag field
374 WordList StatusList
[] = {{"not-installed",pkgCache::State::NotInstalled
},
375 {"unpacked",pkgCache::State::UnPacked
},
376 {"half-configured",pkgCache::State::HalfConfigured
},
377 {"installed",pkgCache::State::Installed
},
378 {"half-installed",pkgCache::State::HalfInstalled
},
379 {"config-files",pkgCache::State::ConfigFiles
},
380 {"triggers-awaited",pkgCache::State::TriggersAwaited
},
381 {"triggers-pending",pkgCache::State::TriggersPending
},
382 {"post-inst-failed",pkgCache::State::HalfConfigured
},
383 {"removal-failed",pkgCache::State::HalfInstalled
},
385 if (GrabWord(string(Start
,I
-Start
),StatusList
,Pkg
->CurrentState
) == false)
386 return _error
->Error("Malformed 3rd word in the Status line");
388 /* A Status line marks the package as indicating the current
389 version as well. Only if it is actually installed.. Otherwise
390 the interesting dpkg handling of the status file creates bogus
392 if (!(Pkg
->CurrentState
== pkgCache::State::NotInstalled
||
393 Pkg
->CurrentState
== pkgCache::State::ConfigFiles
))
395 if (Ver
.end() == true)
396 _error
->Warning("Encountered status field in a non-version description");
398 Pkg
->CurrentVer
= Ver
.Index();
404 const char *debListParser::ConvertRelation(const char *I
,unsigned int &Op
)
406 // Determine the operator
414 Op
= pkgCache::Dep::LessEq
;
421 Op
= pkgCache::Dep::Less
;
425 // < is the same as <= and << is really Cs < for some reason
426 Op
= pkgCache::Dep::LessEq
;
434 Op
= pkgCache::Dep::GreaterEq
;
441 Op
= pkgCache::Dep::Greater
;
445 // > is the same as >= and >> is really Cs > for some reason
446 Op
= pkgCache::Dep::GreaterEq
;
450 Op
= pkgCache::Dep::Equals
;
454 // HACK around bad package definitions
456 Op
= pkgCache::Dep::Equals
;
465 * The complete architecture, consisting of <kernel>-<cpu>.
467 static string
CompleteArch(std::string
const &arch
) {
468 if (arch
== "armel") return "linux-arm";
469 if (arch
== "armhf") return "linux-arm";
470 if (arch
== "lpia") return "linux-i386";
471 if (arch
== "powerpcspe") return "linux-powerpc";
472 if (arch
== "uclibc-linux-armel") return "linux-arm";
473 if (arch
== "uclinux-armel") return "uclinux-arm";
475 return (arch
.find("-") != string::npos
) ? arch
: "linux-" + arch
;
478 // ListParser::ParseDepends - Parse a dependency element /*{{{*/
479 // ---------------------------------------------------------------------
480 /* This parses the dependency elements out of a standard string in place,
482 const char *debListParser::ParseDepends(const char *Start
,const char *Stop
,
483 string
&Package
,string
&Ver
,
484 unsigned int &Op
, bool const &ParseArchFlags
,
485 bool const &StripMultiArch
)
487 // Strip off leading space
488 for (;Start
!= Stop
&& isspace(*Start
) != 0; Start
++);
490 // Parse off the package name
491 const char *I
= Start
;
492 for (;I
!= Stop
&& isspace(*I
) == 0 && *I
!= '(' && *I
!= ')' &&
493 *I
!= ',' && *I
!= '|' && *I
!= '[' && *I
!= ']'; I
++);
496 if (I
!= Stop
&& *I
== ')')
502 // Stash the package name
503 Package
.assign(Start
,I
- Start
);
505 // We don't want to confuse library users which can't handle MultiArch
506 string
const arch
= _config
->Find("APT::Architecture");
507 if (StripMultiArch
== true) {
508 size_t const found
= Package
.rfind(':');
509 if (found
!= string::npos
&&
510 (strcmp(Package
.c_str() + found
, ":any") == 0 ||
511 strcmp(Package
.c_str() + found
, ":native") == 0 ||
512 strcmp(Package
.c_str() + found
+ 1, arch
.c_str()) == 0))
513 Package
= Package
.substr(0,found
);
516 // Skip white space to the '('
517 for (;I
!= Stop
&& isspace(*I
) != 0 ; I
++);
520 if (I
!= Stop
&& *I
== '(')
523 for (I
++; I
!= Stop
&& isspace(*I
) != 0 ; I
++);
526 I
= ConvertRelation(I
,Op
);
529 for (;I
!= Stop
&& isspace(*I
) != 0; I
++);
531 I
= (const char*) memchr(I
, ')', Stop
- I
);
532 if (I
== NULL
|| Start
== I
)
535 // Skip trailing whitespace
537 for (; End
> Start
&& isspace(End
[-1]); End
--);
539 Ver
.assign(Start
,End
-Start
);
545 Op
= pkgCache::Dep::NoOp
;
549 for (;I
!= Stop
&& isspace(*I
) != 0; I
++);
551 if (ParseArchFlags
== true)
553 string completeArch
= CompleteArch(arch
);
555 // Parse an architecture
556 if (I
!= Stop
&& *I
== '[')
565 bool NegArch
= false;
568 // look for whitespace or ending ']'
569 while (End
!= Stop
&& !isspace(*End
) && *End
!= ']')
581 if (stringcmp(arch
,I
,End
) == 0) {
584 std::string wildcard
= SubstVar(string(I
, End
), "any", "*");
585 if (fnmatch(wildcard
.c_str(), completeArch
.c_str(), 0) == 0)
595 for (;I
!= Stop
&& isspace(*I
) != 0; I
++);
602 Package
= ""; /* not for this arch */
606 for (;I
!= Stop
&& isspace(*I
) != 0; I
++);
609 if (I
!= Stop
&& *I
== '|')
610 Op
|= pkgCache::Dep::Or
;
612 if (I
== Stop
|| *I
== ',' || *I
== '|')
615 for (I
++; I
!= Stop
&& isspace(*I
) != 0; I
++);
622 // ListParser::ParseDepends - Parse a dependency list /*{{{*/
623 // ---------------------------------------------------------------------
624 /* This is the higher level depends parser. It takes a tag and generates
625 a complete depends tree for the given version. */
626 bool debListParser::ParseDepends(pkgCache::VerIterator
&Ver
,
627 const char *Tag
,unsigned int Type
)
631 if (Section
.Find(Tag
,Start
,Stop
) == false)
635 string
const pkgArch
= Ver
.Arch();
641 Start
= ParseDepends(Start
,Stop
,Package
,Version
,Op
,false,!MultiArchEnabled
);
643 return _error
->Error("Problem parsing dependency %s",Tag
);
645 if (MultiArchEnabled
== true &&
646 (Type
== pkgCache::Dep::Conflicts
||
647 Type
== pkgCache::Dep::DpkgBreaks
||
648 Type
== pkgCache::Dep::Replaces
))
650 for (std::vector
<std::string
>::const_iterator a
= Architectures
.begin();
651 a
!= Architectures
.end(); ++a
)
652 if (NewDepends(Ver
,Package
,*a
,Version
,Op
,Type
) == false)
655 else if (NewDepends(Ver
,Package
,pkgArch
,Version
,Op
,Type
) == false)
663 // ListParser::ParseProvides - Parse the provides list /*{{{*/
664 // ---------------------------------------------------------------------
666 bool debListParser::ParseProvides(pkgCache::VerIterator
&Ver
)
670 if (Section
.Find("Provides",Start
,Stop
) == true)
674 string
const Arch
= Ver
.Arch();
679 Start
= ParseDepends(Start
,Stop
,Package
,Version
,Op
);
681 return _error
->Error("Problem parsing Provides line");
682 if (Op
!= pkgCache::Dep::NoOp
) {
683 _error
->Warning("Ignoring Provides line with DepCompareOp for package %s", Package
.c_str());
684 } else if ((Ver
->MultiArch
& pkgCache::Version::Foreign
) == pkgCache::Version::Foreign
) {
685 if (NewProvidesAllArch(Ver
, Package
, Version
) == false)
688 if (NewProvides(Ver
, Package
, Arch
, Version
) == false)
697 if (MultiArchEnabled
== false)
699 else if ((Ver
->MultiArch
& pkgCache::Version::Allowed
) == pkgCache::Version::Allowed
)
701 string
const Package
= string(Ver
.ParentPkg().Name()).append(":").append("any");
702 return NewProvidesAllArch(Ver
, Package
, Ver
.VerStr());
704 else if ((Ver
->MultiArch
& pkgCache::Version::Foreign
) == pkgCache::Version::Foreign
)
705 return NewProvidesAllArch(Ver
, Ver
.ParentPkg().Name(), Ver
.VerStr());
710 // ListParser::NewProvides - add provides for all architectures /*{{{*/
711 bool debListParser::NewProvidesAllArch(pkgCache::VerIterator
&Ver
, string
const &Package
,
712 string
const &Version
) {
713 for (std::vector
<string
>::const_iterator a
= Architectures
.begin();
714 a
!= Architectures
.end(); ++a
)
716 if (NewProvides(Ver
, Package
, *a
, Version
) == false)
722 // ListParser::GrabWord - Matches a word and returns /*{{{*/
723 // ---------------------------------------------------------------------
724 /* Looks for a word in a list of words - for ParseStatus */
725 bool debListParser::GrabWord(string Word
,WordList
*List
,unsigned char &Out
)
727 for (unsigned int C
= 0; List
[C
].Str
!= 0; C
++)
729 if (strcasecmp(Word
.c_str(),List
[C
].Str
) == 0)
738 // ListParser::Step - Move to the next section in the file /*{{{*/
739 // ---------------------------------------------------------------------
740 /* This has to be carefull to only process the correct architecture */
741 bool debListParser::Step()
743 iOffset
= Tags
.Offset();
744 while (Tags
.Step(Section
) == true)
746 /* See if this is the correct Architecture, if it isn't then we
747 drop the whole section. A missing arch tag only happens (in theory)
748 inside the Status file, so that is a positive return */
749 string
const Architecture
= Section
.FindS("Architecture");
750 if (Architecture
.empty() == true)
753 if (Arch
.empty() == true || Arch
== "any" || MultiArchEnabled
== false)
755 if (APT::Configuration::checkArchitecture(Architecture
) == true)
760 if (Architecture
== Arch
)
763 if (Architecture
== "all" && Arch
== _config
->Find("APT::Architecture"))
767 iOffset
= Tags
.Offset();
772 // ListParser::LoadReleaseInfo - Load the release information /*{{{*/
773 // ---------------------------------------------------------------------
775 bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator
&FileI
,
776 FileFd
&File
, string component
)
778 // apt-secure does no longer download individual (per-section) Release
779 // file. to provide Component pinning we use the section name now
780 FileI
->Component
= WriteUniqString(component
);
782 // FIXME: Code depends on the fact that Release files aren't compressed
783 FILE* release
= fdopen(dup(File
.Fd()), "r");
788 bool gpgClose
= false;
789 while (fgets(buffer
, sizeof(buffer
), release
) != NULL
)
794 for (; buffer
[len
] == '\r' && buffer
[len
] == '\n'; ++len
)
797 if (buffer
[len
] == '\0')
800 // only evalute the first GPG section
801 if (strncmp("-----", buffer
, 5) == 0)
803 if (gpgClose
== true)
809 // seperate the tag from the data
810 const char* dataStart
= strchr(buffer
+ len
, ':');
811 if (dataStart
== NULL
)
813 len
= dataStart
- buffer
;
814 for (++dataStart
; *dataStart
== ' '; ++dataStart
)
817 const char* dataEnd
= (const char*)rawmemchr(dataStart
, '\0');
818 // The last char should be a newline, but we can never be sure: #633350
819 const char* lineEnd
= dataEnd
;
820 for (--lineEnd
; *lineEnd
== '\r' || *lineEnd
== '\n'; --lineEnd
)
825 // which datastorage need to be updated
826 enum { Suite
, Component
, Version
, Origin
, Codename
, Label
, None
} writeTo
= None
;
827 if (buffer
[0] == ' ')
829 #define APT_PARSER_WRITETO(X) else if (strncmp(#X, buffer, len) == 0) writeTo = X;
830 APT_PARSER_WRITETO(Suite
)
831 APT_PARSER_WRITETO(Component
)
832 APT_PARSER_WRITETO(Version
)
833 APT_PARSER_WRITETO(Origin
)
834 APT_PARSER_WRITETO(Codename
)
835 APT_PARSER_WRITETO(Label
)
836 #undef APT_PARSER_WRITETO
837 #define APT_PARSER_FLAGIT(X) else if (strncmp(#X, buffer, len) == 0) \
838 pkgTagSection::FindFlag(FileI->Flags, pkgCache::Flag:: X, dataStart, lineEnd);
839 APT_PARSER_FLAGIT(NotAutomatic
)
840 APT_PARSER_FLAGIT(ButAutomaticUpgrades
)
841 #undef APT_PARSER_FLAGIT
843 // load all data from the line and save it
846 data
.append(dataStart
, dataEnd
);
847 if (sizeof(buffer
) - 1 == (dataEnd
- buffer
))
849 while (fgets(buffer
, sizeof(buffer
), release
) != NULL
)
853 if (strlen(buffer
) != sizeof(buffer
) - 1)
859 // remove spaces and stuff from the end of the data line
860 for (std::string::reverse_iterator s
= data
.rbegin();
861 s
!= data
.rend(); ++s
)
863 if (*s
!= '\r' && *s
!= '\n' && *s
!= ' ')
868 case Suite
: FileI
->Archive
= WriteUniqString(data
); break;
869 case Component
: FileI
->Component
= WriteUniqString(data
); break;
870 case Version
: FileI
->Version
= WriteUniqString(data
); break;
871 case Origin
: FileI
->Origin
= WriteUniqString(data
); break;
872 case Codename
: FileI
->Codename
= WriteUniqString(data
); break;
873 case Label
: FileI
->Label
= WriteUniqString(data
); break;
880 return !_error
->PendingError();
883 // ListParser::GetPrio - Convert the priority from a string /*{{{*/
884 // ---------------------------------------------------------------------
886 unsigned char debListParser::GetPrio(string Str
)
889 if (GrabWord(Str
,PrioList
,Out
) == false)
890 Out
= pkgCache::State::Extra
;