]> git.saurik.com Git - apt.git/blame - apt-pkg/deb/deblistparser.cc
Fix a segfault in the version merger introduced in the previous patch:
[apt.git] / apt-pkg / deb / deblistparser.cc
CommitLineData
f55a958f
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
b3d44315 3// $Id: deblistparser.cc,v 1.29.2.5 2004/01/06 01:43:44 mdz Exp $
f55a958f
AL
4/* ######################################################################
5
6 Package Cache Generator - Generator for the cache structure.
7
8 This builds the cache structure from the abstract package list parser.
9
10 ##################################################################### */
11 /*}}}*/
12// Include Files /*{{{*/
094a497d
AL
13#include <apt-pkg/deblistparser.h>
14#include <apt-pkg/error.h>
15#include <apt-pkg/configuration.h>
45df0ad2 16#include <apt-pkg/aptconfiguration.h>
cdcc6d34 17#include <apt-pkg/strutl.h>
204fbdcc 18#include <apt-pkg/crc-16.h>
a52f938b 19#include <apt-pkg/md5.h>
5c0d3668 20#include <apt-pkg/macros.h>
9c14e3d6 21
e7b470ee 22#include <ctype.h>
f55a958f
AL
23 /*}}}*/
24
b2e465d6
AL
25static debListParser::WordList PrioList[] = {{"important",pkgCache::State::Important},
26 {"required",pkgCache::State::Required},
27 {"standard",pkgCache::State::Standard},
28 {"optional",pkgCache::State::Optional},
29 {"extra",pkgCache::State::Extra},
30 {}};
31
f55a958f
AL
32// ListParser::debListParser - Constructor /*{{{*/
33// ---------------------------------------------------------------------
34/* */
b2e465d6 35debListParser::debListParser(FileFd *File) : Tags(File)
f55a958f 36{
ddc1d8d0 37 Arch = _config->Find("APT::architecture");
0149949b
AL
38}
39 /*}}}*/
f55a958f
AL
40// ListParser::UniqFindTagWrite - Find the tag and write a unq string /*{{{*/
41// ---------------------------------------------------------------------
42/* */
43unsigned long debListParser::UniqFindTagWrite(const char *Tag)
44{
45 const char *Start;
46 const char *Stop;
47 if (Section.Find(Tag,Start,Stop) == false)
48 return 0;
49 return WriteUniqString(Start,Stop - Start);
50}
51 /*}}}*/
f55a958f
AL
52// ListParser::Package - Return the package name /*{{{*/
53// ---------------------------------------------------------------------
54/* This is to return the name of the package this section describes */
55string debListParser::Package()
56{
b0b4efb9 57 string Result = Section.FindS("Package");
f55a958f 58 if (Result.empty() == true)
65a1e968 59 _error->Error("Encountered a section with no Package: header");
f55a958f
AL
60 return Result;
61}
62 /*}}}*/
63// ListParser::Version - Return the version string /*{{{*/
64// ---------------------------------------------------------------------
65/* This is to return the string describing the version in debian form,
66 epoch:upstream-release. If this returns the blank string then the
67 entry is assumed to only describe package properties */
68string debListParser::Version()
69{
b0b4efb9 70 return Section.FindS("Version");
f55a958f
AL
71}
72 /*}}}*/
f55a958f
AL
73// ListParser::NewVersion - Fill in the version structure /*{{{*/
74// ---------------------------------------------------------------------
75/* */
76bool debListParser::NewVersion(pkgCache::VerIterator Ver)
0149949b
AL
77{
78 // Parse the section
b35d2f5f 79 Ver->Section = UniqFindTagWrite("Section");
17caf1b1 80 Ver->Arch = UniqFindTagWrite("Architecture");
0149949b
AL
81
82 // Archive Size
b0b4efb9 83 Ver->Size = (unsigned)Section.FindI("Size");
0149949b
AL
84
85 // Unpacked Size (in K)
b0b4efb9 86 Ver->InstalledSize = (unsigned)Section.FindI("Installed-Size");
0149949b
AL
87 Ver->InstalledSize *= 1024;
88
89 // Priority
90 const char *Start;
91 const char *Stop;
92 if (Section.Find("Priority",Start,Stop) == true)
b2e465d6
AL
93 {
94 if (GrabWord(string(Start,Stop-Start),PrioList,Ver->Priority) == false)
421c8d10 95 Ver->Priority = pkgCache::State::Extra;
0149949b 96 }
dcb79bae 97
6c139d6e 98 if (ParseDepends(Ver,"Depends",pkgCache::Dep::Depends) == false)
dcb79bae 99 return false;
8efa2a3b 100 if (ParseDepends(Ver,"Pre-Depends",pkgCache::Dep::PreDepends) == false)
dcb79bae 101 return false;
6c139d6e 102 if (ParseDepends(Ver,"Suggests",pkgCache::Dep::Suggests) == false)
dcb79bae 103 return false;
6c139d6e 104 if (ParseDepends(Ver,"Recommends",pkgCache::Dep::Recommends) == false)
dcb79bae 105 return false;
6c139d6e 106 if (ParseDepends(Ver,"Conflicts",pkgCache::Dep::Conflicts) == false)
dcb79bae 107 return false;
308c7d30
IJ
108 if (ParseDepends(Ver,"Breaks",pkgCache::Dep::DpkgBreaks) == false)
109 return false;
f55ece0e 110 if (ParseDepends(Ver,"Replaces",pkgCache::Dep::Replaces) == false)
dcb79bae 111 return false;
f8ae7e8b 112 if (ParseDepends(Ver,"Enhances",pkgCache::Dep::Enhances) == false)
113 return false;
dcb79bae 114
b2e465d6
AL
115 // Obsolete.
116 if (ParseDepends(Ver,"Optional",pkgCache::Dep::Suggests) == false)
117 return false;
118
dcb79bae
AL
119 if (ParseProvides(Ver) == false)
120 return false;
0149949b 121
f55a958f
AL
122 return true;
123}
124 /*}}}*/
a52f938b
OS
125// ListParser::Description - Return the description string /*{{{*/
126// ---------------------------------------------------------------------
127/* This is to return the string describing the package in debian
128 form. If this returns the blank string then the entry is assumed to
129 only describe package properties */
130string debListParser::Description()
131{
45df0ad2
DK
132 string const lang = DescriptionLanguage();
133 if (lang.empty())
a52f938b
OS
134 return Section.FindS("Description");
135 else
45df0ad2 136 return Section.FindS(string("Description-").append(lang).c_str());
a52f938b
OS
137}
138 /*}}}*/
139// ListParser::DescriptionLanguage - Return the description lang string /*{{{*/
140// ---------------------------------------------------------------------
141/* This is to return the string describing the language of
142 description. If this returns the blank string then the entry is
143 assumed to describe original description. */
144string debListParser::DescriptionLanguage()
145{
45df0ad2
DK
146 if (Section.FindS("Description").empty() == false)
147 return "";
148
149 std::vector<string> const lang = APT::Configuration::getLanguages();
150 for (std::vector<string>::const_iterator l = lang.begin();
151 l != lang.end(); l++)
152 if (Section.FindS(string("Description-").append(*l).c_str()).empty() == false)
153 return *l;
154
155 return "";
a52f938b
OS
156}
157 /*}}}*/
158// ListParser::Description - Return the description_md5 MD5SumValue /*{{{*/
159// ---------------------------------------------------------------------
770c32ec
MV
160/* This is to return the md5 string to allow the check if it is the right
161 description. If no Description-md5 is found in the section it will be
162 calculated.
163 */
a52f938b
OS
164MD5SumValue debListParser::Description_md5()
165{
166 string value = Section.FindS("Description-md5");
167
770c32ec
MV
168 if (value.empty())
169 {
a52f938b
OS
170 MD5Summation md5;
171 md5.Add((Description() + "\n").c_str());
172 return md5.Result();
173 } else
174 return MD5SumValue(value);
175}
176 /*}}}*/
f55a958f
AL
177// ListParser::UsePackage - Update a package structure /*{{{*/
178// ---------------------------------------------------------------------
179/* This is called to update the package with any new information
180 that might be found in the section */
181bool debListParser::UsePackage(pkgCache::PkgIterator Pkg,
182 pkgCache::VerIterator Ver)
183{
184 if (Pkg->Section == 0)
b35d2f5f 185 Pkg->Section = UniqFindTagWrite("Section");
b0b4efb9 186 if (Section.FindFlag("Essential",Pkg->Flags,pkgCache::Flag::Essential) == false)
f55a958f 187 return false;
138d4b3d 188 if (Section.FindFlag("Important",Pkg->Flags,pkgCache::Flag::Important) == false)
f55a958f 189 return false;
138d4b3d
AL
190
191 if (strcmp(Pkg.Name(),"apt") == 0)
192 Pkg->Flags |= pkgCache::Flag::Important;
193
f55a958f
AL
194 if (ParseStatus(Pkg,Ver) == false)
195 return false;
196 return true;
197}
198 /*}}}*/
204fbdcc
AL
199// ListParser::VersionHash - Compute a unique hash for this version /*{{{*/
200// ---------------------------------------------------------------------
201/* */
202unsigned short debListParser::VersionHash()
203{
204 const char *Sections[] ={"Installed-Size",
205 "Depends",
206 "Pre-Depends",
f78439bf
AL
207// "Suggests",
208// "Recommends",
204fbdcc 209 "Conflicts",
308c7d30 210 "Breaks",
204fbdcc
AL
211 "Replaces",0};
212 unsigned long Result = INIT_FCS;
418a471f 213 char S[1024];
204fbdcc
AL
214 for (const char **I = Sections; *I != 0; I++)
215 {
216 const char *Start;
217 const char *End;
218 if (Section.Find(*I,Start,End) == false || End - Start >= (signed)sizeof(S))
219 continue;
220
221 /* Strip out any spaces from the text, this undoes dpkgs reformatting
421c8d10
AL
222 of certain fields. dpkg also has the rather interesting notion of
223 reformatting depends operators < -> <= */
204fbdcc
AL
224 char *I = S;
225 for (; Start != End; Start++)
421c8d10 226 {
204fbdcc 227 if (isspace(*Start) == 0)
4e86942a 228 *I++ = tolower_ascii(*Start);
421c8d10
AL
229 if (*Start == '<' && Start[1] != '<' && Start[1] != '=')
230 *I++ = '=';
231 if (*Start == '>' && Start[1] != '>' && Start[1] != '=')
232 *I++ = '=';
233 }
418a471f 234
204fbdcc
AL
235 Result = AddCRC16(Result,S,I - S);
236 }
237
238 return Result;
239}
240 /*}}}*/
dcb79bae 241// ListParser::ParseStatus - Parse the status field /*{{{*/
f55a958f
AL
242// ---------------------------------------------------------------------
243/* Status lines are of the form,
244 Status: want flag status
245 want = unknown, install, hold, deinstall, purge
246 flag = ok, reinstreq, hold, hold-reinstreq
a005475e 247 status = not-installed, unpacked, half-configured,
f55a958f
AL
248 half-installed, config-files, post-inst-failed,
249 removal-failed, installed
250
251 Some of the above are obsolete (I think?) flag = hold-* and
252 status = post-inst-failed, removal-failed at least.
253 */
254bool debListParser::ParseStatus(pkgCache::PkgIterator Pkg,
255 pkgCache::VerIterator Ver)
256{
257 const char *Start;
258 const char *Stop;
259 if (Section.Find("Status",Start,Stop) == false)
260 return true;
261
262 // Isolate the first word
263 const char *I = Start;
264 for(; I < Stop && *I != ' '; I++);
265 if (I >= Stop || *I != ' ')
266 return _error->Error("Malformed Status line");
267
268 // Process the want field
6c139d6e
AL
269 WordList WantList[] = {{"unknown",pkgCache::State::Unknown},
270 {"install",pkgCache::State::Install},
271 {"hold",pkgCache::State::Hold},
272 {"deinstall",pkgCache::State::DeInstall},
b2e465d6
AL
273 {"purge",pkgCache::State::Purge},
274 {}};
275 if (GrabWord(string(Start,I-Start),WantList,Pkg->SelectedState) == false)
f55a958f
AL
276 return _error->Error("Malformed 1st word in the Status line");
277
278 // Isloate the next word
279 I++;
280 Start = I;
281 for(; I < Stop && *I != ' '; I++);
282 if (I >= Stop || *I != ' ')
283 return _error->Error("Malformed status line, no 2nd word");
284
285 // Process the flag field
6c139d6e
AL
286 WordList FlagList[] = {{"ok",pkgCache::State::Ok},
287 {"reinstreq",pkgCache::State::ReInstReq},
288 {"hold",pkgCache::State::HoldInst},
b2e465d6
AL
289 {"hold-reinstreq",pkgCache::State::HoldReInstReq},
290 {}};
291 if (GrabWord(string(Start,I-Start),FlagList,Pkg->InstState) == false)
f55a958f
AL
292 return _error->Error("Malformed 2nd word in the Status line");
293
294 // Isloate the last word
295 I++;
296 Start = I;
297 for(; I < Stop && *I != ' '; I++);
298 if (I != Stop)
299 return _error->Error("Malformed Status line, no 3rd word");
300
301 // Process the flag field
6c139d6e
AL
302 WordList StatusList[] = {{"not-installed",pkgCache::State::NotInstalled},
303 {"unpacked",pkgCache::State::UnPacked},
304 {"half-configured",pkgCache::State::HalfConfigured},
305 {"installed",pkgCache::State::Installed},
6c139d6e
AL
306 {"half-installed",pkgCache::State::HalfInstalled},
307 {"config-files",pkgCache::State::ConfigFiles},
9d06bc80
MV
308 {"triggers-awaited",pkgCache::State::TriggersAwaited},
309 {"triggers-pending",pkgCache::State::TriggersPending},
6c139d6e 310 {"post-inst-failed",pkgCache::State::HalfConfigured},
b2e465d6
AL
311 {"removal-failed",pkgCache::State::HalfInstalled},
312 {}};
313 if (GrabWord(string(Start,I-Start),StatusList,Pkg->CurrentState) == false)
f55a958f
AL
314 return _error->Error("Malformed 3rd word in the Status line");
315
316 /* A Status line marks the package as indicating the current
317 version as well. Only if it is actually installed.. Otherwise
318 the interesting dpkg handling of the status file creates bogus
319 entries. */
6c139d6e
AL
320 if (!(Pkg->CurrentState == pkgCache::State::NotInstalled ||
321 Pkg->CurrentState == pkgCache::State::ConfigFiles))
f55a958f
AL
322 {
323 if (Ver.end() == true)
324 _error->Warning("Encountered status field in a non-version description");
325 else
326 Pkg->CurrentVer = Ver.Index();
327 }
328
dcb79bae
AL
329 return true;
330}
a1826878 331
b2e465d6
AL
332const char *debListParser::ConvertRelation(const char *I,unsigned int &Op)
333{
334 // Determine the operator
335 switch (*I)
336 {
337 case '<':
338 I++;
339 if (*I == '=')
340 {
341 I++;
342 Op = pkgCache::Dep::LessEq;
343 break;
344 }
345
346 if (*I == '<')
347 {
348 I++;
349 Op = pkgCache::Dep::Less;
350 break;
351 }
352
353 // < is the same as <= and << is really Cs < for some reason
354 Op = pkgCache::Dep::LessEq;
355 break;
356
357 case '>':
358 I++;
359 if (*I == '=')
360 {
361 I++;
362 Op = pkgCache::Dep::GreaterEq;
363 break;
364 }
365
366 if (*I == '>')
367 {
368 I++;
369 Op = pkgCache::Dep::Greater;
370 break;
371 }
372
373 // > is the same as >= and >> is really Cs > for some reason
374 Op = pkgCache::Dep::GreaterEq;
375 break;
376
377 case '=':
378 Op = pkgCache::Dep::Equals;
379 I++;
380 break;
381
382 // HACK around bad package definitions
383 default:
384 Op = pkgCache::Dep::Equals;
385 break;
386 }
387 return I;
388}
389
a1826878
AL
390 /*}}}*/
391// ListParser::ParseDepends - Parse a dependency element /*{{{*/
392// ---------------------------------------------------------------------
393/* This parses the dependency elements out of a standard string in place,
394 bit by bit. */
dcb79bae
AL
395const char *debListParser::ParseDepends(const char *Start,const char *Stop,
396 string &Package,string &Ver,
41c81fd8
DK
397 unsigned int &Op, bool const &ParseArchFlags,
398 bool const &StripMultiArch)
dcb79bae
AL
399{
400 // Strip off leading space
401 for (;Start != Stop && isspace(*Start) != 0; Start++);
402
403 // Parse off the package name
404 const char *I = Start;
405 for (;I != Stop && isspace(*I) == 0 && *I != '(' && *I != ')' &&
406 *I != ',' && *I != '|'; I++);
407
408 // Malformed, no '('
409 if (I != Stop && *I == ')')
410 return 0;
411
412 if (I == Start)
413 return 0;
414
415 // Stash the package name
416 Package.assign(Start,I - Start);
41c81fd8
DK
417
418 // We don't want to confuse library users which can't handle MultiArch
419 if (StripMultiArch == true) {
420 size_t const found = Package.rfind(':');
421 if (found != string::npos)
422 Package = Package.substr(0,found);
423 }
424
dcb79bae
AL
425 // Skip white space to the '('
426 for (;I != Stop && isspace(*I) != 0 ; I++);
427
428 // Parse a version
429 if (I != Stop && *I == '(')
430 {
431 // Skip the '('
432 for (I++; I != Stop && isspace(*I) != 0 ; I++);
433 if (I + 3 >= Stop)
434 return 0;
b2e465d6 435 I = ConvertRelation(I,Op);
dcb79bae
AL
436
437 // Skip whitespace
438 for (;I != Stop && isspace(*I) != 0; I++);
439 Start = I;
440 for (;I != Stop && *I != ')'; I++);
441 if (I == Stop || Start == I)
442 return 0;
443
02f000a9
AL
444 // Skip trailing whitespace
445 const char *End = I;
446 for (; End > Start && isspace(End[-1]); End--);
447
171c75f1 448 Ver.assign(Start,End-Start);
dcb79bae
AL
449 I++;
450 }
451 else
452 {
171c75f1 453 Ver.clear();
6c139d6e 454 Op = pkgCache::Dep::NoOp;
dcb79bae
AL
455 }
456
457 // Skip whitespace
458 for (;I != Stop && isspace(*I) != 0; I++);
b2e465d6
AL
459
460 if (ParseArchFlags == true)
461 {
462 string arch = _config->Find("APT::Architecture");
9e10ad8a 463
b2e465d6
AL
464 // Parse an architecture
465 if (I != Stop && *I == '[')
466 {
467 // malformed
468 I++;
469 if (I == Stop)
470 return 0;
471
472 const char *End = I;
473 bool Found = false;
9e10ad8a 474 bool NegArch = false;
b2e465d6
AL
475 while (I != Stop)
476 {
477 // look for whitespace or ending ']'
478 while (End != Stop && !isspace(*End) && *End != ']')
479 End++;
480
481 if (End == Stop)
482 return 0;
9e10ad8a
AL
483
484 if (*I == '!')
485 {
486 NegArch = true;
487 I++;
488 }
489
3e18cc75 490 if (stringcmp(arch,I,End) == 0)
b2e465d6
AL
491 Found = true;
492
493 if (*End++ == ']') {
494 I = End;
495 break;
496 }
497
498 I = End;
499 for (;I != Stop && isspace(*I) != 0; I++);
500 }
9e10ad8a
AL
501
502 if (NegArch)
503 Found = !Found;
b2e465d6 504
9e10ad8a 505 if (Found == false)
b2e465d6
AL
506 Package = ""; /* not for this arch */
507 }
508
509 // Skip whitespace
510 for (;I != Stop && isspace(*I) != 0; I++);
511 }
512
dcb79bae 513 if (I != Stop && *I == '|')
6c139d6e 514 Op |= pkgCache::Dep::Or;
dcb79bae
AL
515
516 if (I == Stop || *I == ',' || *I == '|')
517 {
518 if (I != Stop)
519 for (I++; I != Stop && isspace(*I) != 0; I++);
520 return I;
521 }
522
523 return 0;
524}
525 /*}}}*/
526// ListParser::ParseDepends - Parse a dependency list /*{{{*/
527// ---------------------------------------------------------------------
528/* This is the higher level depends parser. It takes a tag and generates
529 a complete depends tree for the given version. */
530bool debListParser::ParseDepends(pkgCache::VerIterator Ver,
531 const char *Tag,unsigned int Type)
532{
533 const char *Start;
534 const char *Stop;
535 if (Section.Find(Tag,Start,Stop) == false)
536 return true;
537
538 string Package;
539 string Version;
540 unsigned int Op;
541
8efa2a3b 542 while (1)
dcb79bae 543 {
8efa2a3b 544 Start = ParseDepends(Start,Stop,Package,Version,Op);
dcb79bae
AL
545 if (Start == 0)
546 return _error->Error("Problem parsing dependency %s",Tag);
8efa2a3b 547
dcb79bae
AL
548 if (NewDepends(Ver,Package,Version,Op,Type) == false)
549 return false;
8efa2a3b
AL
550 if (Start == Stop)
551 break;
dcb79bae
AL
552 }
553 return true;
554}
555 /*}}}*/
556// ListParser::ParseProvides - Parse the provides list /*{{{*/
557// ---------------------------------------------------------------------
558/* */
559bool debListParser::ParseProvides(pkgCache::VerIterator Ver)
560{
561 const char *Start;
562 const char *Stop;
563 if (Section.Find("Provides",Start,Stop) == false)
564 return true;
565
566 string Package;
567 string Version;
568 unsigned int Op;
569
570 while (1)
571 {
572 Start = ParseDepends(Start,Stop,Package,Version,Op);
573 if (Start == 0)
574 return _error->Error("Problem parsing Provides line");
b63380b0
MV
575 if (Op != pkgCache::Dep::NoOp) {
576 _error->Warning("Ignoring Provides line with DepCompareOp for package %s", Package.c_str());
577 } else {
578 if (NewProvides(Ver,Package,Version) == false)
579 return false;
580 }
dcb79bae
AL
581
582 if (Start == Stop)
583 break;
584 }
585
f55a958f
AL
586 return true;
587}
588 /*}}}*/
589// ListParser::GrabWord - Matches a word and returns /*{{{*/
590// ---------------------------------------------------------------------
591/* Looks for a word in a list of words - for ParseStatus */
b2e465d6 592bool debListParser::GrabWord(string Word,WordList *List,unsigned char &Out)
f55a958f 593{
b2e465d6 594 for (unsigned int C = 0; List[C].Str != 0; C++)
f55a958f
AL
595 {
596 if (strcasecmp(Word.c_str(),List[C].Str) == 0)
597 {
598 Out = List[C].Val;
599 return true;
600 }
601 }
602 return false;
603}
604 /*}}}*/
605// ListParser::Step - Move to the next section in the file /*{{{*/
606// ---------------------------------------------------------------------
0149949b 607/* This has to be carefull to only process the correct architecture */
f55a958f
AL
608bool debListParser::Step()
609{
dcb79bae 610 iOffset = Tags.Offset();
0149949b 611 while (Tags.Step(Section) == true)
ddc1d8d0
AL
612 {
613 /* See if this is the correct Architecture, if it isn't then we
614 drop the whole section. A missing arch tag only happens (in theory)
615 inside the Status file, so that is a positive return */
0149949b
AL
616 const char *Start;
617 const char *Stop;
618 if (Section.Find("Architecture",Start,Stop) == false)
619 return true;
9c14e3d6 620
3e18cc75 621 if (stringcmp(Arch,Start,Stop) == 0)
0149949b
AL
622 return true;
623
9c14e3d6 624 if (stringcmp(Start,Stop,"all") == 0)
0149949b 625 return true;
dcb79bae
AL
626
627 iOffset = Tags.Offset();
0149949b
AL
628 }
629 return false;
f55a958f
AL
630}
631 /*}}}*/
b0b4efb9
AL
632// ListParser::LoadReleaseInfo - Load the release information /*{{{*/
633// ---------------------------------------------------------------------
634/* */
635bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator FileI,
f2152f03 636 FileFd &File, string component)
b0b4efb9 637{
b3d44315 638 pkgTagFile Tags(&File, File.Size() + 256); // XXX
b0b4efb9
AL
639 pkgTagSection Section;
640 if (Tags.Step(Section) == false)
641 return false;
642
f2152f03
MV
643 //mvo: I don't think we need to fill that in (it's unused since apt-0.6)
644 //FileI->Architecture = WriteUniqString(Arch);
645
646 // apt-secure does no longer download individual (per-section) Release
647 // file. to provide Component pinning we use the section name now
648 FileI->Component = WriteUniqString(component);
649
b0b4efb9
AL
650 const char *Start;
651 const char *Stop;
b3d44315 652 if (Section.Find("Suite",Start,Stop) == true)
b0b4efb9
AL
653 FileI->Archive = WriteUniqString(Start,Stop - Start);
654 if (Section.Find("Component",Start,Stop) == true)
655 FileI->Component = WriteUniqString(Start,Stop - Start);
656 if (Section.Find("Version",Start,Stop) == true)
657 FileI->Version = WriteUniqString(Start,Stop - Start);
658 if (Section.Find("Origin",Start,Stop) == true)
659 FileI->Origin = WriteUniqString(Start,Stop - Start);
efc487fb
DK
660 if (Section.Find("Codename",Start,Stop) == true)
661 FileI->Codename = WriteUniqString(Start,Stop - Start);
b0b4efb9
AL
662 if (Section.Find("Label",Start,Stop) == true)
663 FileI->Label = WriteUniqString(Start,Stop - Start);
664 if (Section.Find("Architecture",Start,Stop) == true)
665 FileI->Architecture = WriteUniqString(Start,Stop - Start);
0dbb95d8 666
3c124dde
AL
667 if (Section.FindFlag("NotAutomatic",FileI->Flags,
668 pkgCache::Flag::NotAutomatic) == false)
0dbb95d8 669 _error->Warning("Bad NotAutomatic flag");
f2152f03 670
b0b4efb9
AL
671 return !_error->PendingError();
672}
673 /*}}}*/
b2e465d6
AL
674// ListParser::GetPrio - Convert the priority from a string /*{{{*/
675// ---------------------------------------------------------------------
676/* */
677unsigned char debListParser::GetPrio(string Str)
678{
679 unsigned char Out;
680 if (GrabWord(Str,PrioList,Out) == false)
681 Out = pkgCache::State::Extra;
682
683 return Out;
684}
685 /*}}}*/