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

Annotation of mandoc/apropos.c, Revision 1.13

1.13    ! kristaps    1: /*     $Id: apropos.c,v 1.12 2011/11/13 11:10:27 schwarze 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:  */
1.13    ! kristaps   17: #ifdef HAVE_CONFIG_H
        !            18: #include "config.h"
        !            19: #endif
        !            20:
1.1       kristaps   21: #include <assert.h>
                     22: #include <getopt.h>
                     23: #include <limits.h>
                     24: #include <stdio.h>
                     25: #include <stdlib.h>
                     26: #include <string.h>
                     27:
1.11      schwarze   28: #include "apropos_db.h"
1.1       kristaps   29: #include "mandoc.h"
                     30:
1.8       kristaps   31: static int      cmp(const void *, const void *);
                     32: static void     list(struct rec *, size_t, void *);
1.1       kristaps   33: static void     usage(void);
                     34:
1.2       kristaps   35: static char    *progname;
1.1       kristaps   36:
                     37: int
                     38: main(int argc, char *argv[])
                     39: {
1.12      schwarze   40:        int              ch;
1.13    ! kristaps   41:        size_t           sz;
        !            42:        char            *buf;
1.1       kristaps   43:        struct opts      opts;
1.10      kristaps   44:        struct expr     *e;
1.1       kristaps   45:        extern int       optind;
                     46:        extern char     *optarg;
                     47:
                     48:        memset(&opts, 0, sizeof(struct opts));
                     49:
                     50:        progname = strrchr(argv[0], '/');
                     51:        if (progname == NULL)
                     52:                progname = argv[0];
                     53:        else
                     54:                ++progname;
                     55:
1.12      schwarze   56:        while (-1 != (ch = getopt(argc, argv, "S:s:")))
1.1       kristaps   57:                switch (ch) {
1.9       kristaps   58:                case ('S'):
1.1       kristaps   59:                        opts.arch = optarg;
                     60:                        break;
1.9       kristaps   61:                case ('s'):
1.1       kristaps   62:                        opts.cat = optarg;
                     63:                        break;
                     64:                default:
                     65:                        usage();
                     66:                        return(EXIT_FAILURE);
                     67:                }
                     68:
                     69:        argc -= optind;
                     70:        argv += optind;
                     71:
1.10      kristaps   72:        if (0 == argc)
1.8       kristaps   73:                return(EXIT_SUCCESS);
1.1       kristaps   74:
1.13    ! kristaps   75:        /*
        !            76:         * Collapse expressions into a single string.
        !            77:         * First count up the contained strings, adding a space at the
        !            78:         * end of each (plus nil-terminator).  Then merge.
        !            79:         */
        !            80:
        !            81:        for (sz = 0, ch = 0; ch < argc; ch++)
        !            82:                sz += strlen(argv[ch]) + 1;
        !            83:
        !            84:        buf = mandoc_malloc(++sz);
        !            85:
        !            86:        for (*buf = '\0', ch = 0; ch < argc; ch++) {
        !            87:                strlcat(buf, argv[ch], sz);
        !            88:                strlcat(buf, " ", sz);
        !            89:        }
        !            90:
        !            91:        buf[sz - 2] = '\0';
        !            92:
        !            93:        if (NULL == (e = exprcomp(buf))) {
1.10      kristaps   94:                fprintf(stderr, "Bad expression\n");
1.13    ! kristaps   95:                free(buf);
1.10      kristaps   96:                return(EXIT_FAILURE);
                     97:        }
1.13    ! kristaps   98:
        !            99:        free(buf);
1.1       kristaps  100:
1.2       kristaps  101:        /*
                    102:         * Configure databases.
                    103:         * The keyword database is a btree that allows for duplicate
                    104:         * entries.
                    105:         * The index database is a recno.
                    106:         */
                    107:
1.10      kristaps  108:        apropos_search(&opts, e, NULL, list);
                    109:        exprfree(e);
1.8       kristaps  110:        return(EXIT_SUCCESS);
1.1       kristaps  111: }
                    112:
1.8       kristaps  113: /* ARGSUSED */
1.1       kristaps  114: static void
1.8       kristaps  115: list(struct rec *res, size_t sz, void *arg)
1.1       kristaps  116: {
1.8       kristaps  117:        int              i;
1.1       kristaps  118:
1.8       kristaps  119:        qsort(res, sz, sizeof(struct rec), cmp);
1.1       kristaps  120:
1.8       kristaps  121:        for (i = 0; i < (int)sz; i++)
1.1       kristaps  122:                printf("%s(%s%s%s) - %s\n", res[i].title,
                    123:                                res[i].cat,
                    124:                                *res[i].arch ? "/" : "",
                    125:                                *res[i].arch ? res[i].arch : "",
                    126:                                res[i].desc);
                    127: }
                    128:
1.8       kristaps  129: static int
                    130: cmp(const void *p1, const void *p2)
                    131: {
                    132:
                    133:        return(strcmp(((const struct rec *)p1)->title,
                    134:                                ((const struct rec *)p2)->title));
                    135: }
                    136:
1.1       kristaps  137: static void
                    138: usage(void)
                    139: {
                    140:
                    141:        fprintf(stderr, "usage: %s "
1.8       kristaps  142:                        "[-I] "
1.9       kristaps  143:                        "[-S arch] "
                    144:                        "[-s section] "
1.10      kristaps  145:                        "EXPR\n",
                    146:                        progname);
1.1       kristaps  147: }

CVSweb