home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / unix_c / utils / s5look.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-21  |  4.3 KB  |  252 lines

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