]>
git.saurik.com Git - apt.git/blob - apt-pkg/deb/deblistparser.cc
   1 // -*- mode: cpp; mode: fold -*- 
   3 // $Id: deblistparser.cc,v 1.29.2.5 2004/01/06 01:43:44 mdz Exp $ 
   4 /* ###################################################################### 
   6    Package Cache Generator - Generator for the cache structure. 
   8    This builds the cache structure from the abstract package list parser.  
  10    ##################################################################### */ 
  12 // Include Files                                                        /*{{{*/ 
  13 #include <apt-pkg/deblistparser.h> 
  14 #include <apt-pkg/error.h> 
  15 #include <apt-pkg/configuration.h> 
  16 #include <apt-pkg/aptconfiguration.h> 
  17 #include <apt-pkg/strutl.h> 
  18 #include <apt-pkg/crc-16.h> 
  19 #include <apt-pkg/md5.h> 
  20 #include <apt-pkg/macros.h> 
  25 static 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
}, 
  32 // ListParser::debListParser - Constructor                              /*{{{*/ 
  33 // --------------------------------------------------------------------- 
  34 /* Provide an architecture and only this one and "all" will be accepted 
  35    in Step(), if no Architecture is given we will accept every arch 
  36    we would accept in general with checkArchitecture() */ 
  37 debListParser::debListParser(FileFd 
*File
, string 
const &Arch
) : Tags(File
), 
  40                 this->Arch 
= _config
->Find("APT::Architecture"); 
  43 // ListParser::UniqFindTagWrite - Find the tag and write a unq string   /*{{{*/ 
  44 // --------------------------------------------------------------------- 
  46 unsigned long debListParser::UniqFindTagWrite(const char *Tag
) 
  50    if (Section
.Find(Tag
,Start
,Stop
) == false) 
  52    return WriteUniqString(Start
,Stop 
- Start
); 
  55 // ListParser::Package - Return the package name                        /*{{{*/ 
  56 // --------------------------------------------------------------------- 
  57 /* This is to return the name of the package this section describes */ 
  58 string 
