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