home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / misc / volume05 / s5look < prev    next >
Encoding:
Internet Message Format  |  1991-08-27  |  4.7 KB

  1. From decwrl!labrea!rutgers!mailrus!cwjcc!hal!ncoast!allbery Sun Oct 30 15:05:50 PST 1988
  2. Article 684 of comp.sources.misc:
  3. Path: granite!decwrl!labrea!rutgers!mailrus!cwjcc!hal!ncoast!allbery
  4. From: campbell@redsox.UUCP (Larry Campbell)
  5. Newsgroups: comp.sources.misc
  6. Subject: v05i007: Public domain look(1) for SysV
  7. Message-ID: <491@redsox.UUCP>
  8. Date: 28 Oct 88 02:25:50 GMT
  9. Sender: allbery@ncoast.UUCP
  10. Reply-To: campbell@redsox.UUCP (Larry Campbell)
  11. Organization: The Boston Software Works, Inc.
  12. Lines: 247
  13. Approved: allbery@ncoast.UUCP
  14.  
  15. Posting-number: Volume 5, Issue 7
  16. Submitted-by: "Larry Campbell" <campbell@redsox.UUCP>
  17. Archive-name: s5look
  18.  
  19. Here's a quickie public domain implementation of look.  It's not blazingly
  20. fast, but it sure beats grep, it lints cleanly, and the price is right.
  21.  
  22. /*
  23.  * look.c
  24.  *
  25.  *    <-xtx-*> cc -o look -O -s look.c
  26.  *
  27.  *    An implementation of the V7/Berkeley look(1) utility, which
  28.  *    is annoyingly lacking from System V.  This code is in the public
  29.  *    public domain.  You may use this code for any purpose, commercial
  30.  *    or noncommercial, as long as you don't try to claim you wrote it.
  31.  *
  32.  *    This code hasn't been tuned;  it runs about half the speed of the
  33.  *    V7 version.  That's good enough for me.
  34.  *
  35.  *    If you find bugs, please send me the fixes.
  36.  *
  37.  * Written October, 1988 by:
  38.  *
  39.  *    Larry Campbell
  40.  *    The Boston Software Works, Inc.
  41.  *    120 Fulton Street, Boston, MA 02109
  42.  *    campbell@bsw.com
  43.  ******************************************************************
  44.  * usage:
  45.  *
  46.  *    look [-f] words file
  47.  *
  48.  *    Conducts a binary search in <file>, which must be sorted,
  49.  *    for a line beginning with <words>.  The -f switch means
  50.  *    ignore (fold) case.
  51.  *
  52.  *    If the input file is not sorted, the results are unpredictable.
  53.  */
  54.  
  55. #include <stdio.h>
  56. #include <ctype.h>
  57. #include <string.h>
  58. #include <sys/types.h>
  59. #include <sys/stat.h>
  60.  
  61. extern void
  62.     perror(),
  63.     exit();
  64.  
  65. char
  66.     *words,
  67.     *filename,
  68.     buf[BUFSIZ];
  69.  
  70. int
  71.     fold_flag,
  72.     length;
  73.  
  74. FILE
  75.     *f;
  76.  
  77. long
  78.     left_offset,
  79.     offset,
  80.     right_offset,
  81.     size,
  82.     step;
  83.  
  84. /* Forward declarations */
  85.  
  86. void
  87.     search(),
  88.     start_of_line(),
  89.     strlwr(),
  90.     usage();
  91.  
  92. main(argc, argv)
  93. char *argv[];
  94. {
  95. int
  96.     i;
  97.  
  98. struct stat
  99.     statb;
  100.  
  101. if (argc < 3 || argc > 4)
  102.     usage();
  103. fold_flag = 0;
  104. if (argc == 4) 
  105.     if (argv[1][0] == '-' && argv[1][1] == 'f')
  106.     fold_flag = 1;
  107.     else
  108.     usage();
  109. i = argc - 2;
  110. words = argv[i];
  111. length = strlen(words);
  112. if (fold_flag)
  113.     strlwr(words);
  114.  
  115. filename = argv[i + 1];
  116.  
  117. f = fopen(filename, "r");
  118. if (f == NULL)
  119.     perror("can't open input file");
  120.  
  121. if (fstat(fileno(f), &statb) < 0)
  122.     perror("stat failed on input file");
  123.  
  124. size = statb.st_size;
  125. if (size == 0)
  126.     exit(0);
  127.  
  128. offset = size / 2;
  129. step = offset / 2;
  130. search();
  131. return 0;
  132. }
  133.  
  134. void
  135. search()
  136. {
  137. int
  138.     compare;
  139.  
  140. char
  141.     buf2[BUFSIZ];
  142.  
  143. for (;;)
  144.     {
  145.     if (fseek(f, offset, 0) == -1)
  146.     perror("fseek");
  147.     start_of_line();
  148.     compare = strncmp(words, buf, length);
  149.     if (compare == 0)
  150.     {
  151.     while (offset > 0L)    /* back up to first nonmatching line */
  152.         {
  153.         offset -= left_offset;
  154.         start_of_line();
  155.         compare = strncmp(words, buf, length);
  156.         if (compare != 0)
  157.         {
  158.         if (fseek(f, ++offset, 0) == -1) /* skip nonmatching line */
  159.             perror("fseek");
  160.         if (fgets(buf, BUFSIZ, f) == 0)    /* reload matching line */
  161.             perror("fgets");
  162.         break;
  163.         }
  164.         }
  165.     for (;;)
  166.         {
  167.         (void) fputs(buf, stdout);
  168.         if (fgets(buf, BUFSIZ, f) == 0)
  169.         break;
  170.         (void) strcpy(buf2, buf);
  171.         if (fold_flag)
  172.         strlwr(buf2);
  173.         if (strncmp(words, buf2, length) != 0)
  174.         break;
  175.         }
  176.     exit(0);
  177.     }
  178.  
  179.     if (step == 0)
  180.     exit(1);
  181.     if (compare < 0)
  182.     {
  183.     if (step < left_offset)
  184.         offset -= left_offset;
  185.     else
  186.         offset -= step;
  187.     if (offset <= 0L)
  188.         exit(1);
  189.     }
  190.     else
  191.     {
  192.     if (step < right_offset)
  193.         offset += right_offset;
  194.     else
  195.         offset += step;
  196.     if (offset > size)
  197.         exit(1);
  198.     }
  199.     step = step / 2;
  200.     }
  201. }
  202.  
  203. void
  204. start_of_line()
  205. {
  206. int
  207.     c;
  208.  
  209. long
  210.     toffset;
  211.  
  212. if (offset <= 0L)
  213.     return;
  214. toffset = offset;
  215. while (toffset > 0L)
  216.     {
  217.     c = fgetc(f);
  218.     if (c == '\n')
  219.     break;
  220.     if (fseek(f, --toffset, 0) == -1)
  221.     perror("fseek");
  222.     }
  223. if (fgets(buf, BUFSIZ, f) == 0)
  224.     perror("prev_line: fgets");
  225. if (fold_flag)
  226.     strlwr(buf);
  227. left_offset = offset - toffset;
  228. right_offset = (strlen(buf) - left_offset) + 1;
  229. }
  230.  
  231.  
  232. void
  233. usage()
  234. {
  235. (void) fprintf(stderr, "usage: look [-f] string file\n");
  236. exit(2);
  237. }
  238.  
  239.  
  240. /*
  241.  * This function is in ANSI C but AT&T is still behind the times.
  242.  */
  243.  
  244. void
  245. strlwr(s)
  246. char *s;
  247. {
  248. register char
  249.     c;
  250.  
  251. while (c = *s)
  252.     {
  253.     if (isupper(c))
  254.     *s = tolower(c);
  255.     s++;
  256.     }
  257. }
  258. -- 
  259. Larry Campbell                          The Boston Software Works, Inc.
  260. campbell@bsw.com                        120 Fulton Street
  261. wjh12!redsox!campbell                   Boston, MA 02146
  262.  
  263.  
  264.