debListParser::Package() { 
  59         string 
const Result 
= Section
.FindS("Package"); 
  60         if(unlikely(Result
.empty() == true)) 
  61                 _error
->Error("Encountered a section with no Package: header"); 
  65 // ListParser::Architecture - Return the package arch                   /*{{{*/ 
  66 // --------------------------------------------------------------------- 
  67 /* This will return the Architecture of the package this section describes 
  68    Note that architecture "all" packages will get the architecture of the 
  69    Packages file parsed here. */ 
  70 string 
debListParser::Architecture() { 
  71         string 
const Result 
= Section
.FindS("Architecture"); 
  72         if (Result
.empty() == true || Result 
== "all") { 
  73                 if (Arch
.empty() == true) 
  74                         /* FIXME: this is a problem for installed arch all 
  75                            packages as we don't know from which arch this 
  76                            package was installed - and therefore which 
  77                            dependency this package resolves. */ 
  78                         return _config
->Find("APT::Architecture"); 
  85 // ListParser::ArchitectureAll                                          /*{{{*/ 
  86 // --------------------------------------------------------------------- 
  88 bool debListParser::ArchitectureAll() { 
  89         return Section
.FindS("Architecture") == "all"; 
  92 // ListParser::Version - Return the version string                      /*{{{*/ 
  93 // --------------------------------------------------------------------- 
  94 /* This is to return the string describing the version in debian form, 
  95    epoch:upstream-release. If this returns the blank string then the  
  96    entry is assumed to only describe package properties */ 
  97 string 
debListParser::Version() 
  99    return Section
.FindS("Version"); 
 102 // ListParser::NewVersion - Fill in the version structure               /*{{{*/ 
 103 // --------------------------------------------------------------------- 
 105 bool debListParser::NewVersion(pkgCache::VerIterator Ver
) 
 108    Ver
->Section 
= UniqFindTagWrite("Section"); 
 111    if (Section
.FindS("Architecture") == "all") 
 112       /* Arch all packages can't have a Multi-Arch field, 
 113          but we need a special treatment for them nonetheless */ 
 114       Ver
->MultiArch 
= pkgCache::Version::All
; 
 117       string 
const MultiArch 
= Section
.FindS("Multi-Arch"); 
 118       if (MultiArch
.empty() == true) 
 119          Ver
->MultiArch 
= pkgCache::Version::None
; 
 120       else if (MultiArch 
== "same") 
 121          Ver
->MultiArch 
= pkgCache::Version::Same
; 
 122       else if (MultiArch 
== "foreign") 
 123          Ver
->MultiArch 
= pkgCache::Version::Foreign
; 
 124       else if (MultiArch 
== "allowed") 
 125          Ver
->MultiArch 
= pkgCache::Version::Allowed
; 
 128          _error
->Warning("Unknown Multi-Arch type »%s« for package »%s«", 
 129                         MultiArch
.c_str(), Section
.FindS("Package").c_str()); 
 130          Ver
->MultiArch 
= pkgCache::Version::None
; 
 135    Ver
->Size 
= (unsigned)Section
.FindI("Size"); 
 137    // Unpacked Size (in K) 
 138    Ver
->InstalledSize 
= (unsigned)Section
.FindI("Installed-Size"); 
 139    Ver
->InstalledSize 
*= 1024; 
 144    if (Section
.Find("Priority",Start
,Stop
) == true) 
 146       if (GrabWord(string(Start
,Stop
-Start
),PrioList
,Ver
->Priority
) == false) 
 147          Ver
->Priority 
= pkgCache::State::Extra
; 
 150    if (Ver
->MultiArch 
== pkgCache::Version::All
) 
 152       /* We maintain a "pseudo" arch=all package for architecture all versions 
 153          on which these versions can depend on. This pseudo package is many used 
 154          for downloading/installing: The other pseudo-packages will degenerate 
 155          to a NOP in the download/install step - this package will ensure that 
 156          it is downloaded only one time and installed only one time -- even if 
 157          the architecture bound versions coming in and out on regular basis. */ 
 158       bool const static multiArch 
= APT::Configuration::getArchitectures().size() > 1; 
 159       if (strcmp(Ver
.Arch(true),"all") == 0) 
 161       else if (multiArch 
== true) 
 163          // our pseudo packages have no size to not confuse the fetcher 
 165          Ver
->InstalledSize 
= 0; 
 169    if (ParseDepends(Ver
,"Depends",pkgCache::Dep::Depends
) == false) 
 171    if (ParseDepends(Ver
,"Pre-Depends",pkgCache::Dep::PreDepends
) == false) 
 173    if (ParseDepends(Ver
,"Suggests",pkgCache::Dep::Suggests
) == false) 
 175    if (ParseDepends(Ver
,"Recommends",pkgCache::Dep::Recommends
) == false) 
 177    if (ParseDepends(Ver
,"Conflicts",pkgCache::Dep::Conflicts
) == false) 
 179    if (ParseDepends(Ver
,"Breaks",pkgCache::Dep::DpkgBreaks
) == false) 
 181    if (ParseDepends(Ver
,"Replaces",pkgCache::Dep::Replaces
) == false) 
 183    if (ParseDepends(Ver
,"Enhances",pkgCache::Dep::Enhances
) == false) 
 187    if (ParseDepends(Ver
,"Optional",pkgCache::Dep::Suggests
) == false) 
 190    if (ParseProvides(Ver
) == false) 
 196 // ListParser::Description - Return the description string              /*{{{*/ 
 197 // --------------------------------------------------------------------- 
 198 /* This is to return the string describing the package in debian 
 199    form. If this returns the blank string then the entry is assumed to 
 200    only describe package properties */ 
 201 string 
debListParser::Description() 
 203    string 
const lang 
= DescriptionLanguage(); 
 205       return Section
.FindS("Description"); 
 207       return Section
.FindS(string("Description-").append(lang
).c_str()); 
 210 // ListParser::DescriptionLanguage - Return the description lang string /*{{{*/ 
 211 // --------------------------------------------------------------------- 
 212 /* This is to return the string describing the language of 
 213    description. If this returns the blank string then the entry is 
 214    assumed to describe original description. */ 
 215 string 
debListParser::DescriptionLanguage() 
 217    if (Section
.FindS("Description").empty() == false) 
 220    std::vector
<string
> const lang 
= APT::Configuration::getLanguages(); 
 221    for (std::vector
<string
>::const_iterator l 
= lang
.begin(); 
 222         l 
!= lang
.end(); l
++) 
 223       if (Section
.FindS(string("Description-").append(*l
).c_str()).empty() == false) 
 229 // ListParser::Description - Return the description_md5 MD5SumValue     /*{{{*/ 
 230 // --------------------------------------------------------------------- 
 231 /* This is to return the md5 string to allow the check if it is the right 
 232    description. If no Description-md5 is found in the section it will be 
 235 MD5SumValue 
debListParser::Description_md5() 
 237    string value 
= Section
.FindS("Description-md5"); 
 242       md5
.Add((Description() + "\n").c_str()); 
 245       return MD5SumValue(value
); 
 248 // ListParser::UsePackage - Update a package structure                  /*{{{*/ 
 249 // --------------------------------------------------------------------- 
 250 /* This is called to update the package with any new information  
 251    that might be found in the section */ 
 252 bool debListParser::UsePackage(pkgCache::PkgIterator Pkg
, 
 253                                pkgCache::VerIterator Ver
) 
 255    if (Pkg
->Section 
== 0) 
 256       Pkg
->Section 
= UniqFindTagWrite("Section"); 
 258    // Packages which are not from "our" arch doesn't get the essential flag 
 259    string 
const static myArch 
= _config
->Find("APT::Architecture"); 
 260    if (Pkg
->Arch 
!= 0 && myArch 
== Pkg
.Arch()) 
 261       if (Section
.FindFlag("Essential",Pkg
->Flags
,pkgCache::Flag::Essential
) == false) 
 263    if (Section
.FindFlag("Important",Pkg
->Flags
,pkgCache::Flag::Important
) == false) 
 266    if (strcmp(Pkg
.Name(),"apt") == 0) 
 267       Pkg
->Flags 
|= pkgCache::Flag::Important
; 
 269    if (ParseStatus(Pkg
,Ver
) == false) 
 274 // ListParser::VersionHash - Compute a unique hash for this version     /*{{{*/ 
 275 // --------------------------------------------------------------------- 
 277 unsigned short debListParser::VersionHash() 
 279    const char *Sections
[] ={"Installed-Size", 
 287    unsigned long Result 
= INIT_FCS
; 
 289    for (const char **I 
= Sections
; *I 
!= 0; I
++) 
 293       if (Section
.Find(*I
,Start
,End
) == false || End 
- Start 
>= (signed)sizeof(S
)) 
 296       /* Strip out any spaces from the text, this undoes dpkgs reformatting 
 297          of certain fields. dpkg also has the rather interesting notion of 
 298          reformatting depends operators < -> <= */ 
 300       for (; Start 
!= End
; Start
++) 
 302          if (isspace(*Start
) == 0) 
 303             *I
++ = tolower_ascii(*Start
); 
 304          if (*Start 
== '<' && Start
[1] != '<' && Start
[1] != '=') 
 306          if (*Start 
== '>' && Start
[1] != '>' && Start
[1] != '=') 
 310       Result 
= AddCRC16(Result
,S
,I 
- S
); 
 316 // ListParser::ParseStatus - Parse the status field                     /*{{{*/ 
 317 // --------------------------------------------------------------------- 
 318 /* Status lines are of the form, 
 319      Status: want flag status 
 320    want = unknown, install, hold, deinstall, purge 
 321    flag = ok, reinstreq, hold, hold-reinstreq 
 322    status = not-installed, unpacked, half-configured, 
 323             half-installed, config-files, post-inst-failed,  
 324             removal-failed, installed 
 326    Some of the above are obsolete (I think?) flag = hold-* and  
 327    status = post-inst-failed, removal-failed at least. 
 329 bool debListParser::ParseStatus(pkgCache::PkgIterator Pkg
, 
 330                                 pkgCache::VerIterator Ver
) 
 334    if (Section
.Find("Status",Start
,Stop
) == false) 
 337    // Isolate the first word 
 338    const char *I 
= Start
; 
 339    for(; I 
< Stop 
&& *I 
!= ' '; I
++); 
 340    if (I 
>= Stop 
|| *I 
!= ' ') 
 341       return _error
->Error("Malformed Status line"); 
 343    // Process the want field 
 344    WordList WantList
[] = {{"unknown",pkgCache::State::Unknown
}, 
 345                           {"install",pkgCache::State::Install
}, 
 346                           {"hold",pkgCache::State::Hold
}, 
 347                           {"deinstall",pkgCache::State::DeInstall
}, 
 348                           {"purge",pkgCache::State::Purge
}, 
 350    if (GrabWord(string(Start
,I
-Start
),WantList
,Pkg
->SelectedState
) == false) 
 351       return _error
->Error("Malformed 1st word in the Status line"); 
 353    // Isloate the next word 
 356    for(; I 
< Stop 
&& *I 
!= ' '; I
++); 
 357    if (I 
>= Stop 
|| *I 
!= ' ') 
 358       return _error
->Error("Malformed status line, no 2nd word"); 
 360    // Process the flag field 
 361    WordList FlagList
[] = {{"ok",pkgCache::State::Ok
}, 
 362                           {"reinstreq",pkgCache::State::ReInstReq
}, 
 363                           {"hold",pkgCache::State::HoldInst
}, 
 364                           {"hold-reinstreq",pkgCache::State::HoldReInstReq
}, 
 366    if (GrabWord(string(Start
,I
-Start
),FlagList
,Pkg
->InstState
) == false) 
 367       return _error
->Error("Malformed 2nd word in the Status line"); 
 369    // Isloate the last word 
 372    for(; I 
< Stop 
&& *I 
!= ' '; I
++); 
 374       return _error
->Error("Malformed Status line, no 3rd word"); 
 376    // Process the flag field 
 377    WordList StatusList
[] = {{"not-installed",pkgCache::State::NotInstalled
}, 
 378                             {"unpacked",pkgCache::State::UnPacked
}, 
 379                             {"half-configured",pkgCache::State::HalfConfigured
}, 
 380                             {"installed",pkgCache::State::Installed
}, 
 381                             {"half-installed",pkgCache::State::HalfInstalled
}, 
 382                             {"config-files",pkgCache::State::ConfigFiles
}, 
 383                             {"triggers-awaited",pkgCache::State::TriggersAwaited
}, 
 384                             {"triggers-pending",pkgCache::State::TriggersPending
}, 
 385                             {"post-inst-failed",pkgCache::State::HalfConfigured
}, 
 386                             {"removal-failed",pkgCache::State::HalfInstalled
}, 
 388    if (GrabWord(string(Start
,I
-Start
),StatusList
,Pkg
->CurrentState
) == false) 
 389       return _error
->Error("Malformed 3rd word in the Status line"); 
 391    /* A Status line marks the package as indicating the current 
 392       version as well. Only if it is actually installed.. Otherwise 
 393       the interesting dpkg handling of the status file creates bogus  
 395    if (!(Pkg
->CurrentState 
== pkgCache::State::NotInstalled 
|| 
 396          Pkg
->CurrentState 
== pkgCache::State::ConfigFiles
)) 
 398       if (Ver
.end() == true) 
 399          _error
->Warning("Encountered status field in a non-version description"); 
 401          Pkg
->CurrentVer 
= Ver
.Index(); 
 407 const char *debListParser::ConvertRelation(const char *I
,unsigned int &Op
) 
 409    // Determine the operator 
 417          Op 
= pkgCache::Dep::LessEq
; 
 424          Op 
= pkgCache::Dep::Less
; 
 428       // < is the same as <= and << is really Cs < for some reason 
 429       Op 
= pkgCache::Dep::LessEq
; 
 437          Op 
= pkgCache::Dep::GreaterEq
; 
 444          Op 
= pkgCache::Dep::Greater
; 
 448       // > is the same as >= and >> is really Cs > for some reason 
 449       Op 
= pkgCache::Dep::GreaterEq
; 
 453       Op 
= pkgCache::Dep::Equals
; 
 457       // HACK around bad package definitions 
 459       Op 
= pkgCache::Dep::Equals
; 
 466 // ListParser::ParseDepends - Parse a dependency element                /*{{{*/ 
 467 // --------------------------------------------------------------------- 
 468 /* This parses the dependency elements out of a standard string in place, 
 470 const char *debListParser::ParseDepends(const char *Start
,const char *Stop
, 
 471                                         string 
&Package
,string 
&Ver
, 
 472                                         unsigned int &Op
, bool const &ParseArchFlags
, 
 473                                         bool const &StripMultiArch
) 
 475    // Strip off leading space 
 476    for (;Start 
!= Stop 
&& isspace(*Start
) != 0; Start
++); 
 478    // Parse off the package name 
 479    const char *I 
= Start
; 
 480    for (;I 
!= Stop 
&& isspace(*I
) == 0 && *I 
!= '(' && *I 
!= ')' && 
 481         *I 
!= ',' && *I 
!= '|'; I
++); 
 484    if (I 
!= Stop 
&& *I 
== ')') 
 490    // Stash the package name 
 491    Package
.assign(Start
,I 
- Start
); 
 493    // We don't want to confuse library users which can't handle MultiArch 
 494    if (StripMultiArch 
== true) { 
 495       size_t const found 
= Package
.rfind(':'); 
 496       if (found 
!= string::npos
) 
 497          Package 
= Package
.substr(0,found
); 
 500    // Skip white space to the '(' 
 501    for (;I 
!= Stop 
&& isspace(*I
) != 0 ; I
++); 
 504    if (I 
!= Stop 
&& *I 
== '(') 
 507       for (I
++; I 
!= Stop 
&& isspace(*I
) != 0 ; I
++); 
 510       I 
= ConvertRelation(I
,Op
); 
 513       for (;I 
!= Stop 
&& isspace(*I
) != 0; I
++); 
 515       for (;I 
!= Stop 
&& *I 
!= ')'; I
++); 
 516       if (I 
== Stop 
|| Start 
== I
) 
 519       // Skip trailing whitespace 
 521       for (; End 
> Start 
&& isspace(End
[-1]); End
--); 
 523       Ver
.assign(Start
,End
-Start
); 
 529       Op 
= pkgCache::Dep::NoOp
; 
 533    for (;I 
!= Stop 
&& isspace(*I
) != 0; I
++); 
 535    if (ParseArchFlags 
== true) 
 537       string arch 
= _config
->Find("APT::Architecture"); 
 539       // Parse an architecture 
 540       if (I 
!= Stop 
&& *I 
== '[') 
 549          bool NegArch 
= false; 
 552             // look for whitespace or ending ']' 
 553             while (End 
!= Stop 
&& !isspace(*End
) && *End 
!= ']')  
 565             if (stringcmp(arch
,I
,End
) == 0) 
 574             for (;I 
!= Stop 
&& isspace(*I
) != 0; I
++); 
 581             Package 
= ""; /* not for this arch */ 
 585       for (;I 
!= Stop 
&& isspace(*I
) != 0; I
++); 
 588    if (I 
!= Stop 
&& *I 
== '|') 
 589       Op 
|= pkgCache::Dep::Or
; 
 591    if (I 
== Stop 
|| *I 
== ',' || *I 
== '|') 
 594          for (I
++; I 
!= Stop 
&& isspace(*I
) != 0; I
++); 
 601 // ListParser::ParseDepends - Parse a dependency list                   /*{{{*/ 
 602 // --------------------------------------------------------------------- 
 603 /* This is the higher level depends parser. It takes a tag and generates 
 604    a complete depends tree for the given version. */ 
 605 bool debListParser::ParseDepends(pkgCache::VerIterator Ver
, 
 606                                  const char *Tag
,unsigned int Type
) 
 610    if (Section
.Find(Tag
,Start
,Stop
) == false) 
 614    string 
const pkgArch 
= Ver
.Arch(true); 
 620       Start 
= ParseDepends(Start
,Stop
,Package
,Version
,Op
); 
 622          return _error
->Error("Problem parsing dependency %s",Tag
); 
 624       if (NewDepends(Ver
,Package
,pkgArch
,Version
,Op
,Type
) == false) 
 632 // ListParser::ParseProvides - Parse the provides list                  /*{{{*/ 
 633 // --------------------------------------------------------------------- 
 635 bool debListParser::ParseProvides(pkgCache::VerIterator Ver
) 
 639    if (Section
.Find("Provides",Start
,Stop
) == true) 
 643       string 
const Arch 
= Ver
.Arch(true); 
 648          Start 
= ParseDepends(Start
,Stop
,Package
,Version
,Op
); 
 650             return _error
->Error("Problem parsing Provides line"); 
 651          if (Op 
!= pkgCache::Dep::NoOp
) { 
 652             _error
->Warning("Ignoring Provides line with DepCompareOp for package %s", Package
.c_str()); 
 654             if (NewProvides(Ver
, Package
, Arch
, Version
) == false) 
 663    if (Ver
->MultiArch 
== pkgCache::Version::Allowed
) 
 665       string 
const Package 
= string(Ver
.ParentPkg().Name()).append(":").append("any"); 
 666       NewProvides(Ver
, Package
, "any", Ver
.VerStr()); 
 669    if (Ver
->MultiArch 
!= pkgCache::Version::Foreign
) 
 672    std::vector
<string
> const archs 
= APT::Configuration::getArchitectures(); 
 673    if (archs
.size() <= 1) 
 676    string 
const Package 
= Ver
.ParentPkg().Name(); 
 677    string 
const Version 
= Ver
.VerStr(); 
 678    for (std::vector
<string
>::const_iterator a 
= archs
.begin(); 
 679         a 
!= archs
.end(); ++a
) 
 681       if (NewProvides(Ver
, Package
, *a
, Version
) == false) 
 688 // ListParser::GrabWord - Matches a word and returns                    /*{{{*/ 
 689 // --------------------------------------------------------------------- 
 690 /* Looks for a word in a list of words - for ParseStatus */ 
 691 bool debListParser::GrabWord(string Word
,WordList 
*List
,unsigned char &Out
) 
 693    for (unsigned int C 
= 0; List
[C
].Str 
!= 0; C
++) 
 695       if (strcasecmp(Word
.c_str(),List
[C
].Str
) == 0) 
 704 // ListParser::Step - Move to the next section in the file              /*{{{*/ 
 705 // --------------------------------------------------------------------- 
 706 /* This has to be carefull to only process the correct architecture */ 
 707 bool debListParser::Step() 
 709    iOffset 
= Tags
.Offset(); 
 710    while (Tags
.Step(Section
) == true) 
 712       /* See if this is the correct Architecture, if it isn't then we 
 713          drop the whole section. A missing arch tag only happens (in theory) 
 714          inside the Status file, so that is a positive return */ 
 715       string 
const Architecture 
= Section
.FindS("Architecture"); 
 716       if (Architecture
.empty() == true) 
 719       if (Arch
.empty() == true) 
 721          if (APT::Configuration::checkArchitecture(Architecture
) == true) 
 726          if (Architecture 
== Arch
) 
 729          if (Architecture 
== "all") 
 733       iOffset 
= Tags
.Offset(); 
 738 // ListParser::LoadReleaseInfo - Load the release information           /*{{{*/ 
 739 // --------------------------------------------------------------------- 
 741 bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator FileI
, 
 742                                     FileFd 
&File
, string component
) 
 744    pkgTagFile 
Tags(&File
, File
.Size() + 256); // XXX 
 745    pkgTagSection Section
; 
 746    if (Tags
.Step(Section
) == false) 
 749    // FIXME: Do we need it now for multi-arch? 
 750    // mvo: I don't think we need to fill that in (it's unused since apt-0.6) 
 751 //    FileI->Architecture = WriteUniqString(Arch); 
 753    // apt-secure does no longer download individual (per-section) Release 
 754    // file. to provide Component pinning we use the section name now 
 755    FileI
->Component 
= WriteUniqString(component
); 
 759    if (Section
.Find("Suite",Start
,Stop
) == true) 
 760       FileI
->Archive 
= WriteUniqString(Start
,Stop 
- Start
); 
 761    if (Section
.Find("Component",Start
,Stop
) == true) 
 762       FileI
->Component 
= WriteUniqString(Start
,Stop 
- Start
); 
 763    if (Section
.Find("Version",Start
,Stop
) == true) 
 764       FileI
->Version 
= WriteUniqString(Start
,Stop 
- Start
); 
 765    if (Section
.Find("Origin",Start
,Stop
) == true) 
 766       FileI
->Origin 
= WriteUniqString(Start
,Stop 
- Start
); 
 767    if (Section
.Find("Codename",Start
,Stop
) == true) 
 768       FileI
->Codename 
= WriteUniqString(Start
,Stop 
- Start
); 
 769    if (Section
.Find("Label",Start
,Stop
) == true) 
 770       FileI
->Label 
= WriteUniqString(Start
,Stop 
- Start
); 
 771    if (Section
.Find("Architecture",Start
,Stop
) == true) 
 772       FileI
->Architecture 
= WriteUniqString(Start
,Stop 
- Start
); 
 774    if (Section
.FindFlag("NotAutomatic",FileI
->Flags
, 
 775                         pkgCache::Flag::NotAutomatic
) == false) 
 776       _error
->Warning("Bad NotAutomatic flag"); 
 778    return !_error
->PendingError(); 
 781 // ListParser::GetPrio - Convert the priority from a string             /*{{{*/ 
 782 // --------------------------------------------------------------------- 
 784 unsigned char debListParser::GetPrio(string Str
) 
 787    if (GrabWord(Str
,PrioList
,Out
) == false) 
 788       Out 
= pkgCache::State::Extra
;