=================================================================== RCS file: /cvs/mandoc/main.c,v retrieving revision 1.212 retrieving revision 1.213 diff -u -p -r1.212 -r1.213 --- mandoc/main.c 2015/01/13 13:22:22 1.212 +++ mandoc/main.c 2015/01/13 23:17:52 1.213 @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.212 2015/01/13 13:22:22 schwarze Exp $ */ +/* $Id: main.c,v 1.213 2015/01/13 23:17:52 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010-2012, 2014, 2015 Ingo Schwarze @@ -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); @@ -524,6 +533,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,