pkg-show.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /*
  2. * libdpkg - Debian packaging suite library routines
  3. * pkg-show.c - primitives for pkg information display
  4. *
  5. * Copyright © 1995,1996 Ian Jackson <ian@chiark.greenend.org.uk>
  6. * Copyright © 2008-2014 Guillem Jover <guillem@debian.org>
  7. *
  8. * This is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. */
  21. #include <config.h>
  22. #include <compat.h>
  23. #include <string.h>
  24. #include <dpkg/macros.h>
  25. #include <dpkg/i18n.h>
  26. #include <dpkg/dpkg-db.h>
  27. #include <dpkg/pkg-show.h>
  28. static bool
  29. pkgbin_name_needs_arch(const struct pkgbin *pkgbin,
  30. enum pkg_name_arch_when pnaw)
  31. {
  32. switch (pnaw) {
  33. case pnaw_never:
  34. break;
  35. case pnaw_nonambig:
  36. if (pkgbin->multiarch == PKG_MULTIARCH_SAME)
  37. return true;
  38. /* Fall through. */
  39. case pnaw_foreign:
  40. if (pkgbin->arch->type == DPKG_ARCH_NATIVE ||
  41. pkgbin->arch->type == DPKG_ARCH_ALL ||
  42. pkgbin->arch->type == DPKG_ARCH_NONE)
  43. break;
  44. /* Fall through. */
  45. case pnaw_always:
  46. return true;
  47. }
  48. return false;
  49. }
  50. /**
  51. * Add a string representation of the package name to a varbuf.
  52. *
  53. * Works exactly like pkgbin_name() but acts on the varbuf instead of
  54. * returning a string. It NUL terminates the varbuf.
  55. *
  56. * @param vb The varbuf struct to modify.
  57. * @param pkg The package to consider.
  58. * @param pkgbin The binary package instance to consider.
  59. * @param pnaw When to display the architecture qualifier.
  60. */
  61. void
  62. varbuf_add_pkgbin_name(struct varbuf *vb,
  63. const struct pkginfo *pkg, const struct pkgbin *pkgbin,
  64. enum pkg_name_arch_when pnaw)
  65. {
  66. varbuf_add_str(vb, pkg->set->name);
  67. if (pkgbin_name_needs_arch(pkgbin, pnaw))
  68. varbuf_add_archqual(vb, pkgbin->arch);
  69. varbuf_end_str(vb);
  70. }
  71. /**
  72. * Return a string representation of the package name.
  73. *
  74. * The returned string must not be freed, and it's permanently allocated so
  75. * can be used as long as the non-freeing memory pool has not been freed.
  76. *
  77. * The pnaw parameter should be one of pnaw_never (never print arch),
  78. * pnaw_foreign (print arch for foreign packages only), pnaw_nonambig (print
  79. * arch for non ambiguous cases) or pnaw_always (always print arch),
  80. *
  81. * @param pkg The package to consider.
  82. * @param pkgbin The binary package instance to consider.
  83. * @param pnaw When to display the architecture qualifier.
  84. *
  85. * @return The string representation.
  86. */
  87. const char *
  88. pkgbin_name(struct pkginfo *pkg, struct pkgbin *pkgbin,
  89. enum pkg_name_arch_when pnaw)
  90. {
  91. if (!pkgbin_name_needs_arch(pkgbin, pnaw))
  92. return pkg->set->name;
  93. /* Cache the package name representation, for later reuse. */
  94. if (pkgbin->pkgname_archqual == NULL) {
  95. struct varbuf vb = VARBUF_INIT;
  96. varbuf_add_str(&vb, pkg->set->name);
  97. varbuf_add_archqual(&vb, pkgbin->arch);
  98. varbuf_end_str(&vb);
  99. pkgbin->pkgname_archqual = nfstrsave(vb.buf);
  100. varbuf_destroy(&vb);
  101. }
  102. return pkgbin->pkgname_archqual;
  103. }
  104. /**
  105. * Return a string representation of the package name.
  106. *
  107. * This is equivalent to pkgbin_name() but just for its installed pkgbin.
  108. *
  109. * @param pkg The package to consider.
  110. * @param pnaw When to display the architecture qualifier.
  111. *
  112. * @return The string representation.
  113. */
  114. const char *
  115. pkg_name(struct pkginfo *pkg, enum pkg_name_arch_when pnaw)
  116. {
  117. return pkgbin_name(pkg, &pkg->installed, pnaw);
  118. }
  119. const char *
  120. pkg_summary(const struct pkginfo *pkg, const struct pkgbin *pkgbin, int *len)
  121. {
  122. const char *pdesc;
  123. pdesc = pkgbin->description;
  124. if (!pdesc)
  125. pdesc = _("(no description available)");
  126. *len = strcspn(pdesc, "\n");
  127. return pdesc;
  128. }
  129. int
  130. pkg_abbrev_want(const struct pkginfo *pkg)
  131. {
  132. return "uihrp"[pkg->want];
  133. }
  134. int
  135. pkg_abbrev_status(const struct pkginfo *pkg)
  136. {
  137. return "ncHUFWti"[pkg->status];
  138. }
  139. int
  140. pkg_abbrev_eflag(const struct pkginfo *pkg)
  141. {
  142. return " R"[pkg->eflag];
  143. }
  144. /**
  145. * Return a string representation of the package want status name.
  146. *
  147. * @param pkg The package to consider.
  148. *
  149. * @return The string representation.
  150. */
  151. const char *
  152. pkg_want_name(const struct pkginfo *pkg)
  153. {
  154. return wantinfos[pkg->want].name;
  155. }
  156. /**
  157. * Return a string representation of the package eflag status name.
  158. *
  159. * @param pkg The package to consider.
  160. *
  161. * @return The string representation.
  162. */
  163. const char *
  164. pkg_eflag_name(const struct pkginfo *pkg)
  165. {
  166. return eflaginfos[pkg->eflag].name;
  167. }
  168. /**
  169. * Return a string representation of the package current status name.
  170. *
  171. * @param pkg The package to consider.
  172. *
  173. * @return The string representation.
  174. */
  175. const char *
  176. pkg_status_name(const struct pkginfo *pkg)
  177. {
  178. return statusinfos[pkg->status].name;
  179. }
  180. /**
  181. * Return a string representation of the package priority name.
  182. *
  183. * @param pkg The package to consider.
  184. *
  185. * @return The string representation.
  186. */
  187. const char *
  188. pkg_priority_name(const struct pkginfo *pkg)
  189. {
  190. if (pkg->priority == PKG_PRIO_OTHER)
  191. return pkg->otherpriority;
  192. else
  193. return priorityinfos[pkg->priority].name;
  194. }
  195. /**
  196. * Compare a package to be sorted by non-ambiguous name and architecture.
  197. *
  198. * @param a A pointer of a pointer to a struct pkginfo.
  199. * @param b A pointer of a pointer to a struct pkginfo.
  200. *
  201. * @return An integer with the result of the comparison.
  202. * @retval -1 a is earlier than b.
  203. * @retval 0 a is equal to b.
  204. * @retval 1 a is later than b.
  205. */
  206. int
  207. pkg_sorter_by_nonambig_name_arch(const void *a, const void *b)
  208. {
  209. const struct pkginfo *pa = *(const struct pkginfo **)a;
  210. const struct pkginfo *pb = *(const struct pkginfo **)b;
  211. const struct pkgbin *pbina = &pa->installed;
  212. const struct pkgbin *pbinb = &pb->installed;
  213. int res;
  214. res = strcmp(pa->set->name, pb->set->name);
  215. if (res)
  216. return res;
  217. if (pbina->arch == pbinb->arch)
  218. return 0;
  219. if (pkgbin_name_needs_arch(pbina, pnaw_nonambig)) {
  220. if (pkgbin_name_needs_arch(pbinb, pnaw_nonambig))
  221. return strcmp(pbina->arch->name, pbinb->arch->name);
  222. else
  223. return 1;
  224. } else {
  225. return -1;
  226. }
  227. }