+
+// DPkgPM::BuildPackagesProgressMap /*{{{*/
+void pkgDPkgPM::BuildPackagesProgressMap()
+{
+ // map the dpkg states to the operations that are performed
+ // (this is sorted in the same way as Item::Ops)
+ static const std::array<std::array<DpkgState, 3>, 4> DpkgStatesOpMap = {{
+ // Install operation
+ {{
+ {"half-installed", N_("Preparing %s")},
+ {"unpacked", N_("Unpacking %s") },
+ {nullptr, nullptr}
+ }},
+ // Configure operation
+ {{
+ {"unpacked",N_("Preparing to configure %s") },
+ {"half-configured", N_("Configuring %s") },
+ { "installed", N_("Installed %s")},
+ }},
+ // Remove operation
+ {{
+ {"half-configured", N_("Preparing for removal of %s")},
+ {"half-installed", N_("Removing %s")},
+ {"config-files", N_("Removed %s")},
+ }},
+ // Purge operation
+ {{
+ {"config-files", N_("Preparing to completely remove %s")},
+ {"not-installed", N_("Completely removed %s")},
+ {nullptr, nullptr}
+ }},
+ }};
+ static_assert(Item::Purge == 3, "Enum item has unexpected index for mapping array");
+
+ // init the PackageOps map, go over the list of packages that
+ // that will be [installed|configured|removed|purged] and add
+ // them to the PackageOps map (the dpkg states it goes through)
+ // and the PackageOpsTranslations (human readable strings)
+ for (auto &&I : List)
+ {
+ if(I.Pkg.end() == true)
+ continue;
+
+ string const name = I.Pkg.FullName();
+ PackageOpsDone[name] = 0;
+ auto AddToPackageOps = std::back_inserter(PackageOps[name]);
+ if (I.Op == Item::Purge && I.Pkg->CurrentVer != 0)
+ {
+ // purging a package which is installed first passes through remove states
+ auto const DpkgOps = DpkgStatesOpMap[Item::Remove];
+ std::copy(DpkgOps.begin(), DpkgOps.end(), AddToPackageOps);
+ PackagesTotal += DpkgOps.size();
+ }
+ auto const DpkgOps = DpkgStatesOpMap[I.Op];
+ std::copy_if(DpkgOps.begin(), DpkgOps.end(), AddToPackageOps, [&](DpkgState const &state) {
+ if (state.state == nullptr)
+ return false;
+ ++PackagesTotal;
+ return true;
+ });
+ }
+ /* one extra: We don't want the progress bar to reach 100%, especially not
+ if we call dpkg --configure --pending and process a bunch of triggers
+ while showing 100%. Also, spindown takes a while, so never reaching 100%
+ is way more correct than reaching 100% while still doing stuff even if
+ doing it this way is slightly bending the rules */
+ ++PackagesTotal;
+}
+ /*}}}*/
+bool pkgDPkgPM::Go(int StatusFd) /*{{{*/