+ static std::vector<std::string> parsePlusMinusArchOptions(std::string const &Name,
+ std::map<std::string, std::string> const &Options)
+ {
+ auto Values = getDefaultSetOf(Name, Options, APT::Configuration::getArchitectures());
+ // all is a very special architecture users shouldn't be concerned with explicitly
+ // but if the user does, do not override the choice
+ auto const val = Options.find(Name + "-");
+ if (val != Options.end())
+ {
+ std::vector<std::string> const minus = VectorizeString(val->second, ',');
+ if (std::find(minus.begin(), minus.end(), "all") != minus.end())
+ return applyPlusMinusOptions(Name, Options, std::move(Values));
+ }
+ Values = applyPlusMinusOptions(Name, Options, std::move(Values));
+ if (std::find(Values.begin(), Values.end(), "all") == Values.end())
+ Values.push_back("implicit:all");
+ return Values;
+ }
+ static std::vector<std::string> parsePlusMinusTargetOptions(char const * const Name,
+ std::map<std::string, std::string> const &Options)
+ {
+ std::vector<std::string> const alltargets = _config->FindVector(std::string("Acquire::IndexTargets::") + Name, "", true);
+ std::vector<std::string> deftargets;
+ deftargets.reserve(alltargets.size());
+ std::copy_if(alltargets.begin(), alltargets.end(), std::back_inserter(deftargets), [&](std::string const &t) {
+ std::string c = "Acquire::IndexTargets::";
+ c.append(Name).append("::").append(t).append("::DefaultEnabled");
+ return _config->FindB(c, true);
+ });
+ std::vector<std::string> mytargets = parsePlusMinusOptions("target", Options, deftargets);
+ for (auto const &target : alltargets)
+ {
+ std::map<std::string, std::string>::const_iterator const opt = Options.find(target);
+ if (opt == Options.end())
+ continue;
+ auto const idMatch = [&](std::string const &t) {
+ return target == _config->Find(std::string("Acquire::IndexTargets::") + Name + "::" + t + "::Identifier", t);
+ };
+ if (StringToBool(opt->second))
+ std::copy_if(alltargets.begin(), alltargets.end(), std::back_inserter(mytargets), idMatch);
+ else
+ mytargets.erase(std::remove_if(mytargets.begin(), mytargets.end(), idMatch), mytargets.end());
+ }
+ // if we can't order it in a 1000 steps we give up… probably a cycle
+ for (auto i = 0; i < 1000; ++i)
+ {
+ bool Changed = false;
+ for (auto t = mytargets.begin(); t != mytargets.end(); ++t)
+ {
+ std::string const fallback = _config->Find(std::string("Acquire::IndexTargets::") + Name + "::" + *t + "::Fallback-Of");
+ if (fallback.empty())
+ continue;
+ auto const faller = std::find(mytargets.begin(), mytargets.end(), fallback);
+ if (faller == mytargets.end() || faller < t)
+ continue;
+ Changed = true;
+ auto const tv = *t;
+ mytargets.erase(t);
+ mytargets.emplace_back(tv);
+ }
+ if (Changed == false)
+ break;
+ }
+ // remove duplicates without changing the order (in first appearance)
+ {
+ std::set<std::string> seenOnce;
+ mytargets.erase(std::remove_if(mytargets.begin(), mytargets.end(), [&](std::string const &t) {
+ return seenOnce.insert(t).second == false;
+ }), mytargets.end());
+ }
+ return mytargets;
+ }
+