summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@cvs.openbsd.org>2017-07-19 14:05:10 +0000
committerIngo Schwarze <schwarze@cvs.openbsd.org>2017-07-19 14:05:10 +0000
commit8310912f50603f70dc50d8c619decb1136480ca4 (patch)
treedd4657ad4b90dcbe8fcc86317de7643c075bb382
parent24cd25e013cf532c8c1f458204ea92f6203f53ec (diff)
Prefer arch-dependent over arch-independent pages if the name priority,
the section number, and all names match. Changes little on installed systems except the ordering of apropos(1) results, because we install base and Xenocara manuals in different trees, but fixes lookup of pages like apm(4) vs. apm(4/amd64) in man.cgi(8). Issue discovered by martian67 on freenode and reported via tj@.
-rw-r--r--usr.bin/mandoc/mansearch.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/usr.bin/mandoc/mansearch.c b/usr.bin/mandoc/mansearch.c
index f9de5f515f8..f88edc1af92 100644
--- a/usr.bin/mandoc/mansearch.c
+++ b/usr.bin/mandoc/mansearch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mansearch.c,v 1.57 2017/07/01 09:47:23 schwarze Exp $ */
+/* $OpenBSD: mansearch.c,v 1.58 2017/07/19 14:05:09 schwarze Exp $ */
/*
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -391,13 +391,29 @@ 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;
- return (diff = mp2->bits - mp1->bits) ? diff :
- (diff = mp1->sec - mp2->sec) ? diff :
- strcasecmp(mp1->names, mp2->names);
+ 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 *