home *** CD-ROM | disk | FTP | other *** search
/ Chip 1995 March / CHIP3.mdf / slackwar / a / util / util-lin.10 / util-lin / util-linux-1.10 / look.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-10  |  4.4 KB  |  195 lines

  1. /* look.c -- find lines in a sorted list
  2.  * Created: Mon Mar  8 23:16:36 1993 by faith@cs.unc.edu
  3.  * Revised: Wed Mar 10 14:18:27 1993 by faith@cs.unc.edu
  4.  * Copyright 1993 Rickard E. Faith (faith@cs.unc.edu)
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify it
  7.  * under the terms of the GNU General Public License as published by the
  8.  * Free Software Foundation; either version 1, or (at your option) any
  9.  * later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful, but
  12.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License along
  17.  * with this program; if not, write to the Free Software Foundation, Inc.,
  18.  * 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  * 
  20.  * $Log$
  21.  *
  22.  */
  23.  
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <ctype.h>
  28. #include <getopt.h>
  29.  
  30. static int dictionary_flag = 0;
  31. static int fold_flag = 0;
  32. static int debug_flag = 0;
  33.  
  34. static char *default_wordlist   = "/usr/dict/words";
  35. static char *alternate_wordlist = "/usr/dict/web2";
  36.  
  37. static void usage( void )
  38. {
  39.    fprintf( stderr, "usage: look [-dfa] string [file]\n" );
  40.    exit( 1 );
  41. }
  42.  
  43. static void getword( FILE *str, char *word, int length )
  44. {
  45.    int count = 0;
  46.    int c;
  47.  
  48.    while ((c = getc( str )) != EOF && c != '\n' && count < length) {
  49.       *word++ = c;
  50.       ++count;
  51.    }
  52.    *word = '\0';
  53. }
  54.  
  55. static int compare( char *a, char *b, int length_of_b )
  56. {
  57.    int i;
  58.    int A;
  59.    int B;
  60.  
  61.    for (i = 0; i < length_of_b; i++) {
  62.       if (!*a) return -1;    /* a is shorter than b */
  63.       if (dictionary_flag) {
  64.      while (*a && !isalnum(*a) && *a != '\t' && *a != ' ') a++;
  65.      while (*b && !isalnum(*b) && *b != '\t' && *b != ' ') {
  66.         b++;
  67.         length_of_b--;
  68.      }
  69.       }
  70.       if (fold_flag) {
  71.      A = isupper( *a ) ? tolower( *a ) : *a;
  72.      B = isupper( *b ) ? tolower( *b ) : *b;
  73.      if (A < B) return -1;
  74.      if (A > B) return 1;
  75.       } else {
  76.      if (*a < *b) return -1;
  77.      if (*a > *b) return 1;
  78.       }
  79.       ++a;
  80.       ++b;
  81.    }
  82.    return 0;
  83. }
  84.  
  85. static void search( char *filename, char *target )
  86. {
  87.    FILE      *str;
  88.    long int  left = 0;
  89.    long int  mid;
  90.    long int  right;
  91.    int       c;
  92.    const int LEN = 255;
  93.    char      word[LEN];
  94.    int       target_length = strlen( target );
  95.  
  96.  
  97.    if (!(str = fopen( filename, "r"))) {
  98.       fprintf( stderr, "look: cannot open \"%s\" for read\n", filename );
  99.       perror( "look" );
  100.       exit( 1 );
  101.    }
  102.  
  103.    fseek( str, 0, SEEK_END );
  104.    right = ftell( str );
  105.  
  106.    if (debug_flag) fprintf( stderr, "end = %ld\n", right );
  107.  
  108.    mid = right / 2;
  109.  
  110.    for (;;) {
  111.       if (debug_flag) fprintf( stderr, "seeking %ld\n", mid );
  112.       fseek( str, mid, SEEK_SET );
  113.       while ((c = getc( str )) != EOF && c != '\n')
  114.         ;
  115.       getword( str, word, LEN );
  116.       if (debug_flag) fprintf( stderr, "Found \"%s\" (%ld,%ld,%ld)\n",
  117.                    word,
  118.                    left,
  119.                    mid,
  120.                    right );
  121.       if (compare( word, target, target_length ) < 0) {
  122.      left = mid;
  123.      mid = (left + right) / 2;
  124.      if (left == mid) break;
  125.       } else {
  126.      right = mid;
  127.      mid = (left + right) / 2;
  128.      if (right == mid) break;
  129.       }
  130.    }
  131.  
  132.    if (!compare( word, target, target_length))
  133.      printf( "%s\n", word );
  134.    for (;;) {
  135.       getword( str, word, LEN );
  136.       if (compare( word, target, target_length )) return;
  137.       printf( "%s\n", word );
  138.    }
  139. }
  140.  
  141. int main( int argc, char **argv )
  142. {
  143.    int  c;
  144.    char *filename = NULL;
  145.    char *target;
  146.  
  147.    while ((c = getopt( argc, argv, "dft:aD" )) != EOF)
  148.      switch (c) {
  149.      case 'd':
  150.         ++dictionary_flag;
  151.         break;
  152.      case 'f':
  153.         ++fold_flag;
  154.         break;
  155.      case 'a':
  156.         filename = alternate_wordlist;
  157.         ++dictionary_flag;
  158.         ++fold_flag;
  159.         break;
  160.      case 'D':
  161.         ++debug_flag;
  162.         break;
  163.      default:
  164.         usage();
  165.         break;
  166.      }
  167.  
  168.    switch (argc - optind) {
  169.    case 1:
  170.       target = argv[optind];
  171.       if (!filename) {
  172.      filename = default_wordlist;
  173.      ++dictionary_flag;
  174.      ++fold_flag;
  175.       }
  176.       break;
  177.    case 2:
  178.       target = argv[optind];
  179.       filename = argv[optind + 1];
  180.       break;
  181.    default:
  182.       usage();
  183.       break;
  184.    }
  185.  
  186.    if (debug_flag) {
  187.       fprintf( stderr, "Searching for \"%s\" in \"%s\"\n", target, filename );
  188.       if (dictionary_flag) fprintf( stderr, "Dictionary order\n" );
  189.       if (fold_flag)       fprintf( stderr, "Fold\n" );
  190.    }
  191.  
  192.    search( filename, target );
  193.    return 0;
  194. }
  195.