summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2014-03-17 16:31:44 +0000
committerIngo Schwarze <schwarze@openbsd.org>2014-03-17 16:31:44 +0000
commit4c1341e91af6443c15b87a1ec441a3f2a44cf2c8 (patch)
tree18b398d81aa1590b0dbd254b4ccfa6627029e0f0
parent5489c70bc373fe99b735827edbcf971cfde4537a (diff)
downloadmandoc-4c1341e91af6443c15b87a1ec441a3f2a44cf2c8.tar.gz
in apropos(1) output, sort names and avoid multiple section numbers
-rw-r--r--mansearch.c60
1 files changed, 54 insertions, 6 deletions
diff --git a/mansearch.c b/mansearch.c
index fe5def6a..562ca636 100644
--- a/mansearch.c
+++ b/mansearch.c
@@ -254,7 +254,8 @@ mansearch(const struct mansearch *search,
sqlite3_finalize(s);
c = sqlite3_prepare_v2(db,
- "SELECT * FROM mlinks WHERE pageid=?",
+ "SELECT * FROM mlinks WHERE pageid=?"
+ " ORDER BY sec, arch, name",
-1, &s, NULL);
if (SQLITE_OK != c)
fprintf(stderr, "%s\n", sqlite3_errmsg(db));
@@ -303,17 +304,18 @@ static void
buildnames(struct manpage *mpage, sqlite3 *db, sqlite3_stmt *s,
uint64_t id, const char *path, int form)
{
- char *newnames;
+ char *newnames, *prevsec, *prevarch;
const char *oldnames, *sep1, *name, *sec, *sep2, *arch, *fsec;
size_t i;
int c;
mpage->names = NULL;
+ prevsec = prevarch = NULL;
i = 1;
SQL_BIND_INT64(db, s, i, id);
while (SQLITE_ROW == (c = sqlite3_step(s))) {
- /* Assemble the list of names. */
+ /* Decide whether we already have some names. */
if (NULL == mpage->names) {
oldnames = "";
@@ -322,12 +324,42 @@ buildnames(struct manpage *mpage, sqlite3 *db, sqlite3_stmt *s,
oldnames = mpage->names;
sep1 = ", ";
}
+
+ /* Fetch the next name. */
+
sec = sqlite3_column_text(s, 0);
arch = sqlite3_column_text(s, 1);
name = sqlite3_column_text(s, 2);
- sep2 = '\0' == *arch ? "" : "/";
- if (-1 == asprintf(&newnames, "%s%s%s(%s%s%s)",
- oldnames, sep1, name, sec, sep2, arch)) {
+
+ /* If the section changed, append the old one. */
+
+ if (NULL != prevsec &&
+ (strcmp(sec, prevsec) ||
+ strcmp(arch, prevarch))) {
+ sep2 = '\0' == *prevarch ? "" : "/";
+ if (-1 == asprintf(&newnames, "%s(%s%s%s)",
+ oldnames, prevsec, sep2, prevarch)) {
+ perror(0);
+ exit((int)MANDOCLEVEL_SYSERR);
+ }
+ free(mpage->names);
+ oldnames = mpage->names = newnames;
+ free(prevsec);
+ free(prevarch);
+ prevsec = prevarch = NULL;
+ }
+
+ /* Save the new section, to append it later. */
+
+ if (NULL == prevsec) {
+ prevsec = mandoc_strdup(sec);
+ prevarch = mandoc_strdup(arch);
+ }
+
+ /* Append the new name. */
+
+ if (-1 == asprintf(&newnames, "%s%s%s",
+ oldnames, sep1, name)) {
perror(0);
exit((int)MANDOCLEVEL_SYSERR);
}
@@ -346,6 +378,7 @@ buildnames(struct manpage *mpage, sqlite3 *db, sqlite3_stmt *s,
sep1 = "cat";
fsec = "0";
}
+ sep2 = '\0' == *arch ? "" : "/";
if (-1 == asprintf(&mpage->file, "%s/%s%s%s%s/%s.%s",
path, sep1, sec, sep2, arch, name, fsec)) {
perror(0);
@@ -355,6 +388,21 @@ buildnames(struct manpage *mpage, sqlite3 *db, sqlite3_stmt *s,
if (SQLITE_DONE != c)
fprintf(stderr, "%s\n", sqlite3_errmsg(db));
sqlite3_reset(s);
+
+ /* Append one final section to the names. */
+
+ if (NULL != prevsec) {
+ sep2 = '\0' == *prevarch ? "" : "/";
+ if (-1 == asprintf(&newnames, "%s(%s%s%s)",
+ mpage->names, prevsec, sep2, prevarch)) {
+ perror(0);
+ exit((int)MANDOCLEVEL_SYSERR);
+ }
+ free(mpage->names);
+ mpage->names = newnames;
+ free(prevsec);
+ free(prevarch);
+ }
}
static char *