X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/131a2dc0cb36c29d002c2a61f96411e5d84f4adf..d27daedb6a0bf672508072100f20233d08ccf0e0:/apt-pkg/deb/debrecords.cc diff --git a/apt-pkg/deb/debrecords.cc b/apt-pkg/deb/debrecords.cc index 518988bb6..beaa83bd9 100644 --- a/apt-pkg/deb/debrecords.cc +++ b/apt-pkg/deb/debrecords.cc @@ -8,126 +8,219 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ -#ifdef __GNUG__ -#pragma implementation "apt-pkg/debrecords.h" -#endif +#include + #include +#include #include +#include +#include +#include +#include +#include #include + +#include +#include +#include +#include +#include #include + +#include /*}}}*/ +using std::string; + // RecordParser::debRecordParser - Constructor /*{{{*/ -// --------------------------------------------------------------------- -/* */ -debRecordParser::debRecordParser(string FileName,pkgCache &Cache) : - File(FileName,FileFd::ReadOnly), - Tags(&File,Cache.Head().MaxVerFileSize + 200) +debRecordParser::debRecordParser(string FileName,pkgCache &Cache) : + debRecordParserBase(), d(NULL), File(FileName, FileFd::ReadOnly, FileFd::Extension), + Tags(&File, std::max(Cache.Head().MaxVerFileSize, Cache.Head().MaxDescFileSize) + 200) { } /*}}}*/ // RecordParser::Jump - Jump to a specific record /*{{{*/ -// --------------------------------------------------------------------- -/* */ bool debRecordParser::Jump(pkgCache::VerFileIterator const &Ver) { + if (Ver.end() == true) + return false; return Tags.Jump(Section,Ver->Offset); } bool debRecordParser::Jump(pkgCache::DescFileIterator const &Desc) { + if (Desc.end() == true) + return false; return Tags.Jump(Section,Desc->Offset); } /*}}}*/ -// RecordParser::FileName - Return the archive filename on the site /*{{{*/ -// --------------------------------------------------------------------- -/* */ -string debRecordParser::FileName() +debRecordParser::~debRecordParser() {} + +debRecordParserBase::debRecordParserBase() : Parser(), d(NULL) {} +// RecordParserBase::FileName - Return the archive filename on the site /*{{{*/ +string debRecordParserBase::FileName() { return Section.FindS("Filename"); } /*}}}*/ -// RecordParser::Name - Return the package name /*{{{*/ -// --------------------------------------------------------------------- -/* */ -string debRecordParser::Name() +// RecordParserBase::Name - Return the package name /*{{{*/ +string debRecordParserBase::Name() { - return Section.FindS("Package"); + string Result = Section.FindS("Package"); + + // Normalize mixed case package names to lower case, like dpkg does + // See Bug#807012 for details + std::transform(Result.begin(), Result.end(), Result.begin(), tolower_ascii); + + return Result; } /*}}}*/ -// RecordParser::MD5Hash - Return the archive hash /*{{{*/ -// --------------------------------------------------------------------- -/* */ -string debRecordParser::MD5Hash() +// RecordParserBase::Homepage - Return the package homepage /*{{{*/ +string debRecordParserBase::Homepage() { - return Section.FindS("MD5Sum"); + return Section.FindS("Homepage"); } /*}}}*/ -// RecordParser::SHA1Hash - Return the archive hash /*{{{*/ -// --------------------------------------------------------------------- -/* */ -string debRecordParser::SHA1Hash() +// RecordParserBase::Hashes - return the available archive hashes /*{{{*/ +HashStringList debRecordParserBase::Hashes() const { - return Section.FindS("SHA1Sum"); + HashStringList hashes; + for (char const * const * type = HashString::SupportedHashes(); *type != NULL; ++type) + { + std::string const hash = Section.FindS(*type); + if (hash.empty() == false) + hashes.push_back(HashString(*type, hash)); + } + return hashes; } /*}}}*/ -// RecordParser::Maintainer - Return the maintainer email /*{{{*/ -// --------------------------------------------------------------------- -/* */ -string debRecordParser::Maintainer() +// RecordParserBase::Maintainer - Return the maintainer email /*{{{*/ +string debRecordParserBase::Maintainer() { return Section.FindS("Maintainer"); } /*}}}*/ -// RecordParser::ShortDesc - Return a 1 line description /*{{{*/ -// --------------------------------------------------------------------- -/* */ -string debRecordParser::ShortDesc() +// RecordParserBase::RecordField - Return the value of an arbitrary field /*{{*/ +string debRecordParserBase::RecordField(const char *fieldName) { - string Res = LongDesc(); - string::size_type Pos = Res.find('\n'); + return Section.FindS(fieldName); +} + /*}}}*/ +// RecordParserBase::ShortDesc - Return a 1 line description /*{{{*/ +string debRecordParserBase::ShortDesc(std::string const &lang) +{ + string const Res = LongDesc(lang); + if (Res.empty() == true) + return ""; + string::size_type const Pos = Res.find('\n'); if (Pos == string::npos) return Res; return string(Res,0,Pos); } /*}}}*/ -// RecordParser::LongDesc - Return a longer description /*{{{*/ -// --------------------------------------------------------------------- -/* */ -string debRecordParser::LongDesc() +// RecordParserBase::LongDesc - Return a longer description /*{{{*/ +string debRecordParserBase::LongDesc(std::string const &lang) { - string orig, dest; - char *codeset = nl_langinfo(CODESET); - - if (!Section.FindS("Description").empty()) - orig = Section.FindS("Description").c_str(); - else - orig = Section.FindS(("Description-" + pkgIndexFile::LanguageCode()).c_str()).c_str(); - - if (strcmp(codeset,"UTF-8") != 0) { - UTF8ToCodeset(codeset, orig, &dest); - orig = dest; - } - + string orig; + if (lang.empty() == true) + { + std::vector const lang = APT::Configuration::getLanguages(); + for (std::vector::const_iterator l = lang.begin(); + l != lang.end(); ++l) + { + std::string const tagname = "Description-" + *l; + orig = Section.FindS(tagname.c_str()); + if (orig.empty() == false) + break; + else if (*l == "en") + { + orig = Section.FindS("Description"); + if (orig.empty() == false) + break; + } + } + if (orig.empty() == true) + orig = Section.FindS("Description"); + } + else + { + std::string const tagname = "Description-" + lang; + orig = Section.FindS(tagname.c_str()); + if (orig.empty() == true && lang == "en") + orig = Section.FindS("Description"); + } + + char const * const codeset = nl_langinfo(CODESET); + if (strcmp(codeset,"UTF-8") != 0) { + string dest; + UTF8ToCodeset(codeset, orig, &dest); + return dest; + } + return orig; } /*}}}*/ -// RecordParser::SourcePkg - Return the source package name if any /*{{{*/ -// --------------------------------------------------------------------- -/* */ -string debRecordParser::SourcePkg() + +static const char * const SourceVerSeparators = " ()"; +// RecordParserBase::SourcePkg - Return the source package name if any /*{{{*/ +string debRecordParserBase::SourcePkg() { string Res = Section.FindS("Source"); - string::size_type Pos = Res.find(' '); + string::size_type Pos = Res.find_first_of(SourceVerSeparators); if (Pos == string::npos) return Res; return string(Res,0,Pos); } /*}}}*/ -// RecordParser::GetRec - Return the whole record /*{{{*/ -// --------------------------------------------------------------------- -/* */ -void debRecordParser::GetRec(const char *&Start,const char *&Stop) +// RecordParserBase::SourceVer - Return the source version number if present /*{{{*/ +string debRecordParserBase::SourceVer() +{ + string Pkg = Section.FindS("Source"); + string::size_type Pos = Pkg.find_first_of(SourceVerSeparators); + if (Pos == string::npos) + return ""; + + string::size_type VerStart = Pkg.find_first_not_of(SourceVerSeparators, Pos); + if(VerStart == string::npos) + return ""; + + string::size_type VerEnd = Pkg.find_first_of(SourceVerSeparators, VerStart); + if(VerEnd == string::npos) + // Corresponds to the case of, e.g., "foo (1.2" without a closing + // paren. Be liberal and guess what it means. + return string(Pkg, VerStart); + else + return string(Pkg, VerStart, VerEnd - VerStart); +} + /*}}}*/ +// RecordParserBase::GetRec - Return the whole record /*{{{*/ +void debRecordParserBase::GetRec(const char *&Start,const char *&Stop) { Section.GetSection(Start,Stop); } /*}}}*/ +debRecordParserBase::~debRecordParserBase() {} + +bool debDebFileRecordParser::LoadContent() +{ + // load content only once + if (controlContent.empty() == false) + return true; + + std::ostringstream content; + if (debDebPkgFileIndex::GetContent(content, debFileName) == false) + return false; + // add two newlines to make sure the scanner finds the section, + // which is usually done by pkgTagFile automatically if needed. + content << "\n\n"; + + controlContent = content.str(); + if (Section.Scan(controlContent.c_str(), controlContent.length()) == false) + return _error->Error(_("Unable to parse package file %s (%d)"), debFileName.c_str(), 3); + return true; +} +bool debDebFileRecordParser::Jump(pkgCache::VerFileIterator const &) { return LoadContent(); } +bool debDebFileRecordParser::Jump(pkgCache::DescFileIterator const &) { return LoadContent(); } +std::string debDebFileRecordParser::FileName() { return debFileName; } + +debDebFileRecordParser::debDebFileRecordParser(std::string FileName) : debRecordParserBase(), d(NULL), debFileName(FileName) {} +debDebFileRecordParser::~debDebFileRecordParser() {}