Annotation of mandoc/apropos.c, Revision 1.9
1.9 ! kristaps 1: /* $Id: apropos.c,v 1.8 2011/11/09 01:24:23 kristaps Exp $ */
1.1 kristaps 2: /*
1.8 kristaps 3: * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
1.1 kristaps 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.8 kristaps 24: #include "apropos.h"
1.1 kristaps 25: #include "mandoc.h"
26:
27: struct type {
28: int mask;
1.2 kristaps 29: const char *name; /* command-line type name */
1.1 kristaps 30: };
31:
32: static const struct type types[] = {
33: { TYPE_NAME, "name" },
34: { TYPE_FUNCTION, "func" },
35: { TYPE_UTILITY, "utility" },
36: { TYPE_INCLUDES, "incl" },
37: { TYPE_VARIABLE, "var" },
38: { TYPE_STANDARD, "stand" },
39: { TYPE_AUTHOR, "auth" },
40: { TYPE_CONFIG, "conf" },
41: { TYPE_DESC, "desc" },
42: { TYPE_XREF, "xref" },
43: { TYPE_PATH, "path" },
44: { TYPE_ENV, "env" },
45: { TYPE_ERR, "err" },
46: { INT_MAX, "all" },
47: { 0, NULL }
48: };
49:
1.8 kristaps 50: static int cmp(const void *, const void *);
51: static void list(struct rec *, size_t, void *);
1.1 kristaps 52: static void usage(void);
53:
1.2 kristaps 54: static char *progname;
1.1 kristaps 55:
56: int
57: main(int argc, char *argv[])
58: {
1.8 kristaps 59: int ch, i;
1.1 kristaps 60: char *q, *v;
61: struct opts opts;
62: extern int optind;
63: extern char *optarg;
64:
65: memset(&opts, 0, sizeof(struct opts));
66:
67: q = NULL;
68:
69: progname = strrchr(argv[0], '/');
70: if (progname == NULL)
71: progname = argv[0];
72: else
73: ++progname;
74:
1.9 ! kristaps 75: while (-1 != (ch = getopt(argc, argv, "S:s:It:")))
1.1 kristaps 76: switch (ch) {
1.9 ! kristaps 77: case ('S'):
1.1 kristaps 78: opts.arch = optarg;
79: break;
1.9 ! kristaps 80: case ('s'):
1.1 kristaps 81: opts.cat = optarg;
82: break;
83: case ('I'):
1.8 kristaps 84: opts.flags |= OPTS_INSENS;
1.1 kristaps 85: break;
86: case ('t'):
87: while (NULL != (v = strsep(&optarg, ","))) {
88: if ('\0' == *v)
89: continue;
90: for (i = 0; types[i].mask; i++) {
91: if (strcmp(types[i].name, v))
92: continue;
93: break;
94: }
95: if (0 == types[i].mask)
96: break;
97: opts.types |= types[i].mask;
98: }
99: if (NULL == v)
100: break;
101:
1.2 kristaps 102: fprintf(stderr, "%s: Bad type\n", v);
1.1 kristaps 103: return(EXIT_FAILURE);
104: default:
105: usage();
106: return(EXIT_FAILURE);
107: }
108:
109: argc -= optind;
110: argv += optind;
111:
112: if (0 == argc || '\0' == **argv) {
113: usage();
1.8 kristaps 114: return(EXIT_SUCCESS);
1.1 kristaps 115: } else
116: q = *argv;
117:
118: if (0 == opts.types)
119: opts.types = TYPE_NAME | TYPE_DESC;
120:
1.2 kristaps 121: /*
122: * Configure databases.
123: * The keyword database is a btree that allows for duplicate
124: * entries.
125: * The index database is a recno.
126: */
127:
1.8 kristaps 128: apropos_search(&opts, q, NULL, list);
129: return(EXIT_SUCCESS);
1.1 kristaps 130: }
131:
1.8 kristaps 132: /* ARGSUSED */
1.1 kristaps 133: static void
1.8 kristaps 134: list(struct rec *res, size_t sz, void *arg)
1.1 kristaps 135: {
1.8 kristaps 136: int i;
1.1 kristaps 137:
1.8 kristaps 138: qsort(res, sz, sizeof(struct rec), cmp);
1.1 kristaps 139:
1.8 kristaps 140: for (i = 0; i < (int)sz; i++)
1.1 kristaps 141: printf("%s(%s%s%s) - %s\n", res[i].title,
142: res[i].cat,
143: *res[i].arch ? "/" : "",
144: *res[i].arch ? res[i].arch : "",
145: res[i].desc);
146: }
147:
1.8 kristaps 148: static int
149: cmp(const void *p1, const void *p2)
150: {
151:
152: return(strcmp(((const struct rec *)p1)->title,
153: ((const struct rec *)p2)->title));
154: }
155:
1.1 kristaps 156: static void
157: usage(void)
158: {
159:
160: fprintf(stderr, "usage: %s "
1.8 kristaps 161: "[-I] "
1.9 ! kristaps 162: "[-S arch] "
! 163: "[-s section] "
1.1 kristaps 164: "[-t type[,...]] "
165: "key\n", progname);
166: }
CVSweb