summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--main.c109
1 files changed, 105 insertions, 4 deletions
diff --git a/main.c b/main.c
index 231609d8..e406cadd 100644
--- a/main.c
+++ b/main.c
@@ -82,6 +82,15 @@ struct curparse {
char outopts[BUFSIZ]; /* buf of output opts */
};
+#if HAVE_SQLITE3
+static int fs_lookup(const struct manpaths *,
+ size_t ipath, const char *,
+ const char *, const char *,
+ struct manpage **, size_t *);
+static void fs_search(const struct mansearch *,
+ const struct manpaths *, int, char**,
+ struct manpage **, size_t *);
+#endif
static int koptions(int *, char *);
#if HAVE_SQLITE3
int mandocdb(int, char**);
@@ -340,12 +349,11 @@ main(int argc, char *argv[])
mansearch_setup(1);
if( ! mansearch(&search, &paths, argc, argv, &res, &sz))
usage(search.argmode);
- resp = res;
+
+ if (sz == 0 && search.argmode == ARG_NAME)
+ fs_search(&search, &paths, argc, argv, &res, &sz);
if (sz == 0) {
- if (search.argmode == ARG_NAME)
- fprintf(stderr, "%s: No entry for %s "
- "in the manual.\n", progname, argv[0]);
rc = MANDOCLEVEL_BADARG;
goto out;
}
@@ -364,6 +372,7 @@ main(int argc, char *argv[])
/* Iterate all matching manuals. */
+ resp = res;
for (i = 0; i < sz; i++) {
if (outmode == OUTMODE_FLN)
puts(res[i].file);
@@ -525,6 +534,98 @@ usage(enum argmode argmode)
exit((int)MANDOCLEVEL_BADARG);
}
+#if HAVE_SQLITE3
+static int
+fs_lookup(const struct manpaths *paths, size_t ipath,
+ const char *sec, const char *arch, const char *name,
+ struct manpage **res, size_t *ressz)
+{
+ struct manpage *page;
+ char *file;
+ int form;
+
+ mandoc_asprintf(&file, "%s/man%s/%s.%s",
+ paths->paths[ipath], sec, name, sec);
+ if (access(file, R_OK) != -1) {
+ form = FORM_SRC;
+ goto found;
+ }
+ free(file);
+
+ mandoc_asprintf(&file, "%s/cat%s/%s.0",
+ paths->paths[ipath], sec, name);
+ if (access(file, R_OK) != -1) {
+ form = FORM_CAT;
+ goto found;
+ }
+ free(file);
+
+ if (arch != NULL) {
+ mandoc_asprintf(&file, "%s/man%s/%s/%s.%s",
+ paths->paths[ipath], sec, arch, name, sec);
+ if (access(file, R_OK) != -1) {
+ form = FORM_SRC;
+ goto found;
+ }
+ free(file);
+ }
+ return(0);
+
+found:
+ fprintf(stderr, "%s: outdated mandoc.db lacks %s(%s) entry,\n"
+ " consider running # makewhatis %s\n",
+ progname, name, sec, paths->paths[ipath]);
+
+ *res = mandoc_reallocarray(*res, ++*ressz, sizeof(struct manpage));
+ page = *res + (*ressz - 1);
+ page->file = file;
+ page->names = NULL;
+ page->output = NULL;
+ page->ipath = ipath;
+ page->bits = NAME_FILE & NAME_MASK;
+ page->sec = (*sec >= '1' && *sec <= '9') ? *sec - '1' + 1 : 10;
+ page->form = form;
+ return(1);
+}
+
+static void
+fs_search(const struct mansearch *cfg, const struct manpaths *paths,
+ int argc, char **argv, struct manpage **res, size_t *ressz)
+{
+ const char *const sections[] =
+ {"1", "8", "6", "2", "3", "3p", "5", "7", "4", "9"};
+ const size_t nsec = sizeof(sections)/sizeof(sections[0]);
+
+ size_t ipath, isec, lastsz;
+
+ assert(cfg->argmode == ARG_NAME);
+
+ *res = NULL;
+ *ressz = lastsz = 0;
+ while (argc) {
+ for (ipath = 0; ipath < paths->sz; ipath++) {
+ if (cfg->sec != NULL) {
+ if (fs_lookup(paths, ipath, cfg->sec,
+ cfg->arch, *argv, res, ressz) &&
+ cfg->firstmatch)
+ return;
+ } else for (isec = 0; isec < nsec; isec++)
+ if (fs_lookup(paths, ipath, sections[isec],
+ cfg->arch, *argv, res, ressz) &&
+ cfg->firstmatch)
+ return;
+ }
+ if (*ressz == lastsz)
+ fprintf(stderr,
+ "%s: No entry for %s in the manual.\n",
+ progname, *argv);
+ lastsz = *ressz;
+ argv++;
+ argc--;
+ }
+}
+#endif
+
static void
parse(struct curparse *curp, int fd, const char *file,
enum mandoclevel *level)