mdocml: tweak mandocdb(8) database creation
[dragonfly.git] / contrib / mdocml / apropos.c
CommitLineData
f88b6c16 1/* $Id: apropos.c,v 1.27.2.1 2013/09/17 23:23:10 schwarze Exp $ */
36342e81
SW
2/*
3 * Copyright (c) 2011, 2012 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#include <sys/param.h>
22
23#include <assert.h>
24#include <getopt.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
36342e81
SW
28
29#include "apropos_db.h"
30#include "mandoc.h"
31#include "manpath.h"
32
36342e81
SW
33static int cmp(const void *, const void *);
34static void list(struct res *, size_t, void *);
36342e81
SW
35
36static char *progname;
37
38int
39main(int argc, char *argv[])
40{
f88b6c16 41 int ch, rc, whatis;
36342e81
SW
42 struct res *res;
43 struct manpaths paths;
f88b6c16 44 size_t terms, ressz;
36342e81
SW
45 struct opts opts;
46 struct expr *e;
f88b6c16
FF
47 char *defpaths, *auxpaths;
48 char *conf_file;
36342e81 49 extern char *optarg;
f88b6c16 50 extern int optind;
36342e81
SW
51
52 progname = strrchr(argv[0], '/');
53 if (progname == NULL)
54 progname = argv[0];
55 else
56 ++progname;
57
f88b6c16 58 whatis = (0 == strncmp(progname, "whatis", 6));
36342e81
SW
59
60 memset(&paths, 0, sizeof(struct manpaths));
61 memset(&opts, 0, sizeof(struct opts));
62
36342e81
SW
63 ressz = 0;
64 res = NULL;
65 auxpaths = defpaths = NULL;
66 conf_file = NULL;
67 e = NULL;
36342e81
SW
68
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:
f88b6c16 87 goto usage;
36342e81
SW
88 }
89
90 argc -= optind;
91 argv += optind;
92
f88b6c16
FF
93 if (0 == argc)
94 goto usage;
36342e81
SW
95
96 rc = 0;
97
98 manpath_parse(&paths, conf_file, defpaths, auxpaths);
99
100 e = whatis ? termcomp(argc, argv, &terms) :
101 exprcomp(argc, argv, &terms);
102
103 if (NULL == e) {
104 fprintf(stderr, "%s: Bad expression\n", progname);
105 goto out;
106 }
107
108 rc = apropos_search
109 (paths.sz, paths.paths, &opts,
110 e, terms, NULL, &ressz, &res, list);
111
36342e81
SW
112 if (0 == rc) {
113 fprintf(stderr, "%s: Bad database\n", progname);
114 goto out;
36342e81
SW
115 }
116
36342e81
SW
117out:
118 manpath_free(&paths);
119 resfree(res, ressz);
120 exprfree(e);
f88b6c16 121 return(rc ? EXIT_SUCCESS : EXIT_FAILURE);
36342e81 122
f88b6c16
FF
123usage:
124 fprintf(stderr, "usage: %s [-C file] [-M path] [-m path] "
125 "[-S arch] [-s section]%s ...\n", progname,
126 whatis ? " name" : "\n expression");
36342e81
SW
127 return(EXIT_FAILURE);
128}
129
130/* ARGSUSED */
131static void
132list(struct res *res, size_t sz, void *arg)
133{
134 size_t i;
135
7d5f90ab
FF
136 if (!sz) {
137 printf("nothing appropriate\n");
138 return;
139 }
140
36342e81
SW
141 qsort(res, sz, sizeof(struct res), cmp);
142
f88b6c16
FF
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);
152 }
36342e81
SW
153}
154
155static int
156cmp(const void *p1, const void *p2)
36342e81
SW
157{
158
f88b6c16
FF
159 return(strcasecmp(((const struct res *)p1)->title,
160 ((const struct res *)p2)->title));
36342e81 161}