summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2017-07-19 14:05:13 +0000
committerIngo Schwarze <schwarze@openbsd.org>2017-07-19 14:05:13 +0000
commit546325f536ffb9a23ad38714c91bf7988ccfaadf (patch)
tree2f216a38c4c27abe7e76169d096deedc20a6f585
parente5b7a83a65764e977e22a3837febc10c489e70ce (diff)
downloadmandoc-546325f536ffb9a23ad38714c91bf7988ccfaadf.tar.gz
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--mansearch.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/mansearch.c b/mansearch.c
index ddfe2f5d..c889aecf 100644
--- a/mansearch.c
+++ b/mansearch.c
@@ -394,13 +394,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 *