[BACK]Return to apropos.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / mandoc

Annotation of src/usr.bin/mandoc/apropos.c, Revision 1.6

1.6     ! schwarze    1: /*     $Id: apropos.c,v 1.5 2011/11/16 13:23:27 schwarze Exp $ */
1.1       schwarze    2: /*
1.3       schwarze    3:  * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
1.1       schwarze    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.3       schwarze   24: #include "apropos_db.h"
1.6     ! schwarze   25: #include "man_conf.h"
1.1       schwarze   26: #include "mandoc.h"
                     27:
1.3       schwarze   28: static int      cmp(const void *, const void *);
                     29: static void     list(struct rec *, 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.6     ! schwarze   37:        struct man_conf  dirs;
        !            38:        int              ch, use_man_conf;
1.5       schwarze   39:        size_t           terms;
1.1       schwarze   40:        struct opts      opts;
1.3       schwarze   41:        struct expr     *e;
1.1       schwarze   42:        extern int       optind;
                     43:        extern char     *optarg;
                     44:
1.6     ! schwarze   45:        memset(&dirs, 0, sizeof(struct man_conf));
1.1       schwarze   46:        memset(&opts, 0, sizeof(struct opts));
1.6     ! schwarze   47:        use_man_conf = 1;
1.1       schwarze   48:
                     49:        progname = strrchr(argv[0], '/');
                     50:        if (progname == NULL)
                     51:                progname = argv[0];
                     52:        else
                     53:                ++progname;
                     54:
1.6     ! schwarze   55:        while (-1 != (ch = getopt(argc, argv, "M:m:S:s:")))
1.1       schwarze   56:                switch (ch) {
1.6     ! schwarze   57:                case ('M'):
        !            58:                        use_man_conf = 0;
        !            59:                        /* FALLTHROUGH */
        !            60:                case ('m'):
        !            61:                        manpath_parse(&dirs, optarg);
        !            62:                        break;
1.3       schwarze   63:                case ('S'):
1.1       schwarze   64:                        opts.arch = optarg;
                     65:                        break;
1.3       schwarze   66:                case ('s'):
1.1       schwarze   67:                        opts.cat = optarg;
                     68:                        break;
                     69:                default:
                     70:                        usage();
                     71:                        return(EXIT_FAILURE);
                     72:                }
                     73:
                     74:        argc -= optind;
                     75:        argv += optind;
                     76:
1.3       schwarze   77:        if (0 == argc)
                     78:                return(EXIT_SUCCESS);
1.1       schwarze   79:
1.5       schwarze   80:        if (NULL == (e = exprcomp(argc, argv, &terms))) {
1.3       schwarze   81:                fprintf(stderr, "Bad expression\n");
                     82:                return(EXIT_FAILURE);
                     83:        }
1.1       schwarze   84:
1.2       schwarze   85:        /*
                     86:         * Configure databases.
                     87:         * The keyword database is a btree that allows for duplicate
                     88:         * entries.
                     89:         * The index database is a recno.
                     90:         */
                     91:
1.6     ! schwarze   92:        if (use_man_conf)
        !            93:                man_conf_parse(&dirs);
        !            94:        apropos_search(dirs.argc, dirs.argv, &opts,
        !            95:                        e, terms, NULL, list);
        !            96:
        !            97:        man_conf_free(&dirs);
1.3       schwarze   98:        exprfree(e);
                     99:        return(EXIT_SUCCESS);
1.1       schwarze  100: }
                    101:
1.3       schwarze  102: /* ARGSUSED */
1.1       schwarze  103: static void
1.3       schwarze  104: list(struct rec *res, size_t sz, void *arg)
1.1       schwarze  105: {
1.3       schwarze  106:        int              i;
1.1       schwarze  107:
1.3       schwarze  108:        qsort(res, sz, sizeof(struct rec), cmp);
1.1       schwarze  109:
1.3       schwarze  110:        for (i = 0; i < (int)sz; i++)
1.1       schwarze  111:                printf("%s(%s%s%s) - %s\n", res[i].title,
                    112:                                res[i].cat,
                    113:                                *res[i].arch ? "/" : "",
                    114:                                *res[i].arch ? res[i].arch : "",
                    115:                                res[i].desc);
                    116: }
                    117:
                    118: static int
1.3       schwarze  119: cmp(const void *p1, const void *p2)
1.1       schwarze  120: {
                    121:
1.3       schwarze  122:        return(strcmp(((const struct rec *)p1)->title,
                    123:                                ((const struct rec *)p2)->title));
1.1       schwarze  124: }
                    125:
1.3       schwarze  126: static void
                    127: usage(void)
1.1       schwarze  128: {
                    129:
1.3       schwarze  130:        fprintf(stderr, "usage: %s "
1.6     ! schwarze  131:                        "[-M path] "
        !           132:                        "[-m path] "
1.3       schwarze  133:                        "[-S arch] "
                    134:                        "[-s section] "
                    135:                        "EXPR\n",
                    136:                        progname);
1.1       schwarze  137: }