123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- // -*- mode: cpp; mode: fold -*-
- // Description /*{{{*/
- // $Id: debrecords.cc,v 1.10 2001/03/13 06:51:46 jgg Exp $
- /* ######################################################################
-
- Debian Package Records - Parser for debian package records
-
- ##################################################################### */
- /*}}}*/
- // Include Files /*{{{*/
- #include <config.h>
- #include <apt-pkg/debrecords.h>
- #include <apt-pkg/debindexfile.h>
- #include <apt-pkg/strutl.h>
- #include <apt-pkg/aptconfiguration.h>
- #include <apt-pkg/fileutl.h>
- #include <apt-pkg/cacheiterators.h>
- #include <apt-pkg/pkgcache.h>
- #include <apt-pkg/tagfile.h>
- #include <apt-pkg/error.h>
- #include <string.h>
- #include <algorithm>
- #include <sstream>
- #include <string>
- #include <vector>
- #include <langinfo.h>
- #include <apti18n.h>
- /*}}}*/
- using std::string;
- // RecordParser::debRecordParser - Constructor /*{{{*/
- debRecordParser::debRecordParser(string FileName,pkgCache &Cache) :
- debRecordParserBase(), d(NULL), File(FileName, FileFd::ReadOnly, FileFd::Extension),
- Tags(&File)
- {
- }
- /*}}}*/
- // 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);
- }
- /*}}}*/
- debRecordParser::~debRecordParser() {}
- debRecordParserBase::debRecordParserBase() : Parser(), d(NULL) {}
- // RecordParserBase::FileName - Return the archive filename on the site /*{{{*/
- string debRecordParserBase::FileName()
- {
- return Section.FindS("Filename");
- }
- /*}}}*/
- // RecordParserBase::Name - Return the package name /*{{{*/
- string debRecordParserBase::Name()
- {
- 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;
- }
- /*}}}*/
- // RecordParserBase::Display - Return the package homepage /*{{{*/
- string debRecordParserBase::Display()
- {
- string display(Section.FindS("Name"));
- if (display.empty())
- display = Section.FindS("Maemo-Display-Name");
- return display;
- }
- /*}}}*/
- // RecordParserBase::Homepage - Return the package homepage /*{{{*/
- string debRecordParserBase::Homepage()
- {
- return Section.FindS("Homepage");
- }
- /*}}}*/
- // RecordParserBase::Hashes - return the available archive hashes /*{{{*/
- HashStringList debRecordParserBase::Hashes() const
- {
- 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));
- }
- auto const size = Section.FindULL("Size", 0);
- if (size != 0)
- hashes.FileSize(size);
- return hashes;
- }
- /*}}}*/
- // RecordParserBase::Maintainer - Return the maintainer email /*{{{*/
- string debRecordParserBase::Maintainer()
- {
- return Section.FindS("Maintainer");
- }
- /*}}}*/
- // RecordParserBase::RecordField - Return the value of an arbitrary field /*{{*/
- string debRecordParserBase::RecordField(const char *fieldName)
- {
- 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);
- }
- /*}}}*/
- // RecordParserBase::LongDesc - Return a longer description /*{{{*/
- string debRecordParserBase::LongDesc(std::string const &lang)
- {
- string orig;
- if (lang.empty() == true)
- {
- std::vector<string> const lang = APT::Configuration::getLanguages();
- for (std::vector<string>::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,"US-ASCII") != 0 && strcmp(codeset,"UTF-8") != 0) {
- string dest;
- UTF8ToCodeset(codeset, orig, &dest);
- return dest;
- }
- return orig;
- }
- /*}}}*/
- 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_first_of(SourceVerSeparators);
- if (Pos == string::npos)
- return Res;
- return string(Res,0,Pos);
- }
- /*}}}*/
- // 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);
- }
- /*}}}*/
- // RecordParserBase::Find - Locate a tag /*{{{*/
- bool debRecordParserBase::Find(const char *Tag,const char *&Start, const char *&End)
- {
- return Section.Find(Tag,Start,End);
- }
- /*}}}*/
- 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) == 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() {}
|