aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/apropos.c
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2012-06-08 10:44:52 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2012-06-08 10:44:52 +0000
commit5f164a6735403143d675639fe5dee257a943e09c (patch)
tree39a8d39df25f3b2b4b37e4acaf031640d632cbfc /apropos.c
parente65910f2c18c908bff6c793aeaa30f94bc89a8bc (diff)
downloadmandoc-5f164a6735403143d675639fe5dee257a943e09c.tar.gz
mandoc-5f164a6735403143d675639fe5dee257a943e09c.tar.zst
mandoc-5f164a6735403143d675639fe5dee257a943e09c.zip
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.
Diffstat (limited to 'apropos.c')
-rw-r--r--apropos.c199
1 files changed, 32 insertions, 167 deletions
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 <kristaps@bsd.lv>
- * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
*
* 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 <string.h>
#include <unistd.h>
-#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);
-}