[BACK]Return to apropos.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

Annotation of mandoc/apropos.c, Revision 1.8

1.8     ! kristaps    1: /*     $Id: apropos.c,v 1.7 2011/10/09 10:46:38 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.8     ! kristaps   75:        while (-1 != (ch = getopt(argc, argv, "a:c:I:t:")))
1.1       kristaps   76:                switch (ch) {
                     77:                case ('a'):
                     78:                        opts.arch = optarg;
                     79:                        break;
                     80:                case ('c'):
                     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.1       kristaps  162:                        "[-a arch] "
                    163:                        "[-c cat] "
                    164:                        "[-t type[,...]] "
                    165:                        "key\n", progname);
                    166: }

CVSweb