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