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