home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 1 / ARM_CLUB_CD.iso / contents / apps / languages / progs / bin / man / c / apropos next >
Encoding:
Text File  |  1994-02-05  |  4.8 KB  |  219 lines

  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. #ifdef ARCH
  32. #include <string.h>
  33. #else
  34. #include <strings.h>
  35. #endif
  36.  
  37. #define    DEF_PATH    "/usr/man:/usr/new/man:/usr/local/man"
  38. #define    MAXLINELEN    1000            /* max line handled */
  39. #define    WHATIS        "whatis"        /* database name */
  40.  
  41. #define    NO    0                /* no/false */
  42. #define    YES    1                /* yes/true */
  43.  
  44. static char *myname;
  45.  
  46. main(argc, argv)
  47.     int argc;
  48.     char **argv;
  49. {
  50.     extern char *optarg;
  51.     extern int optind;
  52.     register char *beg, *end, **C;
  53.     int ch, foundman = NO, *found, isapropos;
  54.     int a_match(), w_match(), (*match)();
  55.     char *manpath = NULL, buf[MAXLINELEN + 1], fname[MAXPATHLEN + 1];
  56.     char wbuf[MAXLINELEN + 1], *getenv(), *malloc();
  57.  
  58.     myname = (beg = rindex(*argv, '/')) ? beg + 1 : *argv;
  59.     if (!strcmp(myname, "apropos")) {
  60.         isapropos = YES;
  61.         match = a_match;
  62.     }
  63.     else {
  64.         isapropos = NO;
  65.         match = w_match;
  66.     }
  67.     while ((ch = getopt(argc, argv, "M:P:")) != EOF)
  68.         switch((char)ch) {
  69.             case 'M':
  70.             case 'P':        /* backward contemptible */
  71.                 manpath = optarg;
  72.                 break;
  73.             case '?':
  74.             default:
  75.                 usage();
  76.         }
  77.     argv += optind;
  78.     argc -= optind;
  79.     if (argc < 1)
  80.         usage();
  81.  
  82.     if (!(manpath = getenv("MANPATH")))
  83.         manpath = DEF_PATH;
  84.  
  85.     /*NOSTRICT*/
  86.     if (!(found = (int *)malloc((u_int)argc))) {
  87.         fprintf(stderr, "%s: out of space.\n", myname);
  88.         exit(1);
  89.     }
  90.     bzero((char *)found, argc * sizeof(int));
  91.  
  92.     if (isapropos)
  93.         for (C = argv; *C; ++C)        /* convert to lower-case */
  94.             lowstr(*C, *C);
  95.     else for (C = argv; *C; ++C)        /* trim full paths */
  96.         if (beg = rindex(*C, '/'))
  97.             *C = beg + 1;
  98.  
  99.     for (beg = manpath; beg; beg = end) {    /* through path list */
  100.         end = index(beg, ':');
  101.         if (!end)
  102.             (void)sprintf(fname, "%s/%s", beg, WHATIS);
  103.         else {
  104.             (void)sprintf(fname, "%.*s/%s", end - beg, beg, WHATIS);
  105.             ++end;
  106.         }
  107.         if (!freopen(fname, "r", stdin))
  108.             continue;
  109.  
  110.                         /* for each file found */
  111.         for (foundman = YES; gets(buf);) {
  112.             if (isapropos)
  113.                 lowstr(buf, wbuf);
  114.             else
  115.                 dashtrunc(buf, wbuf);
  116.             for (C = argv; *C; ++C)
  117.                 if ((*match)(wbuf, *C)) {
  118.                     puts(buf);
  119.                     found[C - argv] = YES;
  120.  
  121.                     /* only print line once */
  122.                     while (*++C)
  123.                         if ((*match)(wbuf, *C))
  124.                             found[C - argv] = YES;
  125.                     break;
  126.                 }
  127.         }
  128.     }
  129.     if (!foundman) {
  130.         fprintf(stderr, "%s: no %s file found in %s.\n", myname, WHATIS, manpath);
  131.         exit(1);
  132.     }
  133.     for (C = argv; *C; ++C)
  134.         if (!found[C - argv])
  135.             printf("%s: %s\n", *C, isapropos ? "nothing appropriate" : "not found");
  136. }
  137.  
  138. /*
  139.  * a_match --
  140.  *    match for apropos; anywhere the string appears
  141.  */
  142. static
  143. a_match(bp, str)
  144.     register char *bp, *str;
  145. {
  146.     register int len;
  147.     register char test;
  148.  
  149.     if (!*bp)
  150.         return(NO);
  151.     /* backward compatible: everything matches empty string */
  152.     if (!*str)
  153.         return(YES);
  154.     for (test = *str++, len = strlen(str); *bp;)
  155.         if (test == *bp++ && !strncmp(bp, str, len))
  156.             return(YES);
  157.     return(NO);
  158. }
  159.  
  160. /*
  161.  * w_match --
  162.  *    match for whatis; looks for full word match
  163.  */
  164. static
  165. w_match(bp, str)
  166.     register char *bp, *str;
  167. {
  168.     register int len;
  169.     register char *start;
  170.  
  171.     if (!*str || !*bp)
  172.         return(NO);
  173.     for (len = strlen(str);;) {
  174.         for (; *bp && !isdigit(*bp) && !isalpha(*bp); ++bp);
  175.         if (!*bp)
  176.             break;
  177.         for (start = bp++; *bp && (isdigit(*bp) || isalpha(*bp)); ++bp);
  178.         if (bp - start == len && !strncasecmp(start, str, len))
  179.             return(YES);
  180.     }
  181.     return(NO);
  182. }
  183.  
  184. /*
  185.  * dashtrunc --
  186.  *    truncate a string at " - "
  187.  */
  188. dashtrunc(from, to)
  189.     register char *from, *to;
  190. {
  191.     do {
  192.         if (from[0] == ' ' && from[1] == '-' && from[2] == ' ')
  193.             break;
  194.     } while (*to++ = *from++);
  195.     *to = '\0';
  196. }
  197.  
  198. /*
  199.  * lowstr --
  200.  *    convert a string to lower case
  201.  */
  202. lowstr(from, to)
  203.     register char *from, *to;
  204. {
  205.     do {
  206.         *to++ = isupper(*from) ? tolower(*from) : *from;
  207.     } while (*from++);
  208. }
  209.  
  210. /*
  211.  * usage --
  212.  *    print usage message and die
  213.  */
  214. usage()
  215. {
  216.     fprintf(stderr, "usage: %s [-M path] string ...\n", myname);
  217.     exit(1);
  218. }
  219.