]>
git.saurik.com Git - apt.git/blob - apt-pkg/deb/deblistparser.cc
b79cef41c7dbc8914c6a97fa2aebf5fee28e83e5
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();
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 *I
++ = tolower_ascii(*Start
);
292 if (*Start
== '<' && Start
[1] != '<' && Start
[1] != '=')
294 if (*Start
== '>' && Start
[1] != '>' && Start
[1] != '=')
298 Result
= AddCRC16(Result
,S
,I
- 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
& 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
++);
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 if (StripMultiArch
== true) {
504 size_t const found
= Package
.rfind(':');
505 if (found
!= string::npos
)
506 Package
= Package
.substr(0,found
);
509 // Skip white space to the '('
510 for (;I
!= Stop
&& isspace(*I
) != 0 ; I
++);
513 if (I
!= Stop
&& *I
== '(')
516 for (I
++; I
!= Stop
&& isspace(*I
) != 0 ; I
++);
519 I
= ConvertRelation(I
,Op
);
522 for (;I
!= Stop
&& isspace(*I
) != 0; I
++);
524 for (;I
!= Stop
&& *I
!= ')'; I
++);
525 if (I
== Stop
|| Start
== I
)
528 // Skip trailing whitespace
530 for (; End
> Start
&& isspace(End
[-1]); End
--);
532 Ver
.assign(Start
,End
-Start
);
538 Op
= pkgCache::Dep::NoOp
;
542 for (;I
!= Stop
&& isspace(*I
) != 0; I
++);
544 if (ParseArchFlags
== true)
546 string arch
= _config
->Find("APT::Architecture");
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
);
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());
679 if (NewProvides(Ver
, Package
, Arch
, Version
) == false)
688 if (Ver
->MultiArch
== pkgCache::Version::Allowed
|| Ver
->MultiArch
== pkgCache::Version::AllAllowed
)
690 string
const Package
= string(Ver
.ParentPkg().Name()).append(":").append("any");
691 NewProvides(Ver
, Package
, "any", Ver
.VerStr());
694 if (Ver
->MultiArch
!= pkgCache::Version::Foreign
&& Ver
->MultiArch
!= pkgCache::Version::AllForeign
)
697 if (MultiArchEnabled
== false)
700 string
const Package
= Ver
.ParentPkg().Name();
701 string
const Version
= Ver
.VerStr();
702 for (std::vector
<string
>::const_iterator a
= Architectures
.begin();
703 a
!= Architectures
.end(); ++a
)
705 if (NewProvides(Ver
, Package
, *a
, Version
) == false)
712 // ListParser::GrabWord - Matches a word and returns /*{{{*/
713 // ---------------------------------------------------------------------
714 /* Looks for a word in a list of words - for ParseStatus */
715 bool debListParser::GrabWord(string Word
,WordList
*List
,unsigned char &Out
)
717 for (unsigned int C
= 0; List
[C
].Str
!= 0; C
++)
719 if (strcasecmp(Word
.c_str(),List
[C
].Str
) == 0)
728 // ListParser::Step - Move to the next section in the file /*{{{*/
729 // ---------------------------------------------------------------------
730 /* This has to be carefull to only process the correct architecture */
731 bool debListParser::Step()
733 iOffset
= Tags
.Offset();
734 while (Tags
.Step(Section
) == true)
736 /* See if this is the correct Architecture, if it isn't then we
737 drop the whole section. A missing arch tag only happens (in theory)
738 inside the Status file, so that is a positive return */
739 string
const Architecture
= Section
.FindS("Architecture");
740 if (Architecture
.empty() == true)
743 if (Arch
.empty() == true || Arch
== "any" || MultiArchEnabled
== false)
745 if (APT::Configuration::checkArchitecture(Architecture
) == true)
750 if (Architecture
== Arch
)
753 if (Architecture
== "all" && Arch
== _config
->Find("APT::Architecture"))
757 iOffset
= Tags
.Offset();
762 // ListParser::LoadReleaseInfo - Load the release information /*{{{*/
763 // ---------------------------------------------------------------------
765 bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator
&FileI
,
766 FileFd
&File
, string component
)
768 // apt-secure does no longer download individual (per-section) Release
769 // file. to provide Component pinning we use the section name now
770 FileI
->Component
= WriteUniqString(component
);
772 FILE* release
= fdopen(dup(File
.Fd()), "r");
777 bool gpgClose
= false;
778 while (fgets(buffer
, sizeof(buffer
), release
) != NULL
)
783 for (; buffer
[len
] == '\r' && buffer
[len
] == '\n'; ++len
);
784 if (buffer
[len
] == '\0')
787 // only evalute the first GPG section
788 if (strncmp("-----", buffer
, 5) == 0)
790 if (gpgClose
== true)
796 // seperate the tag from the data
797 for (; buffer
[len
] != ':' && buffer
[len
] != '\0'; ++len
);
798 if (buffer
[len
] == '\0')
800 char* dataStart
= buffer
+ len
;
801 for (++dataStart
; *dataStart
== ' '; ++dataStart
);
802 char* dataEnd
= dataStart
;
803 for (++dataEnd
; *dataEnd
!= '\0'; ++dataEnd
);
805 // which datastorage need to be updated
806 map_ptrloc
* writeTo
= NULL
;
807 if (buffer
[0] == ' ')
809 #define APT_PARSER_WRITETO(X, Y) else if (strncmp(Y, buffer, len) == 0) writeTo = &X;
810 APT_PARSER_WRITETO(FileI
->Archive
, "Suite")
811 APT_PARSER_WRITETO(FileI
->Component
, "Component")
812 APT_PARSER_WRITETO(FileI
->Version
, "Version")
813 APT_PARSER_WRITETO(FileI
->Origin
, "Origin")
814 APT_PARSER_WRITETO(FileI
->Codename
, "Codename")
815 APT_PARSER_WRITETO(FileI
->Label
, "Label")
816 #undef APT_PARSER_WRITETO
817 #define APT_PARSER_FLAGIT(X) else if (strncmp(#X, buffer, len) == 0) \
818 pkgTagSection::FindFlag(FileI->Flags, pkgCache::Flag:: X, dataStart, dataEnd-1);
819 APT_PARSER_FLAGIT(NotAutomatic
)
820 APT_PARSER_FLAGIT(ButAutomaticUpgrades
)
821 #undef APT_PARSER_FLAGIT
823 // load all data from the line and save it
826 data
.append(dataStart
, dataEnd
);
827 if (sizeof(buffer
) - 1 == (dataEnd
- buffer
))
829 while (fgets(buffer
, sizeof(buffer
), release
) != NULL
)
833 if (strlen(buffer
) != sizeof(buffer
) - 1)
839 // remove spaces and stuff from the end of the data line
840 for (std::string::reverse_iterator s
= data
.rbegin();
841 s
!= data
.rend(); ++s
)
843 if (*s
!= '\r' && *s
!= '\n' && *s
!= ' ')
847 *writeTo
= WriteUniqString(data
);
852 return !_error
->PendingError();
855 // ListParser::GetPrio - Convert the priority from a string /*{{{*/
856 // ---------------------------------------------------------------------
858 unsigned char debListParser::GetPrio(string Str
)
861 if (GrabWord(Str
,PrioList
,Out
) == false)
862 Out
= pkgCache::State::Extra
;