+ free(res);
+}
+
+static int
+manpage_compare(const void *vp1, const void *vp2)
+{
+ const struct manpage *mp1, *mp2;
+ const char *cp1, *cp2;
+ size_t sz1, sz2;
+ int diff;
+
+ mp1 = vp1;
+ mp2 = vp2;
+ if ((diff = mp2->bits - mp1->bits) ||
+ (diff = mp1->sec - mp2->sec))
+ return diff;
+
+ /* Fall back to alphabetic ordering of names. */
+ sz1 = strcspn(mp1->names, "(");
+ sz2 = strcspn(mp2->names, "(");
+ if (sz1 < sz2)
+ sz1 = sz2;
+ if ((diff = strncasecmp(mp1->names, mp2->names, sz1)))
+ return diff;
+
+ /* For identical names and sections, prefer arch-dependent. */
+ cp1 = strchr(mp1->names + sz1, '/');
+ cp2 = strchr(mp2->names + sz2, '/');
+ return cp1 != NULL && cp2 != NULL ? strcasecmp(cp1, cp2) :
+ cp1 != NULL ? -1 : cp2 != NULL ? 1 : 0;
+}
+
+static char *
+buildnames(const struct dbm_page *page)
+{
+ char *buf;
+ size_t i, sz;
+
+ sz = lstlen(page->name, 2) + 1 + lstlen(page->sect, 2) +
+ (page->arch == NULL ? 0 : 1 + lstlen(page->arch, 2)) + 2;
+ buf = mandoc_malloc(sz);
+ i = 0;
+ lstcat(buf, &i, page->name, ", ");
+ buf[i++] = '(';
+ lstcat(buf, &i, page->sect, ", ");
+ if (page->arch != NULL) {
+ buf[i++] = '/';
+ lstcat(buf, &i, page->arch, ", ");
+ }
+ buf[i++] = ')';
+ buf[i++] = '\0';
+ assert(i == sz);
+ return buf;