3.6 branching and setup.
[dragonfly.git] / contrib / mdocml / apropos.c
blob7a7ab69c5b5ab624125e17e1983825bc042bd5e0
1 /* $Id: apropos.c,v 1.27.2.1 2013/09/17 23:23:10 schwarze Exp $ */
2 /*
3 * Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
4 * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
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.
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.
18 #ifdef HAVE_CONFIG_H
19 #include "config.h"
20 #endif
21 #include <sys/param.h>
23 #include <assert.h>
24 #include <getopt.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
29 #include "apropos_db.h"
30 #include "mandoc.h"
31 #include "manpath.h"
33 static int cmp(const void *, const void *);
34 static void list(struct res *, size_t, void *);
36 static char *progname;
38 int
39 main(int argc, char *argv[])
41 int ch, rc, whatis;
42 struct res *res;
43 struct manpaths paths;
44 size_t terms, ressz;
45 struct opts opts;
46 struct expr *e;
47 char *defpaths, *auxpaths;
48 char *conf_file;
49 extern char *optarg;
50 extern int optind;
52 progname = strrchr(argv[0], '/');
53 if (progname == NULL)
54 progname = argv[0];
55 else
56 ++progname;
58 whatis = (0 == strncmp(progname, "whatis", 6));
60 memset(&paths, 0, sizeof(struct manpaths));
61 memset(&opts, 0, sizeof(struct opts));
63 ressz = 0;
64 res = NULL;
65 auxpaths = defpaths = NULL;
66 conf_file = NULL;
67 e = NULL;
69 while (-1 != (ch = getopt(argc, argv, "C:M:m:S:s:")))
70 switch (ch) {
71 case ('C'):
72 conf_file = optarg;
73 break;
74 case ('M'):
75 defpaths = optarg;
76 break;
77 case ('m'):
78 auxpaths = optarg;
79 break;
80 case ('S'):
81 opts.arch = optarg;
82 break;
83 case ('s'):
84 opts.cat = optarg;
85 break;
86 default:
87 goto usage;
90 argc -= optind;
91 argv += optind;
93 if (0 == argc)
94 goto usage;
96 rc = 0;
98 manpath_parse(&paths, conf_file, defpaths, auxpaths);
100 e = whatis ? termcomp(argc, argv, &terms) :
101 exprcomp(argc, argv, &terms);
103 if (NULL == e) {
104 fprintf(stderr, "%s: Bad expression\n", progname);
105 goto out;
108 rc = apropos_search
109 (paths.sz, paths.paths, &opts,
110 e, terms, NULL, &ressz, &res, list);
112 if (0 == rc) {
113 fprintf(stderr, "%s: Bad database\n", progname);
114 goto out;
117 out:
118 manpath_free(&paths);
119 resfree(res, ressz);
120 exprfree(e);
121 return(rc ? EXIT_SUCCESS : EXIT_FAILURE);
123 usage:
124 fprintf(stderr, "usage: %s [-C file] [-M path] [-m path] "
125 "[-S arch] [-s section]%s ...\n", progname,
126 whatis ? " name" : "\n expression");
127 return(EXIT_FAILURE);
130 /* ARGSUSED */
131 static void
132 list(struct res *res, size_t sz, void *arg)
134 size_t i;
136 if (!sz) {
137 printf("nothing appropriate\n");
138 return;
141 qsort(res, sz, sizeof(struct res), cmp);
143 for (i = 0; i < sz; i++) {
144 if ( ! res[i].matched)
145 continue;
146 printf("%s(%s%s%s) - %.70s\n",
147 res[i].title,
148 res[i].cat,
149 *res[i].arch ? "/" : "",
150 *res[i].arch ? res[i].arch : "",
151 res[i].desc);
155 static int
156 cmp(const void *p1, const void *p2)
159 return(strcasecmp(((const struct res *)p1)->title,
160 ((const struct res *)p2)->title));