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