]> git.cameronkatri.com Git - mandoc.git/blob - apropos.c
Use the traditional name "whatis.db" for the mandocdb(8) databases.
[mandoc.git] / apropos.c
1 /* $Id: apropos.c,v 1.24 2011/12/12 02:00:49 schwarze Exp $ */
2 /*
3 * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
4 * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
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 #ifdef HAVE_CONFIG_H
19 #include "config.h"
20 #endif
21
22 #include <assert.h>
23 #include <getopt.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "apropos_db.h"
29 #include "mandoc.h"
30 #include "manpath.h"
31
32 static int cmp(const void *, const void *);
33 static void list(struct res *, size_t, void *);
34 static void usage(void);
35
36 static char *progname;
37
38 int
39 main(int argc, char *argv[])
40 {
41 int ch, rc, whatis;
42 struct manpaths paths;
43 size_t terms;
44 struct opts opts;
45 struct expr *e;
46 char *defpaths, *auxpaths;
47 char *conf_file;
48 extern int optind;
49 extern char *optarg;
50
51 progname = strrchr(argv[0], '/');
52 if (progname == NULL)
53 progname = argv[0];
54 else
55 ++progname;
56
57 whatis = 0 == strncmp(progname, "whatis", 6);
58
59 memset(&paths, 0, sizeof(struct manpaths));
60 memset(&opts, 0, sizeof(struct opts));
61
62 auxpaths = defpaths = NULL;
63 conf_file = NULL;
64 e = NULL;
65
66 while (-1 != (ch = getopt(argc, argv, "C:M:m:S:s:")))
67 switch (ch) {
68 case ('C'):
69 conf_file = optarg;
70 break;
71 case ('M'):
72 defpaths = optarg;
73 break;
74 case ('m'):
75 auxpaths = optarg;
76 break;
77 case ('S'):
78 opts.arch = optarg;
79 break;
80 case ('s'):
81 opts.cat = optarg;
82 break;
83 default:
84 usage();
85 return(EXIT_FAILURE);
86 }
87
88 argc -= optind;
89 argv += optind;
90
91 if (0 == argc)
92 return(EXIT_SUCCESS);
93
94 rc = 0;
95
96 manpath_parse(&paths, conf_file, defpaths, auxpaths);
97
98 e = whatis ? termcomp(argc, argv, &terms) :
99 exprcomp(argc, argv, &terms);
100
101 if (NULL == e) {
102 fprintf(stderr, "%s: Bad expression\n", progname);
103 goto out;
104 }
105
106 rc = apropos_search
107 (paths.sz, paths.paths,
108 &opts, e, terms, NULL, list);
109
110 if (0 == rc)
111 fprintf(stderr, "%s: Error reading "
112 "manual database\n", progname);
113
114 out:
115 manpath_free(&paths);
116 exprfree(e);
117
118 return(rc ? EXIT_SUCCESS : EXIT_FAILURE);
119 }
120
121 /* ARGSUSED */
122 static void
123 list(struct res *res, size_t sz, void *arg)
124 {
125 int i;
126
127 qsort(res, sz, sizeof(struct res), cmp);
128
129 for (i = 0; i < (int)sz; i++)
130 printf("%s(%s%s%s) - %s\n", res[i].title,
131 res[i].cat,
132 *res[i].arch ? "/" : "",
133 *res[i].arch ? res[i].arch : "",
134 res[i].desc);
135 }
136
137 static int
138 cmp(const void *p1, const void *p2)
139 {
140
141 return(strcasecmp(((const struct res *)p1)->title,
142 ((const struct res *)p2)->title));
143 }
144
145 static void
146 usage(void)
147 {
148
149 fprintf(stderr, "usage: %s "
150 "[-C file] "
151 "[-M manpath] "
152 "[-m manpath] "
153 "[-S arch] "
154 "[-s section] "
155 "expression ...\n",
156 progname);
157 }