From 5f164a6735403143d675639fe5dee257a943e09c 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 | 199 ++++++++++---------------------------------------------------- 1 file changed, 32 insertions(+), 167 deletions(-) (limited to 'apropos.c') diff --git a/apropos.c b/apropos.c index 9c3cae96..469bff5e 100644 --- a/apropos.c +++ b/apropos.c @@ -1,7 +1,6 @@ -/* $Id: apropos.c,v 1.30 2012/03/24 02:18:51 kristaps Exp $ */ +/* $Id: apropos.c,v 1.31 2012/06/08 10:44:52 kristaps Exp $ */ /* - * 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 v1.2.3