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