Annotation of src/usr.bin/mandoc/apropos.c, Revision 1.5
1.5 ! schwarze 1: /* $Id: apropos.c,v 1.4 2011/11/13 11:07:10 schwarze Exp $ */
1.1 schwarze 2: /*
1.3 schwarze 3: * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
1.1 schwarze 4: *
5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
8: *
9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16: */
17: #include <assert.h>
18: #include <getopt.h>
19: #include <limits.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"
26:
1.3 schwarze 27: static int cmp(const void *, const void *);
28: static void list(struct rec *, size_t, void *);
1.1 schwarze 29: static void usage(void);
30:
1.2 schwarze 31: static char *progname;
1.1 schwarze 32:
33: int
34: apropos(int argc, char *argv[])
35: {
1.4 schwarze 36: int ch;
1.5 ! schwarze 37: size_t terms;
1.1 schwarze 38: struct opts opts;
1.3 schwarze 39: struct expr *e;
1.1 schwarze 40: extern int optind;
41: extern char *optarg;
42:
43: memset(&opts, 0, sizeof(struct opts));
44:
45: progname = strrchr(argv[0], '/');
46: if (progname == NULL)
47: progname = argv[0];
48: else
49: ++progname;
50:
1.4 schwarze 51: while (-1 != (ch = getopt(argc, argv, "S:s:")))
1.1 schwarze 52: switch (ch) {
1.3 schwarze 53: case ('S'):
1.1 schwarze 54: opts.arch = optarg;
55: break;
1.3 schwarze 56: case ('s'):
1.1 schwarze 57: opts.cat = optarg;
58: break;
59: default:
60: usage();
61: return(EXIT_FAILURE);
62: }
63:
64: argc -= optind;
65: argv += optind;
66:
1.3 schwarze 67: if (0 == argc)
68: return(EXIT_SUCCESS);
1.1 schwarze 69:
1.5 ! schwarze 70: if (NULL == (e = exprcomp(argc, argv, &terms))) {
1.3 schwarze 71: fprintf(stderr, "Bad expression\n");
72: return(EXIT_FAILURE);
73: }
1.1 schwarze 74:
1.2 schwarze 75: /*
76: * Configure databases.
77: * The keyword database is a btree that allows for duplicate
78: * entries.
79: * The index database is a recno.
80: */
81:
1.5 ! schwarze 82: apropos_search(&opts, e, terms, NULL, list);
1.3 schwarze 83: exprfree(e);
84: return(EXIT_SUCCESS);
1.1 schwarze 85: }
86:
1.3 schwarze 87: /* ARGSUSED */
1.1 schwarze 88: static void
1.3 schwarze 89: list(struct rec *res, size_t sz, void *arg)
1.1 schwarze 90: {
1.3 schwarze 91: int i;
1.1 schwarze 92:
1.3 schwarze 93: qsort(res, sz, sizeof(struct rec), cmp);
1.1 schwarze 94:
1.3 schwarze 95: for (i = 0; i < (int)sz; i++)
1.1 schwarze 96: printf("%s(%s%s%s) - %s\n", res[i].title,
97: res[i].cat,
98: *res[i].arch ? "/" : "",
99: *res[i].arch ? res[i].arch : "",
100: res[i].desc);
101: }
102:
103: static int
1.3 schwarze 104: cmp(const void *p1, const void *p2)
1.1 schwarze 105: {
106:
1.3 schwarze 107: return(strcmp(((const struct rec *)p1)->title,
108: ((const struct rec *)p2)->title));
1.1 schwarze 109: }
110:
1.3 schwarze 111: static void
112: usage(void)
1.1 schwarze 113: {
114:
1.3 schwarze 115: fprintf(stderr, "usage: %s "
116: "[-I] "
117: "[-S arch] "
118: "[-s section] "
119: "EXPR\n",
120: progname);
1.1 schwarze 121: }