You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

156 lines
5.0 KiB

  1. // Include Files /*{{{*/
  2. #include <config.h>
  3. #include <apt-pkg/cachefile.h>
  4. #include <apt-pkg/cachefilter.h>
  5. #include <apt-pkg/cacheset.h>
  6. #include <apt-pkg/cmndline.h>
  7. #include <apt-pkg/configuration.h>
  8. #include <apt-pkg/macros.h>
  9. #include <apt-pkg/pkgcache.h>
  10. #include <apt-pkg/pkgrecords.h>
  11. #include <apt-pkg/progress.h>
  12. #include <apt-pkg/strutl.h>
  13. #include <apt-private/private-cacheset.h>
  14. #include <apt-private/private-list.h>
  15. #include <apt-private/private-output.h>
  16. #include <iostream>
  17. #include <map>
  18. #include <sstream>
  19. #include <string>
  20. #include <utility>
  21. #include <vector>
  22. #include <apti18n.h>
  23. /*}}}*/
  24. struct PackageSortAlphabetic /*{{{*/
  25. {
  26. bool operator () (const pkgCache::PkgIterator &p_lhs,
  27. const pkgCache::PkgIterator &p_rhs)
  28. {
  29. const std::string &l_name = p_lhs.FullName(true);
  30. const std::string &r_name = p_rhs.FullName(true);
  31. return (l_name < r_name);
  32. }
  33. };
  34. class PackageNameMatcher : public Matcher
  35. {
  36. public:
  37. explicit PackageNameMatcher(const char **patterns)
  38. {
  39. for(int i=0; patterns[i] != NULL; ++i)
  40. {
  41. std::string pattern = patterns[i];
  42. APT::CacheFilter::PackageMatcher *cachefilter = NULL;
  43. if(_config->FindB("APT::Cmd::Use-Regexp", false) == true)
  44. cachefilter = new APT::CacheFilter::PackageNameMatchesRegEx(pattern);
  45. else
  46. cachefilter = new APT::CacheFilter::PackageNameMatchesFnmatch(pattern);
  47. filters.push_back(cachefilter);
  48. }
  49. }
  50. virtual ~PackageNameMatcher()
  51. {
  52. for(J=filters.begin(); J != filters.end(); ++J)
  53. delete *J;
  54. }
  55. virtual bool operator () (const pkgCache::PkgIterator &P) APT_OVERRIDE
  56. {
  57. for(J=filters.begin(); J != filters.end(); ++J)
  58. {
  59. APT::CacheFilter::PackageMatcher *cachefilter = *J;
  60. if((*cachefilter)(P))
  61. return true;
  62. }
  63. return false;
  64. }
  65. private:
  66. std::vector<APT::CacheFilter::PackageMatcher*> filters;
  67. std::vector<APT::CacheFilter::PackageMatcher*>::const_iterator J;
  68. #undef PackageMatcher
  69. };
  70. /*}}}*/
  71. static void ListAllVersions(pkgCacheFile &CacheFile, pkgRecords &records,/*{{{*/
  72. pkgCache::PkgIterator const &P, std::ostream &outs,
  73. std::string const &format)
  74. {
  75. for (pkgCache::VerIterator Ver = P.VersionList();
  76. Ver.end() == false; ++Ver)
  77. {
  78. ListSingleVersion(CacheFile, records, Ver, outs, format);
  79. outs << std::endl;
  80. }
  81. }
  82. /*}}}*/
  83. // list - list package based on criteria /*{{{*/
  84. // ---------------------------------------------------------------------
  85. bool DoList(CommandLine &Cmd)
  86. {
  87. pkgCacheFile CacheFile;
  88. pkgCache * const Cache = CacheFile.GetPkgCache();
  89. if (unlikely(Cache == nullptr || CacheFile.GetDepCache() == nullptr))
  90. return false;
  91. pkgRecords records(CacheFile);
  92. const char **patterns;
  93. const char *all_pattern[] = { "*", NULL};
  94. if (strv_length(Cmd.FileList + 1) == 0)
  95. {
  96. patterns = all_pattern;
  97. } else {
  98. patterns = Cmd.FileList + 1;
  99. }
  100. std::string format = "${color:highlight}${Package}${color:neutral}/${Origin} ${Version} ${Architecture}${ }${apt:Status}";
  101. if (_config->FindB("APT::Cmd::List-Include-Summary", false) == true)
  102. format += "\n ${Description}\n";
  103. PackageNameMatcher matcher(patterns);
  104. LocalitySortedVersionSet bag;
  105. OpTextProgress progress(*_config);
  106. progress.OverallProgress(0,
  107. Cache->Head().PackageCount,
  108. Cache->Head().PackageCount,
  109. _("Listing"));
  110. GetLocalitySortedVersionSet(CacheFile, &bag, matcher, &progress);
  111. bool const ShowAllVersions = _config->FindB("APT::Cmd::All-Versions", false);
  112. std::map<std::string, std::string> output_map;
  113. for (LocalitySortedVersionSet::iterator V = bag.begin(); V != bag.end(); ++V)
  114. {
  115. std::stringstream outs;
  116. if(ShowAllVersions == true)
  117. ListAllVersions(CacheFile, records, V.ParentPkg(), outs, format);
  118. else
  119. ListSingleVersion(CacheFile, records, V, outs, format);
  120. output_map.insert(std::make_pair<std::string, std::string>(
  121. V.ParentPkg().FullName(), outs.str()));
  122. }
  123. // FIXME: SORT! and make sorting flexible (alphabetic, by pkg status)
  124. // output the sorted map
  125. std::map<std::string, std::string>::const_iterator K;
  126. for (K = output_map.begin(); K != output_map.end(); ++K)
  127. std::cout << (*K).second << std::endl;
  128. // be nice and tell the user if there is more to see
  129. if (bag.size() == 1 && ShowAllVersions == false)
  130. {
  131. // start with -1 as we already displayed one version
  132. int versions = -1;
  133. pkgCache::VerIterator Ver = *bag.begin();
  134. for ( ; Ver.end() == false; ++Ver)
  135. ++versions;
  136. if (versions > 0)
  137. _error->Notice(P_("There is %i additional version. Please use the '-a' switch to see it", "There are %i additional versions. Please use the '-a' switch to see them.", versions), versions);
  138. }
  139. return true;
  140. }