cacheset.cc 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // -*- mode: cpp; mode: fold -*-
  2. // Description /*{{{*/
  3. /* ######################################################################
  4. Simple wrapper around a std::set to provide a similar interface to
  5. a set of cache structures as to the complete set of all structures
  6. in the pkgCache. Currently only Package is supported.
  7. ##################################################################### */
  8. /*}}}*/
  9. // Include Files /*{{{*/
  10. #include <apt-pkg/aptconfiguration.h>
  11. #include <apt-pkg/error.h>
  12. #include <apt-pkg/cacheset.h>
  13. #include <apt-pkg/strutl.h>
  14. #include <apti18n.h>
  15. #include <vector>
  16. #include <regex.h>
  17. /*}}}*/
  18. namespace APT {
  19. // FromRegEx - Return all packages in the cache matching a pattern /*{{{*/
  20. PackageSet PackageSet::FromRegEx(pkgCache &Cache, std::string pattern, std::ostream &out) {
  21. PackageSet pkgset;
  22. std::string arch = "native";
  23. static const char * const isregex = ".?+*|[^$";
  24. if (pattern.find_first_of(isregex) == std::string::npos)
  25. return pkgset;
  26. size_t archfound = pattern.find_last_of(':');
  27. if (archfound != std::string::npos) {
  28. arch = pattern.substr(archfound+1);
  29. if (arch.find_first_of(isregex) == std::string::npos)
  30. pattern.erase(archfound);
  31. else
  32. arch = "native";
  33. }
  34. regex_t Pattern;
  35. int Res;
  36. if ((Res = regcomp(&Pattern, pattern.c_str() , REG_EXTENDED | REG_ICASE | REG_NOSUB)) != 0) {
  37. char Error[300];
  38. regerror(Res, &Pattern, Error, sizeof(Error));
  39. _error->Error(_("Regex compilation error - %s"), Error);
  40. return pkgset;
  41. }
  42. for (pkgCache::GrpIterator Grp = Cache.GrpBegin(); Grp.end() == false; ++Grp)
  43. {
  44. if (regexec(&Pattern, Grp.Name(), 0, 0, 0) != 0)
  45. continue;
  46. pkgCache::PkgIterator Pkg = Grp.FindPkg(arch);
  47. if (Pkg.end() == true) {
  48. if (archfound == std::string::npos) {
  49. std::vector<std::string> archs = APT::Configuration::getArchitectures();
  50. for (std::vector<std::string>::const_iterator a = archs.begin();
  51. a != archs.end() && Pkg.end() != true; ++a)
  52. Pkg = Grp.FindPkg(*a);
  53. }
  54. if (Pkg.end() == true)
  55. continue;
  56. }
  57. ioprintf(out, _("Note, selecting %s for regex '%s'\n"),
  58. Pkg.FullName(true).c_str(), pattern.c_str());
  59. pkgset.insert(Pkg);
  60. }
  61. regfree(&Pattern);
  62. return pkgset;
  63. }
  64. /*}}}*/
  65. // FromCommandLine - Return all packages specified on commandline /*{{{*/
  66. PackageSet PackageSet::FromCommandLine(pkgCache &Cache, const char **cmdline, std::ostream &out) {
  67. PackageSet pkgset;
  68. for (const char **I = cmdline + 1; *I != 0; I++) {
  69. pkgCache::PkgIterator Pkg = Cache.FindPkg(*I);
  70. if (Pkg.end() == true) {
  71. std::vector<std::string> archs = APT::Configuration::getArchitectures();
  72. for (std::vector<std::string>::const_iterator a = archs.begin();
  73. a != archs.end() || Pkg.end() != true; ++a) {
  74. Pkg = Cache.FindPkg(*I, *a);
  75. }
  76. if (Pkg.end() == true) {
  77. PackageSet regex = FromRegEx(Cache, *I, out);
  78. if (regex.empty() == true)
  79. _error->Warning(_("Unable to locate package %s"),*I);
  80. else
  81. pkgset.insert(regex.begin(), regex.end());
  82. continue;
  83. }
  84. }
  85. pkgset.insert(Pkg);
  86. }
  87. return pkgset;
  88. }
  89. /*}}}*/
  90. }