Annotation of 43BSDTahoe/ucb/man/apropos.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1987 Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted
                      6:  * provided that the above copyright notice and this paragraph are
                      7:  * duplicated in all such forms and that any documentation,
                      8:  * advertising materials, and other materials related to such
                      9:  * distribution and use acknowledge that the software was developed
                     10:  * by the University of California, Berkeley.  The name of the
                     11:  * University may not be used to endorse or promote products derived
                     12:  * from this software without specific prior written permission.
                     13:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     14:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     15:  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     16:  */
                     17: 
                     18: #ifndef lint
                     19: char copyright[] =
                     20: "@(#) Copyright (c) 1987 Regents of the University of California.\n\
                     21:  All rights reserved.\n";
                     22: #endif /* not lint */
                     23: 
                     24: #ifndef lint
                     25: static char sccsid[] = "@(#)apropos.c  5.6 (Berkeley) 6/29/88";
                     26: #endif /* not lint */
                     27: 
                     28: #include <sys/param.h>
                     29: #include <stdio.h>
                     30: #include <ctype.h>
                     31: #include <strings.h>
                     32: 
                     33: #define        DEF_PATH        "/usr/man:/usr/new/man:/usr/local/man"
                     34: #define        MAXLINELEN      1000                    /* max line handled */
                     35: #define        WHATIS          "whatis"                /* database name */
                     36: 
                     37: #define        NO      0                               /* no/false */
                     38: #define        YES     1                               /* yes/true */
                     39: 
                     40: static char *myname;
                     41: 
                     42: main(argc, argv)
                     43:        int argc;
                     44:        char **argv;
                     45: {
                     46:        extern char *optarg;
                     47:        extern int optind;
                     48:        register char *beg, *end, **C;
                     49:        int ch, foundman = NO, *found, isapropos;
                     50:        int a_match(), w_match(), (*match)();
                     51:        char *manpath = NULL, buf[MAXLINELEN + 1], fname[MAXPATHLEN + 1];
                     52:        char wbuf[MAXLINELEN + 1], *getenv(), *malloc();
                     53: 
                     54:        myname = (beg = rindex(*argv, '/')) ? beg + 1 : *argv;
                     55:        if (!strcmp(myname, "apropos")) {
                     56:                isapropos = YES;
                     57:                match = a_match;
                     58:        }
                     59:        else {
                     60:                isapropos = NO;
                     61:                match = w_match;
                     62:        }
                     63:        while ((ch = getopt(argc, argv, "M:P:")) != EOF)
                     64:                switch((char)ch) {
                     65:                        case 'M':
                     66:                        case 'P':               /* backward contemptible */
                     67:                                manpath = optarg;
                     68:                                break;
                     69:                        case '?':
                     70:                        default:
                     71:                                usage();
                     72:                }
                     73:        argv += optind;
                     74:        argc -= optind;
                     75:        if (argc < 1)
                     76:                usage();
                     77: 
                     78:        if (!(manpath = getenv("MANPATH")))
                     79:                manpath = DEF_PATH;
                     80: 
                     81:        /*NOSTRICT*/
                     82:        if (!(found = (int *)malloc((u_int)argc))) {
                     83:                fprintf(stderr, "%s: out of space.\n", myname);
                     84:                exit(1);
                     85:        }
                     86:        bzero((char *)found, argc * sizeof(int));
                     87: 
                     88:        if (isapropos)
                     89:                for (C = argv; *C; ++C)         /* convert to lower-case */
                     90:                        lowstr(*C, *C);
                     91:        else for (C = argv; *C; ++C)            /* trim full paths */
                     92:                if (beg = rindex(*C, '/'))
                     93:                        *C = beg + 1;
                     94: 
                     95:        for (beg = manpath; beg; beg = end) {   /* through path list */
                     96:                end = index(beg, ':');
                     97:                if (!end)
                     98:                        (void)sprintf(fname, "%s/%s", beg, WHATIS);
                     99:                else {
                    100:                        (void)sprintf(fname, "%.*s/%s", end - beg, beg, WHATIS);
                    101:                        ++end;
                    102:                }
                    103:                if (!freopen(fname, "r", stdin))
                    104:                        continue;
                    105: 
                    106:                                                /* for each file found */
                    107:                for (foundman = YES; gets(buf);) {
                    108:                        if (isapropos)
                    109:                                lowstr(buf, wbuf);
                    110:                        else
                    111:                                dashtrunc(buf, wbuf);
                    112:                        for (C = argv; *C; ++C)
                    113:                                if ((*match)(wbuf, *C)) {
                    114:                                        puts(buf);
                    115:                                        found[C - argv] = YES;
                    116: 
                    117:                                        /* only print line once */
                    118:                                        while (*++C)
                    119:                                                if ((*match)(wbuf, *C))
                    120:                                                        found[C - argv] = YES;
                    121:                                        break;
                    122:                                }
                    123:                }
                    124:        }
                    125:        if (!foundman) {
                    126:                fprintf(stderr, "%s: no %s file found in %s.\n", myname, WHATIS, manpath);
                    127:                exit(1);
                    128:        }
                    129:        for (C = argv; *C; ++C)
                    130:                if (!found[C - argv])
                    131:                        printf("%s: %s\n", *C, isapropos ? "nothing appropriate" : "not found");
                    132: }
                    133: 
                    134: /*
                    135:  * a_match --
                    136:  *     match for apropos; anywhere the string appears
                    137:  */
                    138: static
                    139: a_match(bp, str)
                    140:        register char *bp, *str;
                    141: {
                    142:        register int len;
                    143:        register char test;
                    144: 
                    145:        if (!*bp)
                    146:                return(NO);
                    147:        /* backward compatible: everything matches empty string */
                    148:        if (!*str)
                    149:                return(YES);
                    150:        for (test = *str++, len = strlen(str); *bp;)
                    151:                if (test == *bp++ && !strncmp(bp, str, len))
                    152:                        return(YES);
                    153:        return(NO);
                    154: }
                    155: 
                    156: /*
                    157:  * w_match --
                    158:  *     match for whatis; looks for full word match
                    159:  */
                    160: static
                    161: w_match(bp, str)
                    162:        register char *bp, *str;
                    163: {
                    164:        register int len;
                    165:        register char *start;
                    166: 
                    167:        if (!*str || !*bp)
                    168:                return(NO);
                    169:        for (len = strlen(str);;) {
                    170:                for (; *bp && !isdigit(*bp) && !isalpha(*bp); ++bp);
                    171:                if (!*bp)
                    172:                        break;
                    173:                for (start = bp++; *bp && (isdigit(*bp) || isalpha(*bp)); ++bp);
                    174:                if (bp - start == len && !strncasecmp(start, str, len))
                    175:                        return(YES);
                    176:        }
                    177:        return(NO);
                    178: }
                    179: 
                    180: /*
                    181:  * dashtrunc --
                    182:  *     truncate a string at " - "
                    183:  */
                    184: static
                    185: dashtrunc(from, to)
                    186:        register char *from, *to;
                    187: {
                    188:        do {
                    189:                if (from[0] == ' ' && from[1] == '-' && from[2] == ' ')
                    190:                        break;
                    191:        } while (*to++ = *from++);
                    192:        *to = '\0';
                    193: }
                    194: 
                    195: /*
                    196:  * lowstr --
                    197:  *     convert a string to lower case
                    198:  */
                    199: static
                    200: lowstr(from, to)
                    201:        register char *from, *to;
                    202: {
                    203:        do {
                    204:                *to++ = isupper(*from) ? tolower(*from) : *from;
                    205:        } while (*from++);
                    206: }
                    207: 
                    208: /*
                    209:  * usage --
                    210:  *     print usage message and die
                    211:  */
                    212: static
                    213: usage()
                    214: {
                    215:        fprintf(stderr, "usage: %s [-M path] string ...\n", myname);
                    216:        exit(1);
                    217: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.