Annotation of src/usr.bin/mandoc/apropos.c, Revision 1.14
1.14 ! schwarze 1: /* $Id: apropos.c,v 1.13 2011/12/26 12:45:58 schwarze Exp $ */
1.1 schwarze 2: /*
1.3 schwarze 3: * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
1.8 schwarze 4: * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
1.1 schwarze 5: *
6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17: */
18: #include <assert.h>
19: #include <getopt.h>
20: #include <stdio.h>
21: #include <stdlib.h>
22: #include <string.h>
23:
1.3 schwarze 24: #include "apropos_db.h"
1.1 schwarze 25: #include "mandoc.h"
1.8 schwarze 26: #include "manpath.h"
1.1 schwarze 27:
1.3 schwarze 28: static int cmp(const void *, const void *);
1.7 schwarze 29: static void list(struct res *, size_t, void *);
1.1 schwarze 30: static void usage(void);
31:
1.2 schwarze 32: static char *progname;
1.1 schwarze 33:
34: int
35: apropos(int argc, char *argv[])
36: {
1.9 schwarze 37: int ch, rc, whatis;
1.8 schwarze 38: struct manpaths paths;
1.5 schwarze 39: size_t terms;
1.1 schwarze 40: struct opts opts;
1.3 schwarze 41: struct expr *e;
1.8 schwarze 42: char *defpaths, *auxpaths;
1.12 schwarze 43: char *conf_file;
1.1 schwarze 44: extern int optind;
45: extern char *optarg;
46:
47: progname = strrchr(argv[0], '/');
48: if (progname == NULL)
49: progname = argv[0];
50: else
51: ++progname;
52:
1.9 schwarze 53: whatis = 0 == strncmp(progname, "whatis", 6);
54:
1.8 schwarze 55: memset(&paths, 0, sizeof(struct manpaths));
56: memset(&opts, 0, sizeof(struct opts));
57:
58: auxpaths = defpaths = NULL;
1.12 schwarze 59: conf_file = NULL;
1.8 schwarze 60: e = NULL;
61:
1.12 schwarze 62: while (-1 != (ch = getopt(argc, argv, "C:M:m:S:s:")))
1.1 schwarze 63: switch (ch) {
1.12 schwarze 64: case ('C'):
65: conf_file = optarg;
66: break;
1.6 schwarze 67: case ('M'):
1.8 schwarze 68: defpaths = optarg;
69: break;
1.6 schwarze 70: case ('m'):
1.8 schwarze 71: auxpaths = optarg;
1.6 schwarze 72: break;
1.3 schwarze 73: case ('S'):
1.1 schwarze 74: opts.arch = optarg;
75: break;
1.3 schwarze 76: case ('s'):
1.1 schwarze 77: opts.cat = optarg;
78: break;
79: default:
80: usage();
1.9 schwarze 81: return(EXIT_FAILURE);
1.1 schwarze 82: }
83:
84: argc -= optind;
85: argv += optind;
86:
1.9 schwarze 87: if (0 == argc)
88: return(EXIT_SUCCESS);
89:
90: rc = 0;
1.8 schwarze 91:
1.12 schwarze 92: manpath_parse(&paths, conf_file, defpaths, auxpaths);
1.1 schwarze 93:
1.9 schwarze 94: e = whatis ? termcomp(argc, argv, &terms) :
95: exprcomp(argc, argv, &terms);
96:
97: if (NULL == e) {
1.8 schwarze 98: fprintf(stderr, "%s: Bad expression\n", progname);
99: goto out;
1.3 schwarze 100: }
1.1 schwarze 101:
1.8 schwarze 102: rc = apropos_search
103: (paths.sz, paths.paths,
104: &opts, e, terms, NULL, list);
105:
106: if (0 == rc)
107: fprintf(stderr, "%s: Error reading "
108: "manual database\n", progname);
1.6 schwarze 109:
1.8 schwarze 110: out:
111: manpath_free(&paths);
1.3 schwarze 112: exprfree(e);
1.8 schwarze 113:
114: return(rc ? EXIT_SUCCESS : EXIT_FAILURE);
1.1 schwarze 115: }
116:
1.3 schwarze 117: /* ARGSUSED */
1.1 schwarze 118: static void
1.7 schwarze 119: list(struct res *res, size_t sz, void *arg)
1.1 schwarze 120: {
1.3 schwarze 121: int i;
1.1 schwarze 122:
1.7 schwarze 123: qsort(res, sz, sizeof(struct res), cmp);
1.1 schwarze 124:
1.3 schwarze 125: for (i = 0; i < (int)sz; i++)
1.14 ! schwarze 126: printf("%s(%s%s%s) - %.*s\n", res[i].title,
1.8 schwarze 127: res[i].cat,
1.1 schwarze 128: *res[i].arch ? "/" : "",
129: *res[i].arch ? res[i].arch : "",
1.14 ! schwarze 130: 70, res[i].desc);
1.1 schwarze 131: }
132:
133: static int
1.3 schwarze 134: cmp(const void *p1, const void *p2)
1.1 schwarze 135: {
136:
1.11 schwarze 137: return(strcasecmp(((const struct res *)p1)->title,
1.7 schwarze 138: ((const struct res *)p2)->title));
1.1 schwarze 139: }
140:
1.3 schwarze 141: static void
142: usage(void)
1.1 schwarze 143: {
144:
1.3 schwarze 145: fprintf(stderr, "usage: %s "
1.12 schwarze 146: "[-C file] "
1.13 schwarze 147: "[-M path] "
148: "[-m path] "
1.3 schwarze 149: "[-S arch] "
150: "[-s section] "
1.12 schwarze 151: "expression ...\n",
1.3 schwarze 152: progname);
1.1 schwarze 153: }