diff options
author | Ingo Schwarze <schwarze@openbsd.org> | 2013-12-27 18:51:25 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@openbsd.org> | 2013-12-27 18:51:25 +0000 |
commit | d8b402becc17ecde4e1ebe75eea8221fd42a162b (patch) | |
tree | b6592c62f2c66ec51eadd067227d58db7ab3f8e3 | |
parent | c5990883f0c591898575364a94056380526ffc11 (diff) | |
download | mandoc-d8b402becc17ecde4e1ebe75eea8221fd42a162b.tar.gz |
Change the mansearch() interface to use the mlinks table in the database
and return a list of names with sections, used by apropos(1) for display.
While here, improve uniformity of the interface by allocating the file
name dynamically, just like the names list and the description.
-rw-r--r-- | apropos.c | 4 | ||||
-rw-r--r-- | manpage.c | 9 | ||||
-rw-r--r-- | mansearch.c | 57 | ||||
-rw-r--r-- | mansearch.h | 3 |
4 files changed, 62 insertions, 11 deletions
@@ -96,7 +96,9 @@ main(int argc, char *argv[]) goto usage; for (i = 0; i < sz; i++) { - printf("%s - %s\n", res[i].file, res[i].desc); + printf("%s - %s\n", res[i].names, res[i].desc); + free(res[i].file); + free(res[i].names); free(res[i].desc); } @@ -106,11 +106,14 @@ main(int argc, char *argv[]) for (i = 0; i < sz; i++) { printf("%6zu %s: %s\n", - i + 1, res[i].file, res[i].desc); + i + 1, res[i].names, res[i].desc); + free(res[i].names); free(res[i].desc); } if (0 == term) { + for (i = 0; i < sz; i++) + free(res[i].file); free(res); return(EXIT_SUCCESS); } @@ -127,12 +130,16 @@ main(int argc, char *argv[]) } if (0 == i) { + for (i = 0; i < sz; i++) + free(res[i].file); free(res); return(EXIT_SUCCESS); } show: cmd = res[i - 1].form ? "mandoc" : "cat"; strlcpy(buf, res[i - 1].file, PATH_MAX); + for (i = 0; i < sz; i++) + free(res[i].file); free(res); show(cmd, buf); diff --git a/mansearch.c b/mansearch.c index ff864c7d..220eefd4 100644 --- a/mansearch.c +++ b/mansearch.c @@ -144,7 +144,9 @@ mansearch(const struct mansearch *search, int fd, rc, c; int64_t id; char buf[PATH_MAX]; - char *sql; + char *sql, *newnames; + const char *oldnames, *sep1, *name, *sec, *sep2, *arch; + struct manpage *mpage; struct expr *e, *ep; sqlite3 *db; sqlite3_stmt *s; @@ -282,7 +284,12 @@ mansearch(const struct mansearch *search, fprintf(stderr, "%s\n", sqlite3_errmsg(db)); sqlite3_finalize(s); - sqlite3_close(db); + + c = sqlite3_prepare_v2(db, + "SELECT * FROM mlinks WHERE pageid=?", + -1, &s, NULL); + if (SQLITE_OK != c) + fprintf(stderr, "%s\n", sqlite3_errmsg(db)); for (mp = ohash_first(&htab, &idx); NULL != mp; @@ -292,16 +299,50 @@ mansearch(const struct mansearch *search, *res = mandoc_realloc (*res, maxres * sizeof(struct manpage)); } - strlcpy((*res)[cur].file, - paths->paths[i], PATH_MAX); - strlcat((*res)[cur].file, "/", PATH_MAX); - strlcat((*res)[cur].file, mp->file, PATH_MAX); - (*res)[cur].desc = mp->desc; - (*res)[cur].form = mp->form; + mpage = *res + cur; + if (-1 == asprintf(&mpage->file, "%s/%s", + paths->paths[i], mp->file)) { + perror(0); + exit((int)MANDOCLEVEL_SYSERR); + } + mpage->names = NULL; + mpage->desc = mp->desc; + mpage->form = mp->form; + + j = 1; + SQL_BIND_INT64(db, s, j, mp->id); + while (SQLITE_ROW == (c = sqlite3_step(s))) { + if (NULL == mpage->names) { + oldnames = ""; + sep1 = ""; + } else { + oldnames = mpage->names; + sep1 = ", "; + } + sec = sqlite3_column_text(s, 1); + arch = sqlite3_column_text(s, 2); + name = sqlite3_column_text(s, 3); + sep2 = '\0' == *arch ? "" : "/"; + if (-1 == asprintf(&newnames, + "%s%s%s(%s%s%s)", oldnames, sep1, + name, sec, sep2, arch)) { + perror(0); + exit((int)MANDOCLEVEL_SYSERR); + } + free(mpage->names); + mpage->names = newnames; + } + if (SQLITE_DONE != c) + fprintf(stderr, "%s\n", sqlite3_errmsg(db)); + sqlite3_reset(s); + free(mp->file); free(mp); cur++; } + + sqlite3_finalize(s); + sqlite3_close(db); ohash_delete(&htab); } rc = 1; diff --git a/mansearch.h b/mansearch.h index e1616e05..9b7a0a2f 100644 --- a/mansearch.h +++ b/mansearch.h @@ -61,7 +61,8 @@ __BEGIN_DECLS struct manpage { - char file[PATH_MAX]; /* prefixed by manpath */ + char *file; /* to be prefixed by manpath */ + char *names; /* a list of names with sections */ char *desc; /* description of manpage */ int form; /* 0 == catpage */ }; |