Annotation of src/usr.bin/mandoc/apropos.c, Revision 1.8
1.8 ! schwarze 1: /* $Id: apropos.c,v 1.7 2011/11/18 01:10:03 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.8 ! schwarze 37: int ch, rc;
! 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.8 ! schwarze 52: memset(&paths, 0, sizeof(struct manpaths));
! 53: memset(&opts, 0, sizeof(struct opts));
! 54:
! 55: auxpaths = defpaths = NULL;
! 56: e = NULL;
! 57: rc = 0;
! 58:
! 59: while (-1 != (ch = getopt(argc, argv, "M:m:S:s:")))
1.1 schwarze 60: switch (ch) {
1.6 schwarze 61: case ('M'):
1.8 ! schwarze 62: defpaths = optarg;
! 63: break;
1.6 schwarze 64: case ('m'):
1.8 ! schwarze 65: auxpaths = optarg;
1.6 schwarze 66: break;
1.3 schwarze 67: case ('S'):
1.1 schwarze 68: opts.arch = optarg;
69: break;
1.3 schwarze 70: case ('s'):
1.1 schwarze 71: opts.cat = optarg;
72: break;
73: default:
74: usage();
1.8 ! schwarze 75: goto out;
1.1 schwarze 76: }
77:
78: argc -= optind;
79: argv += optind;
80:
1.8 ! schwarze 81: if (0 == argc) {
! 82: rc = 1;
! 83: goto out;
! 84: }
! 85:
! 86: manpath_parse(&paths, defpaths, auxpaths);
1.1 schwarze 87:
1.5 schwarze 88: if (NULL == (e = exprcomp(argc, argv, &terms))) {
1.8 ! schwarze 89: fprintf(stderr, "%s: Bad expression\n", progname);
! 90: goto out;
1.3 schwarze 91: }
1.1 schwarze 92:
1.8 ! schwarze 93: rc = apropos_search
! 94: (paths.sz, paths.paths,
! 95: &opts, e, terms, NULL, list);
! 96:
! 97: if (0 == rc)
! 98: fprintf(stderr, "%s: Error reading "
! 99: "manual database\n", progname);
1.6 schwarze 100:
1.8 ! schwarze 101: out:
! 102: manpath_free(&paths);
1.3 schwarze 103: exprfree(e);
1.8 ! schwarze 104:
! 105: return(rc ? EXIT_SUCCESS : EXIT_FAILURE);
1.1 schwarze 106: }
107:
1.3 schwarze 108: /* ARGSUSED */
1.1 schwarze 109: static void
1.7 schwarze 110: list(struct res *res, size_t sz, void *arg)
1.1 schwarze 111: {
1.3 schwarze 112: int i;
1.1 schwarze 113:
1.7 schwarze 114: qsort(res, sz, sizeof(struct res), cmp);
1.1 schwarze 115:
1.3 schwarze 116: for (i = 0; i < (int)sz; i++)
1.8 ! schwarze 117: printf("%s(%s%s%s) - %s\n", res[i].title,
! 118: res[i].cat,
1.1 schwarze 119: *res[i].arch ? "/" : "",
120: *res[i].arch ? res[i].arch : "",
121: res[i].desc);
122: }
123:
124: static int
1.3 schwarze 125: cmp(const void *p1, const void *p2)
1.1 schwarze 126: {
127:
1.7 schwarze 128: return(strcmp(((const struct res *)p1)->title,
129: ((const struct res *)p2)->title));
1.1 schwarze 130: }
131:
1.3 schwarze 132: static void
133: usage(void)
1.1 schwarze 134: {
135:
1.3 schwarze 136: fprintf(stderr, "usage: %s "
1.6 schwarze 137: "[-M path] "
138: "[-m path] "
1.3 schwarze 139: "[-S arch] "
140: "[-s section] "
1.8 ! schwarze 141: "expression...\n",
1.3 schwarze 142: progname);
1.1 schwarze 143: }