From b029b3cbf4ce3eeea06b12cda0ccf718b5c9218a Mon Sep 17 00:00:00 2001 From: Kristaps Dzonsons Date: Fri, 8 Jun 2012 10:44:52 +0000 Subject: Flip apropos to use mansearch instead of apropos_db. This makes the utility much smaller and simpler. A lot of functionality has been omitted while the sqlite3 search routines improve (logical operations, etc.). It still needs work to make the output more conventional. Also add the manpage utility, which I use extensively as a mind-meld of apropos and man. --- apropos.c | 197 ++++++++++---------------------------------------------------- 1 file changed, 31 insertions(+), 166 deletions(-) (limited to 'apropos.c') diff --git a/apropos.c b/apropos.c index 2f1f90b1..1fd3a528 100644 --- a/apropos.c +++ b/apropos.c @@ -1,7 +1,6 @@ /* $Id$ */ /* - * Copyright (c) 2011, 2012 Kristaps Dzonsons - * Copyright (c) 2011 Ingo Schwarze + * Copyright (c) 2012 Kristaps Dzonsons * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -27,38 +26,21 @@ #include #include -#include "apropos_db.h" -#include "mandoc.h" #include "manpath.h" - -#define SINGLETON(_res, _sz) \ - ((_sz) && (_res)[0].matched && \ - (1 == (_sz) || 0 == (_res)[1].matched)) -#define EMPTYSET(_res, _sz) \ - ((0 == (_sz)) || 0 == (_res)[0].matched) - -static int cmp(const void *, const void *); -static void list(struct res *, size_t, void *); -static void usage(void); - -static char *progname; +#include "mansearch.h" int main(int argc, char *argv[]) { - int ch, rc, whatis, usecat; - struct res *res; + int ch; + size_t i, sz; + struct manpage *res; + char *conf_file, *defpaths, *auxpaths, + *arch, *sec; struct manpaths paths; - const char *prog; - pid_t pid; - char path[PATH_MAX]; - int fds[2]; - size_t terms, ressz, sz; - struct opts opts; - struct expr *e; - char *defpaths, *auxpaths, *conf_file, *cp; - extern int optind; + char *progname; extern char *optarg; + extern int optind; progname = strrchr(argv[0], '/'); if (progname == NULL) @@ -66,18 +48,8 @@ main(int argc, char *argv[]) else ++progname; - whatis = 0 == strncmp(progname, "whatis", 6); - + auxpaths = defpaths = conf_file = arch = sec = NULL; memset(&paths, 0, sizeof(struct manpaths)); - memset(&opts, 0, sizeof(struct opts)); - - usecat = 0; - ressz = 0; - res = NULL; - auxpaths = defpaths = NULL; - conf_file = NULL; - e = NULL; - path[0] = '\0'; while (-1 != (ch = getopt(argc, argv, "C:M:m:S:s:"))) switch (ch) { @@ -91,149 +63,42 @@ main(int argc, char *argv[]) auxpaths = optarg; break; case ('S'): - opts.arch = optarg; + arch = optarg; break; case ('s'): - opts.cat = optarg; + sec = optarg; break; default: - usage(); - return(EXIT_FAILURE); + goto usage; } argc -= optind; argv += optind; - if (0 == argc) - return(EXIT_SUCCESS); - - rc = 0; + if (0 == argc) + goto usage; manpath_parse(&paths, conf_file, defpaths, auxpaths); - - e = whatis ? termcomp(argc, argv, &terms) : - exprcomp(argc, argv, &terms); - - if (NULL == e) { - fprintf(stderr, "%s: Bad expression\n", progname); - goto out; - } - - rc = apropos_search - (paths.sz, paths.paths, &opts, - e, terms, NULL, &ressz, &res, list); - - terms = 1; - - if (0 == rc) { - fprintf(stderr, "%s: Bad database\n", progname); - goto out; - } else if ( ! isatty(STDOUT_FILENO) || EMPTYSET(res, ressz)) - goto out; - - if ( ! SINGLETON(res, ressz)) { - printf("Which manpage would you like [1]? "); - fflush(stdout); - if (NULL != (cp = fgetln(stdin, &sz)) && - sz > 1 && '\n' == cp[--sz]) { - if ((ch = atoi(cp)) <= 0) - goto out; - terms = (size_t)ch; - } - } - - if (--terms < ressz && res[terms].matched) { - chdir(paths.paths[res[terms].volume]); - strlcpy(path, res[terms].file, PATH_MAX); - usecat = RESTYPE_CAT == res[terms].type; - } -out: + ch = mansearch(&paths, arch, sec, argc, argv, &res, &sz); manpath_free(&paths); - resfree(res, ressz); - exprfree(e); - if ('\0' == path[0]) - return(rc ? EXIT_SUCCESS : EXIT_FAILURE); + if (0 == ch) + goto usage; - if (-1 == pipe(fds)) { - perror(NULL); - exit(EXIT_FAILURE); + for (i = 0; i < sz; i++) { + printf("%s - %s\n", res[i].file, res[i].desc); + free(res[i].desc); } - if (-1 == (pid = fork())) { - perror(NULL); - exit(EXIT_FAILURE); - } else if (pid > 0) { - dup2(fds[0], STDIN_FILENO); - close(fds[1]); - prog = NULL != getenv("MANPAGER") ? - getenv("MANPAGER") : - (NULL != getenv("PAGER") ? - getenv("PAGER") : "more"); - execlp(prog, prog, (char *)NULL); - perror(prog); - return(EXIT_FAILURE); - } - - dup2(fds[1], STDOUT_FILENO); - close(fds[0]); - prog = usecat ? "cat" : "mandoc"; - execlp(prog, prog, path, (char *)NULL); - perror(prog); + free(res); + return(sz ? EXIT_SUCCESS : EXIT_FAILURE); +usage: + fprintf(stderr, "usage: %s [-C conf] " + "[-M paths] " + "[-m paths] " + "[-S arch] " + "[-s section] " + "expr ...\n", + progname); return(EXIT_FAILURE); } - -/* ARGSUSED */ -static void -list(struct res *res, size_t sz, void *arg) -{ - size_t i; - - qsort(res, sz, sizeof(struct res), cmp); - - if (EMPTYSET(res, sz) || SINGLETON(res, sz)) - return; - - if ( ! isatty(STDOUT_FILENO)) - for (i = 0; i < sz && res[i].matched; i++) - printf("%s(%s%s%s) - %.70s\n", - res[i].title, res[i].cat, - *res[i].arch ? "/" : "", - *res[i].arch ? res[i].arch : "", - res[i].desc); - else - for (i = 0; i < sz && res[i].matched; i++) - printf("[%zu] %s(%s%s%s) - %.70s\n", i + 1, - res[i].title, res[i].cat, - *res[i].arch ? "/" : "", - *res[i].arch ? res[i].arch : "", - res[i].desc); -} - -static int -cmp(const void *p1, const void *p2) -{ - const struct res *r1 = p1; - const struct res *r2 = p2; - - if (0 == r1->matched) - return(1); - else if (0 == r2->matched) - return(1); - - return(strcasecmp(r1->title, r2->title)); -} - -static void -usage(void) -{ - - fprintf(stderr, "usage: %s " - "[-C file] " - "[-M manpath] " - "[-m manpath] " - "[-S arch] " - "[-s section] " - "expression ...\n", - progname); -} -- cgit