]> git.saurik.com Git - apt-legacy.git/blob - apt-pkg/deb/deblistparser.cc
Remove code that isn't being used with Apple http.
[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 {
249 /* Strip out any spaces from the text, this undoes dpkgs reformatting
250 of certain fields. dpkg also has the rather interesting notion of
251 reformatting depends operators < -> <= */
252 char *I = S;
253 for (; Start != End; Start++)
254 {
255 if (isspace(*Start) == 0)
256 *I++ = tolower_ascii(*Start);
257 if (*Start == '<' && Start[1] != '<' && Start[1] != '=')
258 *I++ = '=';
259 if (*Start == '>' && Start[1] != '>' && Start[1] != '=')
260 *I++ = '=';
261 }
262
263 Result = AddCRC16(Result,S,I - S);
264 }
265 }
266
267 return Result;
268 }
269 /*}}}*/
270 // ListParser::ParseStatus - Parse the status field /*{{{*/
271 // ---------------------------------------------------------------------
272 /* Status lines are of the form,
273 Status: want flag status
274 want = unknown, install, hold, deinstall, purge
275 flag = ok, reinstreq, hold, hold-reinstreq
276 status = not-installed, unpacked, half-configured,
277 half-installed, config-files, post-inst-failed,
278 removal-failed, installed
279
280 Some of the above are obsolete (I think?) flag = hold-* and
281 status = post-inst-failed, removal-failed at least.
282 */
283 bool debListParser::ParseStatus(pkgCache::PkgIterator Pkg,
284 pkgCache::VerIterator Ver)
285 {
286 const char *Start;
287 const char *Stop;
288 if (Section.Find("Status",Start,Stop) == false)
289 return true;
290
291 // Isolate the first word
292 const char *I = Start;
293 for(; I < Stop && *I != ' '; I++);
294 if (I >= Stop || *I != ' ')
295 return _error->Error("Malformed Status line");
296
297 // Process the want field
298 WordList WantList[] = {{"unknown",pkgCache::State::Unknown},
299 {"install",pkgCache::State::Install},
300 {"hold",pkgCache::State::Hold},
301 {"deinstall",pkgCache::State::DeInstall},
302 {"purge",pkgCache::State::Purge},
303 {}};
304 if (GrabWord(srkString(Start,I-Start),WantList,Pkg->SelectedState) == false)
305 return _error->Error("Malformed 1st word in the Status line");
306
307 // Isloate the next word
308 I++;
309 Start = I;
310 for(; I < Stop && *I != ' '; I++);
311 if (I >= Stop || *I != ' ')
312 return _error->Error("Malformed status line, no 2nd word");
313
314 // Process the flag field
315 WordList FlagList[] = {{"ok",pkgCache::State::Ok},
316 {"reinstreq",pkgCache::State::ReInstReq},
317 {"hold",pkgCache::State::HoldInst},
318 {"hold-reinstreq",pkgCache::State::HoldReInstReq},
319 {}};
320 if (GrabWord(srkString(Start,I-Start),FlagList,Pkg->InstState) == false)
321 return _error->Error("Malformed 2nd word in the Status line");
322
323 // Isloate the last word
324 I++;
325 Start = I;
326 for(; I < Stop && *I != ' '; I++);
327 if (I != Stop)
328 return _error->Error("Malformed Status line, no 3rd word");
329
330 // Process the flag field
331 WordList StatusList[] = {{"not-installed",pkgCache::State::NotInstalled},
332 {"unpacked",pkgCache::State::UnPacked},
333 {"half-configured",pkgCache::State::HalfConfigured},
334 {"installed",pkgCache::State::Installed},
335 {"half-installed",pkgCache::State::HalfInstalled},
336 {"config-files",pkgCache::State::ConfigFiles},
337 {"triggers-awaited",pkgCache::State::TriggersAwaited},
338 {"triggers-pending",pkgCache::State::TriggersPending},
339 {"post-inst-failed",pkgCache::State::HalfConfigured},
340 {"removal-failed",pkgCache::State::HalfInstalled},
341 {}};
342 if (GrabWord(srkString(Start,I-Start),StatusList,Pkg->CurrentState) == false)
343 return _error->Error("Malformed 3rd word in the Status line");
344
345 /* A Status line marks the package as indicating the current
346 version as well. Only if it is actually installed.. Otherwise
347 the interesting dpkg handling of the status file creates bogus
348 entries. */
349 if (!(Pkg->CurrentState == pkgCache::State::NotInstalled ||
350 Pkg->CurrentState == pkgCache::State::ConfigFiles))
351 {
352 if (Ver.end() == true)
353 _error->Warning("Encountered status field in a non-version description");
354 else
355 Pkg->CurrentVer = Ver.Index();
356 }
357
358 return true;
359 }
360
361 const char *debListParser::ConvertRelation(const char *I,unsigned int &Op)
362 {
363 // Determine the operator
364 switch (*I)
365 {
366 case '<':
367 I++;
368 if (*I == '=')
369 {
370 I++;
371 Op = pkgCache::Dep::LessEq;
372 break;
373 }
374
375 if (*I == '<')
376 {
377 I++;
378 Op = pkgCache::Dep::Less;
379 break;
380 }
381
382 // < is the same as <= and << is really Cs < for some reason
383 Op = pkgCache::Dep::LessEq;
384 break;
385
386 case '>':
387 I++;
388 if (*I == '=')
389 {
390 I++;
391 Op = pkgCache::Dep::GreaterEq;
392 break;
393 }
394
395 if (*I == '>')
396 {
397 I++;
398 Op = pkgCache::Dep::Greater;
399 break;
400 }
401
402 // > is the same as >= and >> is really Cs > for some reason
403 Op = pkgCache::Dep::GreaterEq;
404 break;
405
406 case '=':
407 Op = pkgCache::Dep::Equals;
408 I++;
409 break;
410
411 // HACK around bad package definitions
412 default:
413 Op = pkgCache::Dep::Equals;
414 break;
415 }
416 return I;
417 }
418
419 /*}}}*/
420 // ListParser::ParseDepends - Parse a dependency element /*{{{*/
421 // ---------------------------------------------------------------------
422 /* This parses the dependency elements out of a standard string in place,
423 bit by bit. */
424 const char *debListParser::ParseDepends(const char *Start,const char *Stop,
425 string &Package,string &Ver,
426 unsigned int &Op, bool ParseArchFlags)
427 {
428 srkString cPackage, cVer;
429 const char *Value = ParseDepends(Start, Stop, cPackage, cVer, Op, ParseArchFlags);
430 Package = cPackage;
431 Ver = cVer;
432 return Value;
433 }
434
435 const char *debListParser::ParseDepends(const char *Start,const char *Stop,
436 srkString &Package,srkString &Ver,
437 unsigned int &Op, bool ParseArchFlags)
438 {
439 // Strip off leading space
440 for (;Start != Stop && isspace(*Start) != 0; Start++);
441
442 // Parse off the package name
443 const char *I = Start;
444 for (;I != Stop && isspace(*I) == 0 && *I != '(' && *I != ')' &&
445 *I != ',' && *I != '|'; I++);
446
447 // Malformed, no '('
448 if (I != Stop && *I == ')')
449 return 0;
450
451 if (I == Start)
452 return 0;
453
454 // Stash the package name
455 Package.assign(Start,I - Start);
456
457 // Skip white space to the '('
458 for (;I != Stop && isspace(*I) != 0 ; I++);
459
460 // Parse a version
461 if (I != Stop && *I == '(')
462 {
463 // Skip the '('
464 for (I++; I != Stop && isspace(*I) != 0 ; I++);
465 if (I + 3 >= Stop)
466 return 0;
467 I = ConvertRelation(I,Op);
468
469 // Skip whitespace
470 for (;I != Stop && isspace(*I) != 0; I++);
471 Start = I;
472 for (;I != Stop && *I != ')'; I++);
473 if (I == Stop || Start == I)
474 return 0;
475
476 // Skip trailing whitespace
477 const char *End = I;
478 for (; End > Start && isspace(End[-1]); End--);
479
480 Ver.assign(Start,End-Start);
481 I++;
482 }
483 else
484 {
485 Ver.clear();
486 Op = pkgCache::Dep::NoOp;
487 }
488
489 // Skip whitespace
490 for (;I != Stop && isspace(*I) != 0; I++);
491
492 if (ParseArchFlags == true)
493 {
494 string arch = _config->Find("APT::Architecture");
495
496 // Parse an architecture
497 if (I != Stop && *I == '[')
498 {
499 // malformed
500 I++;
501 if (I == Stop)
502 return 0;
503
504 const char *End = I;
505 bool Found = false;
506 bool NegArch = false;
507 while (I != Stop)
508 {
509 // look for whitespace or ending ']'
510 while (End != Stop && !isspace(*End) && *End != ']')
511 End++;
512
513 if (End == Stop)
514 return 0;
515
516 if (*I == '!')
517 {
518 NegArch = true;
519 I++;
520 }
521
522 if (stringcmp(arch,I,End) == 0)
523 Found = true;
524
525 if (*End++ == ']') {
526 I = End;
527 break;
528 }
529
530 I = End;
531 for (;I != Stop && isspace(*I) != 0; I++);
532 }
533
534 if (NegArch)
535 Found = !Found;
536
537 if (Found == false)
538 Package.clear(); /* not for this arch */
539 }
540
541 // Skip whitespace
542 for (;I != Stop && isspace(*I) != 0; I++);
543 }
544
545 if (I != Stop && *I == '|')
546 Op |= pkgCache::Dep::Or;
547
548 if (I == Stop || *I == ',' || *I == '|')
549 {
550 if (I != Stop)
551 for (I++; I != Stop && isspace(*I) != 0; I++);
552 return I;
553 }
554
555 return 0;
556 }
557 /*}}}*/
558 // ListParser::ParseDepends - Parse a dependency list /*{{{*/
559 // ---------------------------------------------------------------------
560 /* This is the higher level depends parser. It takes a tag and generates
561 a complete depends tree for the given version. */
562 bool debListParser::ParseDepends(pkgCache::VerIterator Ver,
563 const char *Tag,unsigned int Type)
564 {
565 const char *Start;
566 const char *Stop;
567 if (Section.Find(Tag,Start,Stop) == false)
568 return true;
569
570 srkString Package;
571 srkString Version;
572 unsigned int Op;
573
574 while (1)
575 {
576 Start = ParseDepends(Start,Stop,Package,Version,Op);
577 if (Start == 0) {
578 _error->Warning("Problem parsing dependency %s",Tag);
579 return false;
580 }
581
582 if (NewDepends(Ver,Package,Version,Op,Type) == false)
583 return false;
584 if (Start == Stop)
585 break;
586 }
587 return true;
588 }
589 /*}}}*/
590 // ListParser::ParseProvides - Parse the provides list /*{{{*/
591 // ---------------------------------------------------------------------
592 /* */
593 bool debListParser::ParseProvides(pkgCache::VerIterator Ver)
594 {
595 const char *Start;
596 const char *Stop;
597 if (Section.Find("Provides",Start,Stop) == false)
598 return true;
599
600 srkString Package;
601 srkString Version;
602 unsigned int Op;
603
604 while (1)
605 {
606 Start = ParseDepends(Start,Stop,Package,Version,Op);
607 if (Start == 0) {
608 _error->Warning("Problem parsing Provides line");
609 return false;
610 }
611
612 if (Op != pkgCache::Dep::NoOp) {
613 _error->Warning("Ignoring Provides line with DepCompareOp for package %s", std::string(Package).c_str());
614 } else {
615 if (NewProvides(Ver,Package,Version) == false)
616 return false;
617 }
618
619 if (Start == Stop)
620 break;
621 }
622
623 return true;
624 }
625 /*}}}*/
626 // ListParser::ParseTag - Parse the tag list /*{{{*/
627 // ---------------------------------------------------------------------
628 /* */
629 bool debListParser::ParseTag(pkgCache::PkgIterator Pkg)
630 {
631 const char *Start;
632 const char *Stop;
633 if (Section.Find("Tag",Start,Stop) == false)
634 return true;
635
636 while (1) {
637 while (1) {
638 if (Start == Stop)
639 return true;
640 if (Stop[-1] != ' ' && Stop[-1] != '\t')
641 break;
642 --Stop;
643 }
644
645 const char *Begin = Stop - 1;
646 while (Begin != Start && Begin[-1] != ' ' && Begin[-1] != ',')
647 --Begin;
648
649 if (NewTag(Pkg, Begin, Stop - Begin) == false)
650 return false;
651
652 while (1) {
653 if (Begin == Start)
654 return true;
655 if (Begin[-1] == ',')
656 break;
657 --Begin;
658 }
659
660 Stop = Begin - 1;
661 }
662
663 return true;
664 }
665 /*}}}*/
666 // ListParser::GrabWord - Matches a word and returns /*{{{*/
667 // ---------------------------------------------------------------------
668 /* Looks for a word in a list of words - for ParseStatus */
669 bool debListParser::GrabWord(string Word,WordList *List,unsigned char &Out)
670 {
671 return GrabWord(srkString(Word), List, Out);
672 }
673
674 bool debListParser::GrabWord(const srkString &Word,WordList *List,unsigned char &Out)
675 {
676 for (unsigned int C = 0; List[C].Str != 0; C++)
677 {
678 if (strncasecmp(Word.Start,List[C].Str,Word.Size) == 0)
679 {
680 Out = List[C].Val;
681 return true;
682 }
683 }
684 return false;
685 }
686 /*}}}*/
687 // ListParser::Step - Move to the next section in the file /*{{{*/
688 // ---------------------------------------------------------------------
689 /* This has to be carefull to only process the correct architecture */
690 bool debListParser::Step()
691 {
692 iOffset = Tags.Offset();
693 while (Tags.Step(Section) == true)
694 {
695 const char *Start;
696 const char *Stop;
697
698 if (Section.Find("Package",Start,Stop) == false) {
699 _error->Warning("Encountered a section with no Package: header");
700 continue;
701 }
702
703 /* See if this is the correct Architecture, if it isn't then we
704 drop the whole section. A missing arch tag only happens (in theory)
705 inside the Status file, so that is a positive return */
706
707 if (Section.Find("Architecture",Start,Stop) == false)
708 return true;
709
710 if (stringcmp(Arch,Start,Stop) == 0)
711 return true;
712
713 if (stringcmp(Start,Stop,"all") == 0)
714 return true;
715
716 if (stringcmp(Start,Stop,"cydia") == 0)
717 return true;
718
719 iOffset = Tags.Offset();
720 }
721 return false;
722 }
723 /*}}}*/
724 // ListParser::LoadReleaseInfo - Load the release information /*{{{*/
725 // ---------------------------------------------------------------------
726 /* */
727 bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator FileI,
728 FileFd &File, string component)
729 {
730 pkgTagFile Tags(&File, File.Size() + 256); // XXX
731 pkgTagSection Section;
732 if (Tags.Step(Section) == false)
733 return false;
734
735 //mvo: I don't think we need to fill that in (it's unused since apt-0.6)
736 //FileI->Architecture = WriteUniqString(Arch);
737
738 // apt-secure does no longer download individual (per-section) Release
739 // file. to provide Component pinning we use the section name now
740 FileI->Component = WriteUniqString(component);
741
742 const char *Start;
743 const char *Stop;
744 if (Section.Find("Suite",Start,Stop) == true)
745 FileI->Archive = WriteUniqString(Start,Stop - Start);
746 if (Section.Find("Component",Start,Stop) == true)
747 FileI->Component = WriteUniqString(Start,Stop - Start);
748 if (Section.Find("Version",Start,Stop) == true)
749 FileI->Version = WriteUniqString(Start,Stop - Start);
750 if (Section.Find("Origin",Start,Stop) == true)
751 FileI->Origin = WriteUniqString(Start,Stop - Start);
752 if (Section.Find("Label",Start,Stop) == true)
753 FileI->Label = WriteUniqString(Start,Stop - Start);
754 if (Section.Find("Architecture",Start,Stop) == true)
755 FileI->Architecture = WriteUniqString(Start,Stop - Start);
756
757 if (Section.FindFlag("NotAutomatic",FileI->Flags,
758 pkgCache::Flag::NotAutomatic) == false)
759 _error->Warning("Bad NotAutomatic flag");
760
761 return !_error->PendingError();
762 }
763 /*}}}*/
764 // ListParser::GetPrio - Convert the priority from a string /*{{{*/
765 // ---------------------------------------------------------------------
766 /* */
767 unsigned char debListParser::GetPrio(string Str)
768 {
769 unsigned char Out;
770 if (GrabWord(Str,PrioList,Out) == false)
771 Out = pkgCache::State::Extra;
772
773 return Out;
774 }
775 /*}}}*/