[comp.os.minix] look

tholm@uvicctr.UUCP (Terrence W. Holm) (10/18/88)

EFTH MINIX report #49  - October 1988 -  look(1)


There follows an implementation of look(1) for MINIX.
Please consider this public domain software.
A "man" page is included.

(This command is used by people who spell as poorly
as I do.)

----------------------------------------------------------
echo x - look.1
gres '^X' '' > look.1 << '/'
XCOMMANDS
X    look(1)		- spelling helper
X
XINVOCATION
X    look  [ -f ]  prefix[/suffix]  [ dictionary ]
X
XEXPLANATION
X    Looks for all words in the on-line dictionary
X    beginning with the specified <prefix> and ending
X    with <suffix>.
X
XOPTIONS
X    -f      Fold upper case letters to lower case
X	    before comparisons. For "-f" sorted files.
X
X    dictionary  Use the sorted file "dictionary".
X
XFILES
X    /usr/lib/dictionary		The default dictionary
X
XREFERENCES
X    grep(1), sort(1), spell(1)
/
echo x - look.c
gres '^X' '' > look.c << '/'
X/*  look(1)
X *
X *  Author: Terrence Holm          Aug. 1988
X *
X *
X *  look  [ -f ]  prefix[/suffix]  [ dictionary ]
X *
X *  Looks for all words in the on-line dictionary
X *  beginning with the specified <prefix> and ending
X *  with <suffix>.
X *
X *  Fold to lower case if "-f" given. Use the file
X *  "dictionary" or /usr/lib/dictionary.
X *
X ******************************************************
X *
X *  This command was written for MINIX, and is slightly
X *  different than the UNIX look(1). First of all, the
X *  list of words is in a different place. Second, these
X *  words are not sorted by -df. And finally, the
X *  ``suffix'' option was added to limit the output of
X *  the multiple variations of each word as contained
X *  in the MINIX dictionary.
X */
X
X#include <ctype.h>
X#include <stdio.h>
X#include <string.h>
X#include <unistd.h>
X
X#ifdef UNIX
X#define  WORDS   "/usr/dict/words"
X#else
X#define  WORDS   "/usr/lib/dictionary"
X#endif
X
X#define  MAX_WORD_LENGTH   80	  /*  including '\0'  */
X
X
Xmain( argc, argv )
X  int   argc;
X  char *argv[];
X
X  {
X  int   fold = 0;
X  char *prefix;
X  char *suffix;
X  char *word_file = WORDS;
X
X  FILE *words;
X  long  head = 0;
X  long  tail;
X  long  mid_point;
X  char  word[ MAX_WORD_LENGTH ];
X  char  unfolded_word[ MAX_WORD_LENGTH ];
X  int   cmp;
X
X
X  /*  Check the arguments: fold, prefix, suffix and word_file.  */
X
X  if ( argc > 1  &&  strcmp( argv[1], "-f" ) == 0 )
X    {
X    fold = 1;
X    --argc;
X    ++argv;
X    }
X
X  if ( argc < 2  ||  argc > 3 )
X    {
X    fprintf( stderr, "Usage: %s [-f] prefix[/suffix] [dictionary]\n", argv[0] );
X    exit( 1 );
X    }
X
X  prefix = argv[1];
X
X  if ( (suffix = strchr( prefix, '/' )) == NULL )
X    suffix = "";
X  else
X    *suffix++ = '\0';
X
X  if ( fold )
X    {
X    Fold( prefix );
X    Fold( suffix );
X    }
X
X  if ( argc == 3 )
X    word_file = argv[2];
X
X
X  /*  Open the word file, and find how big it is.  */
X
X  if ( (words = fopen( word_file, "r" )) == NULL )
X	File_Error( word_file );
X
X  if ( fseek( words, 0L, SEEK_END ) != 0 )
X	File_Error( word_file );
X
X  tail = ftell( words );
X
X
X  /*  Use a binary search on the word file to find a 512 byte	*/
X  /*  window containing the first word starting with "prefix".	*/
X
X  while ( head + 512 < tail )
X    {
X    mid_point = ( head + tail ) / 2;
X
X    if ( fseek( words, mid_point, SEEK_SET ) != 0 )
X	File_Error( word_file );
X
X    /*  Skip the partial word we seeked into.  */
X
X    fgets( word, MAX_WORD_LENGTH, words );
X
X    if ( fgets( word, MAX_WORD_LENGTH, words ) == NULL )
X	File_Error( word_file );
X
X    word[ strlen(word) - 1 ] = '\0';	/* remove \n  */
X
X    strcpy( unfolded_word, word );
X
X    if ( fold )
X	Fold( word );
X
X    cmp = strcmp( prefix, word );
X
X    if ( cmp == 0 )
X	{
X	printf( "%s\n", unfolded_word );
X	head = ftell( words );
X	break;
X	}
X
X    if ( cmp < 0 )
X	tail = mid_point;
X    else
X	head = ftell( words );
X    }
X
X  fseek( words, head, SEEK_SET );
X
X
X
X  {
X  /*  Print out all the words starting with "prefix".  */
X
X  int   prefix_length = strlen( prefix );
X  int   suffix_length = strlen( suffix );
X  int   word_length;
X
X
X  while( fgets( word, MAX_WORD_LENGTH, words ) != NULL )
X    {
X    word_length = strlen( word ) - 1;
X
X    word[ word_length ] = '\0';		/* remove \n  */
X
X    strcpy( unfolded_word, word );
X
X    if ( fold )
X	Fold( word );
X
X    cmp = strncmp( prefix, word, prefix_length );
X
X    if ( cmp < 0 )
X 	break;
X
X    if ( cmp == 0 )
X	if ( suffix_length == 0  ||  word_length >= suffix_length
X	   &&  strcmp( suffix, word+word_length-suffix_length ) == 0 )
X		printf( "%s\n", unfolded_word );
X    }
X  }
X
X  fclose( words );
X
X  exit( 0 );
X  }
X
X
X
XFold( str )
X  char *str;
X
X  {
X  while( *str )
X    if ( isupper( *str++ ) )
X	str[-1] = _tolower( str[-1] );
X  }
X
X
X
XFile_Error( word_file )
X  char *word_file;
X
X  {
X  perror( word_file );
X  exit( 1 );
X  }
/
----------------------------------------------------------

		Terrence W. Holm
		  uw-beaver!uvicctr!tholm