]>
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 return Section
.FindS("Architecture");
75 // ListParser::ArchitectureAll /*{{{*/
76 // ---------------------------------------------------------------------
78 bool debListParser::ArchitectureAll() {
79 return Section
.FindS("Architecture") == "all";
82 // ListParser::Version - Return the version string /*{{{*/
83 // ---------------------------------------------------------------------
84 /* This is to return the string describing the version in debian form,
85 epoch:upstream-release. If this returns the blank string then the
86 entry is assumed to only describe package properties */
87 string
debListParser::Version()
89 return Section
.FindS("Version");
92 // ListParser::NewVersion - Fill in the version structure /*{{{*/
93 // ---------------------------------------------------------------------
95 bool debListParser::NewVersion(pkgCache::VerIterator
&Ver
)
98 Ver
->Section
= UniqFindTagWrite("Section");
101 string
const MultiArch
= Section
.FindS("Multi-Arch");
102 if (MultiArch
.empty() == true)
103 Ver
->MultiArch
= pkgCache::Version::None
;
104 else if (MultiArch
== "same") {
106 if (ArchitectureAll() == true)
108 /* Arch all packages can't be Multi-Arch: same */
109 _error
->Warning("Architecture: all package '%s' can't be Multi-Arch: same",
110 Section
.FindS("Package").c_str());
111 Ver
->MultiArch
= pkgCache::Version::None
;
114 Ver
->MultiArch
= pkgCache::Version::Same
;
116 else if (MultiArch
== "foreign")
117 Ver
->MultiArch
= pkgCache::Version::Foreign
;
118 else if (MultiArch
== "allowed")
119 Ver
->MultiArch
= pkgCache::Version::Allowed
;
122 _error
->Warning("Unknown Multi-Arch type '%s' for package '%s'",
123 MultiArch
.c_str(), Section
.FindS("Package").c_str());
124 Ver
->MultiArch
= pkgCache::Version::None
;
127 if (ArchitectureAll() == true)
128 Ver
->MultiArch
|= pkgCache::Version::All
;
131 Ver
->Size
= Section
.FindULL("Size");
132 // Unpacked Size (in K)
133 Ver
->InstalledSize
= Section
.FindULL("Installed-Size");
134 Ver
->InstalledSize
*= 1024;
139 if (Section
.Find("Priority",Start
,Stop
) == true)
141 if (GrabWord(string(Start
,Stop
-Start
),PrioList
,Ver
->Priority
) == false)
142 Ver
->Priority
= pkgCache::State::Extra
;
145 if (ParseDepends(Ver
,"Depends",pkgCache::Dep::Depends
) == false)
147 if (ParseDepends(Ver
,"Pre-Depends",pkgCache::Dep::PreDepends
) == false)
149 if (ParseDepends(Ver
,"Suggests",pkgCache::Dep::Suggests
) == false)
151 if (ParseDepends(Ver
,"Recommends",pkgCache::Dep::Recommends
) == false)
153 if (ParseDepends(Ver
,"Conflicts",pkgCache::Dep::Conflicts
) == false)
155 if (ParseDepends(Ver
,"Breaks",pkgCache::Dep::DpkgBreaks
) == false)
157 if (ParseDepends(Ver
,"Replaces",pkgCache::Dep::Replaces
) == false)
159 if (ParseDepends(Ver
,"Enhances",pkgCache::Dep::Enhances
) == false)
163 if (ParseDepends(Ver
,"Optional",pkgCache::Dep::Suggests
) == false)
166 if (ParseProvides(Ver
) == false)
172 // ListParser::Description - Return the description string /*{{{*/
173 // ---------------------------------------------------------------------
174 /* This is to return the string describing the package in debian
175 form. If this returns the blank string then the entry is assumed to
176 only describe package properties */
177 string
debListParser::Description()
179 string
const lang
= DescriptionLanguage();
181 return Section
.FindS("Description");
183 return Section
.FindS(string("Description-").append(lang
).c_str());
186 // ListParser::DescriptionLanguage - Return the description lang string /*{{{*/
187 // ---------------------------------------------------------------------
188 /* This is to return the string describing the language of
189 description. If this returns the blank string then the entry is
190 assumed to describe original description. */
191 string
debListParser::DescriptionLanguage()
193 if (Section
.FindS("Description").empty() == false)
196 std::vector
<string
> const lang
= APT::Configuration::getLanguages(true);
197 for (std::vector
<string
>::const_iterator l
= lang
.begin();
198 l
!= lang
.end(); ++l
)
199 if (Section
.FindS(string("Description-").append(*l
).c_str()).empty() == false)
205 // ListParser::Description - Return the description_md5 MD5SumValue /*{{{*/
206 // ---------------------------------------------------------------------
207 /* This is to return the md5 string to allow the check if it is the right
208 description. If no Description-md5 is found in the section it will be
211 MD5SumValue
debListParser::Description_md5()
213 string value
= Section
.FindS("Description-md5");
218 md5
.Add((Description() + "\n").c_str());
221 return MD5SumValue(value
);
224 // ListParser::UsePackage - Update a package structure /*{{{*/
225 // ---------------------------------------------------------------------
226 /* This is called to update the package with any new information
227 that might be found in the section */
228 bool debListParser::UsePackage(pkgCache::PkgIterator
&Pkg
,
229 pkgCache::VerIterator
&Ver
)
231 if (Pkg
->Section
== 0)
232 Pkg
->Section
= UniqFindTagWrite("Section");
234 // Packages which are not from the "native" arch doesn't get the essential flag
235 // in the default "native" mode - it is also possible to mark "all" or "none".
236 // The "installed" mode is handled by ParseStatus(), See #544481 and friends.
237 string
const static myArch
= _config
->Find("APT::Architecture");
238 string
const static essential
= _config
->Find("pkgCacheGen::Essential", "native");
239 if ((essential
== "native" && Pkg
->Arch
!= 0 && myArch
== Pkg
.Arch()) ||
241 if (Section
.FindFlag("Essential",Pkg
->Flags
,pkgCache::Flag::Essential
) == false)
243 if (Section
.FindFlag("Important",Pkg
->Flags
,pkgCache::Flag::Important
) == false)
246 if (strcmp(Pkg
.Name(),"apt") == 0)
247 Pkg
->Flags
|= pkgCache::Flag::Important
;
249 if (ParseStatus(Pkg
,Ver
) == false)
254 // ListParser::VersionHash - Compute a unique hash for this version /*{{{*/
255 // ---------------------------------------------------------------------
257 unsigned short debListParser::VersionHash()
259 const char *Sections
[] ={"Installed-Size",
267 unsigned long Result
= INIT_FCS
;
269 for (const char **I
= Sections
; *I
!= 0; I
++)
273 if (Section
.Find(*I
,Start
,End
) == false || End
- Start
>= (signed)sizeof(S
))
276 /* Strip out any spaces from the text, this undoes dpkgs reformatting
277 of certain fields. dpkg also has the rather interesting notion of
278 reformatting depends operators < -> <= */
280 for (; Start
!= End
; Start
++)
282 if (isspace(*Start
) == 0)
283 *J
++ = tolower_ascii(*Start
);
284 if (*Start
== '<' && Start
[1] != '<' && Start
[1] != '=')
286 if (*Start
== '>' && Start
[1] != '>' && Start
[1] != '=')
290 Result
= AddCRC16(Result
,S
,J
- S
);
296 // ListParser::ParseStatus - Parse the status field /*{{{*/
297 // ---------------------------------------------------------------------
298 /* Status lines are of the form,
299 Status: want flag status
300 want = unknown, install, hold, deinstall, purge
301 flag = ok, reinstreq, hold, hold-reinstreq
302 status = not-installed, unpacked, half-configured,
303 half-installed, config-files, post-inst-failed,
304 removal-failed, installed
306 Some of the above are obsolete (I think?) flag = hold-* and
307 status = post-inst-failed, removal-failed at least.
309 bool debListParser::ParseStatus(pkgCache::PkgIterator
&Pkg
,
310 pkgCache::VerIterator
&Ver
)
314 if (Section
.Find("Status",Start
,Stop
) == false)
317 // UsePackage() is responsible for setting the flag in the default case
318 bool const static essential
= _config
->Find("pkgCacheGen::Essential", "") == "installed";
319 if (essential
== true &&
320 Section
.FindFlag("Essential",Pkg
->Flags
,pkgCache::Flag::Essential
) == false)
323 // Isolate the first word
324 const char *I
= Start
;
325 for(; I
< Stop
&& *I
!= ' '; I
++);
326 if (I
>= Stop
|| *I
!= ' ')
327 return _error
->Error("Malformed Status line");
329 // Process the want field
330 WordList WantList
[] = {{"unknown",pkgCache::State::Unknown
},
331 {"install",pkgCache::State::Install
},
332 {"hold",pkgCache::State::Hold
},
333 {"deinstall",pkgCache::State::DeInstall
},
334 {"purge",pkgCache::State::Purge
},
336 if (GrabWord(string(Start
,I
-Start
),WantList
,Pkg
->SelectedState
) == false)
337 return _error
->Error("Malformed 1st word in the Status line");
339 // Isloate the next word
342 for(; I
< Stop
&& *I
!= ' '; I
++);
343 if (I
>= Stop
|| *I
!= ' ')
344 return _error
->Error("Malformed status line, no 2nd word");
346 // Process the flag field
347 WordList FlagList
[] = {{"ok",pkgCache::State::Ok
},
348 {"reinstreq",pkgCache::State::ReInstReq
},
349 {"hold",pkgCache::State::HoldInst
},
350 {"hold-reinstreq",pkgCache::State::HoldReInstReq
},
352 if (GrabWord(string(Start
,I
-Start
),FlagList
,Pkg
->InstState
) == false)
353 return _error
->Error("Malformed 2nd word in the Status line");
355 // Isloate the last word
358 for(; I
< Stop
&& *I
!= ' '; I
++);
360 return _error
->Error("Malformed Status line, no 3rd word");
362 // Process the flag field
363 WordList StatusList
[] = {{"not-installed",pkgCache::State::NotInstalled
},
364 {"unpacked",pkgCache::State::UnPacked
},
365 {"half-configured",pkgCache::State::HalfConfigured
},
366 {"installed",pkgCache::State::Installed
},
367 {"half-installed",pkgCache::State::HalfInstalled
},
368 {"config-files",pkgCache::State::ConfigFiles
},
369 {"triggers-awaited",pkgCache::State::TriggersAwaited
},
370 {"triggers-pending",pkgCache::State::TriggersPending
},
371 {"post-inst-failed",pkgCache::State::HalfConfigured
},
372 {"removal-failed",pkgCache::State::HalfInstalled
},
374 if (GrabWord(string(Start
,I
-Start
),StatusList
,Pkg
->CurrentState
) == false)
375 return _error
->Error("Malformed 3rd word in the Status line");
377 /* A Status line marks the package as indicating the current
378 version as well. Only if it is actually installed.. Otherwise
379 the interesting dpkg handling of the status file creates bogus
381 if (!(Pkg
->CurrentState
== pkgCache::State::NotInstalled
||
382 Pkg
->CurrentState
== pkgCache::State::ConfigFiles
))
384 if (Ver
.end() == true)
385 _error
->Warning("Encountered status field in a non-version description");
387 Pkg
->CurrentVer
= Ver
.Index();
393 const char *debListParser::ConvertRelation(const char *I
,unsigned int &Op
)
395 // Determine the operator
403 Op
= pkgCache::Dep::LessEq
;
410 Op
= pkgCache::Dep::Less
;
414 // < is the same as <= and << is really Cs < for some reason
415 Op
= pkgCache::Dep::LessEq
;
423 Op
= pkgCache::Dep::GreaterEq
;
430 Op
= pkgCache::Dep::Greater
;
434 // > is the same as >= and >> is really Cs > for some reason
435 Op
= pkgCache::Dep::GreaterEq
;
439 Op
= pkgCache::Dep::Equals
;
443 // HACK around bad package definitions
445 Op
= pkgCache::Dep::Equals
;
454 * The complete architecture, consisting of <kernel>-<cpu>.
456 static string
CompleteArch(std::string
const &arch
) {
457 if (arch
== "armel") return "linux-arm";
458 if (arch
== "armhf") return "linux-arm";
459 if (arch
== "lpia") return "linux-i386";
460 if (arch
== "powerpcspe") return "linux-powerpc";
461 if (arch
== "uclibc-linux-armel") return "linux-arm";
462 if (arch
== "uclinux-armel") return "uclinux-arm";
464 return (arch
.find("-") != string::npos
) ? arch
: "linux-" + arch
;
467 // ListParser::ParseDepends - Parse a dependency element /*{{{*/
468 // ---------------------------------------------------------------------
469 /* This parses the dependency elements out of a standard string in place,
471 const char *debListParser::ParseDepends(const char *Start
,const char *Stop
,
472 string
&Package
,string
&Ver
,
473 unsigned int &Op
, bool const &ParseArchFlags
,
474 bool const &StripMultiArch
)
476 // Strip off leading space
477 for (;Start
!= Stop
&& isspace(*Start
) != 0; Start
++);
479 // Parse off the package name
480 const char *I
= Start
;
481 for (;I
!= Stop
&& isspace(*I
) == 0 && *I
!= '(' && *I
!= ')' &&
482 *I
!= ',' && *I
!= '|' && *I
!= '[' && *I
!= ']'; I
++);
485 if (I
!= Stop
&& *I
== ')')
491 // Stash the package name
492 Package
.assign(Start
,I
- Start
);
494 // We don't want to confuse library users which can't handle MultiArch
495 string
const arch
= _config
->Find("APT::Architecture");
496 if (StripMultiArch
== true) {
497 size_t const found
= Package
.rfind(':');
498 if (found
!= string::npos
&&
499 (strcmp(Package
.c_str() + found
, ":any") == 0 ||
500 strcmp(Package
.c_str() + found
, ":native") == 0 ||
501 strcmp(Package
.c_str() + found
+ 1, arch
.c_str()) == 0))
502 Package
= Package
.substr(0,found
);
505 // Skip white space to the '('
506 for (;I
!= Stop
&& isspace(*I
) != 0 ; I
++);
509 if (I
!= Stop
&& *I
== '(')
512 for (I
++; I
!= Stop
&& isspace(*I
) != 0 ; I
++);
515 I
= ConvertRelation(I
,Op
);
518 for (;I
!= Stop
&& isspace(*I
) != 0; I
++);
520 for (;I
!= Stop
&& *I
!= ')'; I
++);
521 if (I
== Stop
|| Start
== I
)
524 // Skip trailing whitespace
526 for (; End
> Start
&& isspace(End
[-1]); End
--);
528 Ver
.assign(Start
,End
-Start
);
534 Op
= pkgCache::Dep::NoOp
;
538 for (;I
!= Stop
&& isspace(*I
) != 0; I
++);
540 if (ParseArchFlags
== true)
542 string completeArch
= CompleteArch(arch
);
544 // Parse an architecture
545 if (I
!= Stop
&& *I
== '[')
554 bool NegArch
= false;
557 // look for whitespace or ending ']'
558 while (End
!= Stop
&& !isspace(*End
) && *End
!= ']')
570 if (stringcmp(arch
,I
,End
) == 0) {
573 std::string wildcard
= SubstVar(string(I
, End
), "any", "*");
574 if (fnmatch(wildcard
.c_str(), completeArch
.c_str(), 0) == 0)
584 for (;I
!= Stop
&& isspace(*I
) != 0; I
++);
591 Package
= ""; /* not for this arch */
595 for (;I
!= Stop
&& isspace(*I
) != 0; I
++);
598 if (I
!= Stop
&& *I
== '|')
599 Op
|= pkgCache::Dep::Or
;
601 if (I
== Stop
|| *I
== ',' || *I
== '|')
604 for (I
++; I
!= Stop
&& isspace(*I
) != 0; I
++);
611 // ListParser::ParseDepends - Parse a dependency list /*{{{*/
612 // ---------------------------------------------------------------------
613 /* This is the higher level depends parser. It takes a tag and generates
614 a complete depends tree for the given version. */
615 bool debListParser::ParseDepends(pkgCache::VerIterator
&Ver
,
616 const char *Tag
,unsigned int Type
)
620 if (Section
.Find(Tag
,Start
,Stop
) == false)
624 string
const pkgArch
= Ver
.Arch();
630 Start
= ParseDepends(Start
,Stop
,Package
,Version
,Op
,false,!MultiArchEnabled
);
632 return _error
->Error("Problem parsing dependency %s",Tag
);
634 if (MultiArchEnabled
== true &&
635 (Type
== pkgCache::Dep::Conflicts
||
636 Type
== pkgCache::Dep::DpkgBreaks
||
637 Type
== pkgCache::Dep::Replaces
))
639 for (std::vector
<std::string
>::const_iterator a
= Architectures
.begin();
640 a
!= Architectures
.end(); ++a
)
641 if (NewDepends(Ver
,Package
,*a
,Version
,Op
,Type
) == false)
644 else if (NewDepends(Ver
,Package
,pkgArch
,Version
,Op
,Type
) == false)
652 // ListParser::ParseProvides - Parse the provides list /*{{{*/
653 // ---------------------------------------------------------------------
655 bool debListParser::ParseProvides(pkgCache::VerIterator
&Ver
)
659 if (Section
.Find("Provides",Start
,Stop
) == true)
663 string
const Arch
= Ver
.Arch();
668 Start
= ParseDepends(Start
,Stop
,Package
,Version
,Op
);
670 return _error
->Error("Problem parsing Provides line");
671 if (Op
!= pkgCache::Dep::NoOp
) {
672 _error
->Warning("Ignoring Provides line with DepCompareOp for package %s", Package
.c_str());
674 if (NewProvides(Ver
, Package
, Arch
, Version
) == false)
683 if (MultiArchEnabled
== false)
685 else if ((Ver
->MultiArch
& pkgCache::Version::Allowed
) == pkgCache::Version::Allowed
)
687 string
const Package
= string(Ver
.ParentPkg().Name()).append(":").append("any");
688 return NewProvidesAllArch(Ver
, Package
, Ver
.VerStr());
690 else if ((Ver
->MultiArch
& pkgCache::Version::Foreign
) == pkgCache::Version::Foreign
)
691 return NewProvidesAllArch(Ver
, Ver
.ParentPkg().Name(), Ver
.VerStr());
696 // ListParser::NewProvides - add provides for all architectures /*{{{*/
697 bool debListParser::NewProvidesAllArch(pkgCache::VerIterator
&Ver
, string
const &Package
,
698 string
const &Version
) {
699 for (std::vector
<string
>::const_iterator a
= Architectures
.begin();
700 a
!= Architectures
.end(); ++a
)
702 if (NewProvides(Ver
, Package
, *a
, Version
) == false)
708 // ListParser::GrabWord - Matches a word and returns /*{{{*/
709 // ---------------------------------------------------------------------
710 /* Looks for a word in a list of words - for ParseStatus */
711 bool debListParser::GrabWord(string Word
,WordList
*List
,unsigned char &Out
)
713 for (unsigned int C
= 0; List
[C
].Str
!= 0; C
++)
715 if (strcasecmp(Word
.c_str(),List
[C
].Str
) == 0)
724 // ListParser::Step - Move to the next section in the file /*{{{*/
725 // ---------------------------------------------------------------------
726 /* This has to be carefull to only process the correct architecture */
727 bool debListParser::Step()
729 iOffset
= Tags
.Offset();
730 while (Tags
.Step(Section
) == true)
732 /* See if this is the correct Architecture, if it isn't then we
733 drop the whole section. A missing arch tag only happens (in theory)
734 inside the Status file, so that is a positive return */
735 string
const Architecture
= Section
.FindS("Architecture");
736 if (Architecture
.empty() == true)
739 if (Arch
.empty() == true || Arch
== "any" || MultiArchEnabled
== false)
741 if (APT::Configuration::checkArchitecture(Architecture
) == true)
746 if (Architecture
== Arch
)
749 if (Architecture
== "all" && Arch
== _config
->Find("APT::Architecture"))
753 iOffset
= Tags
.Offset();
758 // ListParser::LoadReleaseInfo - Load the release information /*{{{*/
759 // ---------------------------------------------------------------------
761 bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator
&FileI
,
762 FileFd
&File
, string component
)
764 // apt-secure does no longer download individual (per-section) Release
765 // file. to provide Component pinning we use the section name now
766 FileI
->Component
= WriteUniqString(component
);
768 FILE* release
= fdopen(dup(File
.Fd()), "r");
773 bool gpgClose
= false;
774 while (fgets(buffer
, sizeof(buffer
), release
) != NULL
)
779 for (; buffer
[len
] == '\r' && buffer
[len
] == '\n'; ++len
)
782 if (buffer
[len
] == '\0')
785 // only evalute the first GPG section
786 if (strncmp("-----", buffer
, 5) == 0)
788 if (gpgClose
== true)
794 // seperate the tag from the data
795 for (; buffer
[len
] != ':' && buffer
[len
] != '\0'; ++len
)
798 if (buffer
[len
] == '\0')
800 char* dataStart
= buffer
+ len
;
801 for (++dataStart
; *dataStart
== ' '; ++dataStart
)
804 char* dataEnd
= dataStart
;
805 for (++dataEnd
; *dataEnd
!= '\0'; ++dataEnd
)
808 // The last char should be a newline, but we can never be sure: #633350
809 char* lineEnd
= dataEnd
;
810 for (--lineEnd
; *lineEnd
== '\r' || *lineEnd
== '\n'; --lineEnd
)
815 // which datastorage need to be updated
816 enum { Suite
, Component
, Version
, Origin
, Codename
, Label
, None
} writeTo
= None
;
817 if (buffer
[0] == ' ')
819 #define APT_PARSER_WRITETO(X) else if (strncmp(#X, buffer, len) == 0) writeTo = X;
820 APT_PARSER_WRITETO(Suite
)
821 APT_PARSER_WRITETO(Component
)
822 APT_PARSER_WRITETO(Version
)
823 APT_PARSER_WRITETO(Origin
)
824 APT_PARSER_WRITETO(Codename
)
825 APT_PARSER_WRITETO(Label
)
826 #undef APT_PARSER_WRITETO
827 #define APT_PARSER_FLAGIT(X) else if (strncmp(#X, buffer, len) == 0) \
828 pkgTagSection::FindFlag(FileI->Flags, pkgCache::Flag:: X, dataStart, lineEnd);
829 APT_PARSER_FLAGIT(NotAutomatic
)
830 APT_PARSER_FLAGIT(ButAutomaticUpgrades
)
831 #undef APT_PARSER_FLAGIT
833 // load all data from the line and save it
836 data
.append(dataStart
, dataEnd
);
837 if (sizeof(buffer
) - 1 == (dataEnd
- buffer
))
839 while (fgets(buffer
, sizeof(buffer
), release
) != NULL
)
843 if (strlen(buffer
) != sizeof(buffer
) - 1)
849 // remove spaces and stuff from the end of the data line
850 for (std::string::reverse_iterator s
= data
.rbegin();
851 s
!= data
.rend(); ++s
)
853 if (*s
!= '\r' && *s
!= '\n' && *s
!= ' ')
858 case Suite
: FileI
->Archive
= WriteUniqString(data
); break;
859 case Component
: FileI
->Component
= WriteUniqString(data
); break;
860 case Version
: FileI
->Version
= WriteUniqString(data
); break;
861 case Origin
: FileI
->Origin
= WriteUniqString(data
); break;
862 case Codename
: FileI
->Codename
= WriteUniqString(data
); break;
863 case Label
: FileI
->Label
= WriteUniqString(data
); break;
870 return !_error
->PendingError();
873 // ListParser::GetPrio - Convert the priority from a string /*{{{*/
874 // ---------------------------------------------------------------------
876 unsigned char debListParser::GetPrio(string Str
)
879 if (GrabWord(Str
,PrioList
,Out
) == false)
880 Out
= pkgCache::State::Extra
;